aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/mach-tegra
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/ahb.c218
-rw-r--r--arch/arm/mach-tegra/arb_sema.c243
-rw-r--r--arch/arm/mach-tegra/asm_macros.h72
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.c1063
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.h111
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power2.c681
-rw-r--r--arch/arm/mach-tegra/board-aruba-panel.c256
-rw-r--r--arch/arm/mach-tegra/board-aruba-pinmux.c307
-rw-r--r--arch/arm/mach-tegra/board-aruba-power.c76
-rw-r--r--arch/arm/mach-tegra/board-aruba-sdhci.c248
-rw-r--r--arch/arm/mach-tegra/board-aruba-sensors.c109
-rw-r--r--arch/arm/mach-tegra/board-aruba.c544
-rw-r--r--arch/arm/mach-tegra/board-aruba.h26
-rw-r--r--arch/arm/mach-tegra/board-cardhu-kbc.c299
-rw-r--r--arch/arm/mach-tegra/board-cardhu-memory.c5518
-rw-r--r--arch/arm/mach-tegra/board-cardhu-panel.c1288
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pinmux.c796
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c803
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c791
-rw-r--r--arch/arm/mach-tegra/board-cardhu-power.c1321
-rw-r--r--arch/arm/mach-tegra/board-cardhu-powermon.c259
-rw-r--r--arch/arm/mach-tegra/board-cardhu-sdhci.c305
-rw-r--r--arch/arm/mach-tegra/board-cardhu-sensors.c1001
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c1230
-rw-r--r--arch/arm/mach-tegra/board-cardhu.h257
-rw-r--r--arch/arm/mach-tegra/board-dt.c119
-rw-r--r--arch/arm/mach-tegra/board-enterprise-baseband.c247
-rw-r--r--arch/arm/mach-tegra/board-enterprise-kbc.c107
-rw-r--r--arch/arm/mach-tegra/board-enterprise-memory.c761
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c905
-rw-r--r--arch/arm/mach-tegra/board-enterprise-pinmux.c568
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c838
-rw-r--r--arch/arm/mach-tegra/board-enterprise-sdhci.c269
-rw-r--r--arch/arm/mach-tegra/board-enterprise-sensors.c673
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c1005
-rw-r--r--arch/arm/mach-tegra/board-enterprise.h161
-rw-r--r--arch/arm/mach-tegra/board-harmony-kbc.c375
-rw-r--r--arch/arm/mach-tegra/board-harmony-panel.c398
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c180
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c332
-rw-r--r--arch/arm/mach-tegra/board-harmony.c507
-rw-r--r--arch/arm/mach-tegra/board-harmony.h53
-rw-r--r--arch/arm/mach-tegra/board-info.c201
-rw-r--r--arch/arm/mach-tegra/board-kai-kbc.c103
-rw-r--r--arch/arm/mach-tegra/board-kai-memory.c877
-rw-r--r--arch/arm/mach-tegra/board-kai-panel.c740
-rw-r--r--arch/arm/mach-tegra/board-kai-pinmux.c565
-rw-r--r--arch/arm/mach-tegra/board-kai-power.c658
-rw-r--r--arch/arm/mach-tegra/board-kai-sdhci.c267
-rw-r--r--arch/arm/mach-tegra/board-kai-sensors.c259
-rw-r--r--arch/arm/mach-tegra/board-kai.c854
-rw-r--r--arch/arm/mach-tegra/board-kai.h120
-rw-r--r--arch/arm/mach-tegra/board-p1852-panel.c144
-rw-r--r--arch/arm/mach-tegra/board-p1852-pinmux.c391
-rw-r--r--arch/arm/mach-tegra/board-p1852-sdhci.c79
-rw-r--r--arch/arm/mach-tegra/board-p1852.c456
-rw-r--r--arch/arm/mach-tegra/board-p1852.h99
-rw-r--r--arch/arm/mach-tegra/board-paz00-pinmux.c155
-rw-r--r--arch/arm/mach-tegra/board-seaboard-pinmux.c179
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c228
-rw-r--r--arch/arm/mach-tegra/board-seaboard.h41
-rw-r--r--arch/arm/mach-tegra/board-touch-kai-synaptics-spi.c109
-rw-r--r--arch/arm/mach-tegra/board-touch-raydium_spi.c243
-rw-r--r--arch/arm/mach-tegra/board-trimslice-pinmux.c157
-rw-r--r--arch/arm/mach-tegra/board-trimslice.c182
-rw-r--r--arch/arm/mach-tegra/board-trimslice.h28
-rw-r--r--arch/arm/mach-tegra/board-ventana-memory.c592
-rw-r--r--arch/arm/mach-tegra/board-ventana-panel.c457
-rw-r--r--arch/arm/mach-tegra/board-ventana-pinmux.c194
-rw-r--r--arch/arm/mach-tegra/board-ventana-power.c373
-rw-r--r--arch/arm/mach-tegra/board-ventana-sdhci.c267
-rw-r--r--arch/arm/mach-tegra/board-ventana-sensors.c585
-rw-r--r--arch/arm/mach-tegra/board-ventana.c641
-rw-r--r--arch/arm/mach-tegra/board-ventana.h116
-rw-r--r--arch/arm/mach-tegra/board-whistler-baseband.c230
-rw-r--r--arch/arm/mach-tegra/board-whistler-baseband.h81
-rw-r--r--arch/arm/mach-tegra/board-whistler-kbc.c138
-rw-r--r--arch/arm/mach-tegra/board-whistler-memory.c632
-rw-r--r--arch/arm/mach-tegra/board-whistler-panel.c401
-rw-r--r--arch/arm/mach-tegra/board-whistler-pinmux.c207
-rw-r--r--arch/arm/mach-tegra/board-whistler-power.c291
-rw-r--r--arch/arm/mach-tegra/board-whistler-sdhci.c248
-rw-r--r--arch/arm/mach-tegra/board-whistler-sensors.c405
-rw-r--r--arch/arm/mach-tegra/board-whistler.c560
-rw-r--r--arch/arm/mach-tegra/board-whistler.h39
-rw-r--r--arch/arm/mach-tegra/clock-common.c73
-rw-r--r--arch/arm/mach-tegra/common-t2.c192
-rw-r--r--arch/arm/mach-tegra/common-t3.c268
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.h86
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c555
-rw-r--r--arch/arm/mach-tegra/cpuidle-t2.c413
-rw-r--r--arch/arm/mach-tegra/cpuidle-t3.c532
-rw-r--r--arch/arm/mach-tegra/csi.c84
-rw-r--r--arch/arm/mach-tegra/delay.S52
-rw-r--r--arch/arm/mach-tegra/devices.c1692
-rw-r--r--arch/arm/mach-tegra/devices.h132
-rw-r--r--arch/arm/mach-tegra/dma.c1203
-rw-r--r--arch/arm/mach-tegra/dvfs.c846
-rw-r--r--arch/arm/mach-tegra/dvfs.h180
-rw-r--r--arch/arm/mach-tegra/edp.c515
-rw-r--r--arch/arm/mach-tegra/eeprom-wifi-mac.c65
-rw-r--r--arch/arm/mach-tegra/fiq.c99
-rw-r--r--arch/arm/mach-tegra/gic.c135
-rw-r--r--arch/arm/mach-tegra/gic.h51
-rw-r--r--arch/arm/mach-tegra/i2c_error_recovery.c103
-rw-r--r--arch/arm/mach-tegra/include/mach/arb_sema.h35
-rw-r--r--arch/arm/mach-tegra/include/mach/audio.h57
-rw-r--r--arch/arm/mach-tegra/include/mach/csi.h40
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h570
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S35
-rw-r--r--arch/arm/mach-tegra/include/mach/delay.h41
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h202
-rw-r--r--arch/arm/mach-tegra/include/mach/edp.h80
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S37
-rw-r--r--arch/arm/mach-tegra/include/mach/fb.h61
-rw-r--r--arch/arm/mach-tegra/include/mach/fiq.h25
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio.h80
-rw-r--r--arch/arm/mach-tegra/include/mach/gpufuse.h19
-rw-r--r--arch/arm/mach-tegra/include/mach/hardware.h50
-rw-r--r--arch/arm/mach-tegra/include/mach/hdmi-audio.h46
-rw-r--r--arch/arm/mach-tegra/include/mach/i2s.h316
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h136
-rw-r--r--arch/arm/mach-tegra/include/mach/io_dpd.h40
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h523
-rw-r--r--arch/arm/mach-tegra/include/mach/iovmm.h323
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h391
-rw-r--r--arch/arm/mach-tegra/include/mach/kbc.h86
-rw-r--r--arch/arm/mach-tegra/include/mach/kfuse.h20
-rw-r--r--arch/arm/mach-tegra/include/mach/latency_allowance.h121
-rw-r--r--arch/arm/mach-tegra/include/mach/legacy_irq.h23
-rw-r--r--arch/arm/mach-tegra/include/mach/mc.h109
-rw-r--r--arch/arm/mach-tegra/include/mach/memory.h42
-rw-r--r--arch/arm/mach-tegra/include/mach/nand.h55
-rw-r--r--arch/arm/mach-tegra/include/mach/nvmap.h158
-rw-r--r--arch/arm/mach-tegra/include/mach/pci.h38
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-t2.h184
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-t3.h321
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h375
-rw-r--r--arch/arm/mach-tegra/include/mach/sdhci.h35
-rw-r--r--arch/arm/mach-tegra/include/mach/smmu.h63
-rw-r--r--arch/arm/mach-tegra/include/mach/spdif.h392
-rw-r--r--arch/arm/mach-tegra/include/mach/spi.h42
-rw-r--r--arch/arm/mach-tegra/include/mach/system.h34
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra-bb-power.h61
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_aic326x_pdata.h39
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_asoc_pdata.h36
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_dc_ext.h77
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_fb.h27
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_fuse.h27
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_max98088_pdata.h35
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_odm_fuses.h107
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h45
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_rt5640_pdata.h25
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_smmu.h24
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_usb_modem_power.h47
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_wm8753_pdata.h24
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h23
-rw-r--r--arch/arm/mach-tegra/include/mach/thermal.h62
-rw-r--r--arch/arm/mach-tegra/include/mach/tsensor.h48
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h166
-rw-r--r--arch/arm/mach-tegra/include/mach/vmalloc.h28
-rw-r--r--arch/arm/mach-tegra/include/mach/w1.h84
-rw-r--r--arch/arm/mach-tegra/iovmm-gart.c354
-rw-r--r--arch/arm/mach-tegra/iovmm-smmu.c1350
-rw-r--r--arch/arm/mach-tegra/iovmm.c943
-rw-r--r--arch/arm/mach-tegra/kfuse.c114
-rw-r--r--arch/arm/mach-tegra/latency_allowance.c598
-rw-r--r--arch/arm/mach-tegra/localtimer.c26
-rw-r--r--arch/arm/mach-tegra/mc.c73
-rw-r--r--arch/arm/mach-tegra/p852/Kconfig110
-rw-r--r--arch/arm/mach-tegra/p852/Makefile39
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-gpio.c158
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-i2c.c180
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-panel.c196
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-pinmux.c439
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-power.c209
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sdhci.c199
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku1-b00.c98
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku1-c0x.c98
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku1.c89
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku13-b00.c114
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku13.c112
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku23-b00.c115
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku23-c01.c87
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku23.c113
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku3.c103
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku5-b00.c115
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku5-c01.c93
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku8-b00.c88
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku8-c01.c87
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku9-b00.c93
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-sku9-c01.c92
-rw-r--r--arch/arm/mach-tegra/p852/board-p852.c763
-rw-r--r--arch/arm/mach-tegra/p852/board-p852.h300
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c338
-rw-r--r--arch/arm/mach-tegra/pinmux-t3-tables.c479
-rw-r--r--arch/arm/mach-tegra/pinmux.c1056
-rw-r--r--arch/arm/mach-tegra/pm-irq.c366
-rw-r--r--arch/arm/mach-tegra/pm-irq.h33
-rw-r--r--arch/arm/mach-tegra/pm-t2.c376
-rw-r--r--arch/arm/mach-tegra/pm-t3.c529
-rw-r--r--arch/arm/mach-tegra/powerdetect.c348
-rw-r--r--arch/arm/mach-tegra/pwm.c296
-rw-r--r--arch/arm/mach-tegra/sleep-t2.S574
-rw-r--r--arch/arm/mach-tegra/sleep-t3.S715
-rw-r--r--arch/arm/mach-tegra/syncpt.c100
-rw-r--r--arch/arm/mach-tegra/sysfs-cluster.c461
-rw-r--r--arch/arm/mach-tegra/sysfs-dcc.c249
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c2930
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.c349
-rw-r--r--arch/arm/mach-tegra/tegra2_mc.c1017
-rw-r--r--arch/arm/mach-tegra/tegra2_mc.h250
-rw-r--r--arch/arm/mach-tegra/tegra2_speedo.c140
-rw-r--r--arch/arm/mach-tegra/tegra2_statmon.c440
-rw-r--r--arch/arm/mach-tegra/tegra2_statmon.h33
-rw-r--r--arch/arm/mach-tegra/tegra2_throttle.c180
-rw-r--r--arch/arm/mach-tegra/tegra3_actmon.c847
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c5212
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c968
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.c1254
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.h297
-rw-r--r--arch/arm/mach-tegra/tegra3_speedo.c541
-rw-r--r--arch/arm/mach-tegra/tegra3_thermal.c544
-rw-r--r--arch/arm/mach-tegra/tegra3_throttle.c367
-rw-r--r--arch/arm/mach-tegra/tegra3_tsensor.c187
-rw-r--r--arch/arm/mach-tegra/tegra3_tsensor.h40
-rw-r--r--arch/arm/mach-tegra/tegra_fiq_debugger.c206
-rw-r--r--arch/arm/mach-tegra/tegra_odm_fuses.c998
-rw-r--r--arch/arm/mach-tegra/tegra_usb_modem_power.c297
-rw-r--r--arch/arm/mach-tegra/timer-t2.c128
-rw-r--r--arch/arm/mach-tegra/timer-t3.c338
-rw-r--r--arch/arm/mach-tegra/timer.h55
-rw-r--r--arch/arm/mach-tegra/timerinfo.c74
-rw-r--r--arch/arm/mach-tegra/usb_phy.c3019
-rw-r--r--arch/arm/mach-tegra/wakeups-t2.c111
-rw-r--r--arch/arm/mach-tegra/wakeups-t2.h65
-rw-r--r--arch/arm/mach-tegra/wakeups-t3.c122
-rw-r--r--arch/arm/mach-tegra/wakeups-t3.h71
-rw-r--r--arch/arm/mach-tegra/wdt-recovery.c131
-rw-r--r--arch/arm/mach-tegra/wdt-recovery.h17
241 files changed, 87104 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/ahb.c b/arch/arm/mach-tegra/ahb.c
new file mode 100644
index 00000000000..b7f3fb5219b
--- /dev/null
+++ b/arch/arm/mach-tegra/ahb.c
@@ -0,0 +1,218 @@
1/*
2 * arch/arm/mach-tegra/ahb.c
3 *
4 * Copyright (C) 2011 Google, Inc.
5 *
6 * Author:
7 * Jay Cheng <jacheng@nvidia.com>
8 * James Wylder <james.wylder@motorola.com>
9 * Benoit Goby <benoit@android.com>
10 * Colin Cross <ccross@android.com>
11 *
12 * This software is licensed under the terms of the GNU General Public
13 * License version 2, as published by the Free Software Foundation, and
14 * may be copied, distributed, and modified under those terms.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/syscore_ops.h>
27
28#include <mach/iomap.h>
29
30#define AHB_ARBITRATION_DISABLE 0x00
31#define AHB_ARBITRATION_PRIORITY_CTRL 0x04
32#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
33#define PRIORITY_SELECT_USB BIT(6)
34#define PRIORITY_SELECT_USB2 BIT(18)
35#define PRIORITY_SELECT_USB3 BIT(17)
36
37#define AHB_GIZMO_AHB_MEM 0x0c
38#define ENB_FAST_REARBITRATE BIT(2)
39#define DONT_SPLIT_AHB_WR BIT(7)
40
41#define AHB_GIZMO_APB_DMA 0x10
42#define AHB_GIZMO_IDE 0x18
43#define AHB_GIZMO_USB 0x1c
44#define AHB_GIZMO_AHB_XBAR_BRIDGE 0x20
45#define AHB_GIZMO_CPU_AHB_BRIDGE 0x24
46#define AHB_GIZMO_COP_AHB_BRIDGE 0x28
47#define AHB_GIZMO_XBAR_APB_CTLR 0x2c
48#define AHB_GIZMO_VCP_AHB_BRIDGE 0x30
49#define AHB_GIZMO_NAND 0x3c
50#define AHB_GIZMO_SDMMC4 0x44
51#define AHB_GIZMO_XIO 0x48
52#define AHB_GIZMO_BSEV 0x60
53#define AHB_GIZMO_BSEA 0x70
54#define AHB_GIZMO_NOR 0x74
55#define AHB_GIZMO_USB2 0x78
56#define AHB_GIZMO_USB3 0x7c
57#define IMMEDIATE BIT(18)
58
59#define AHB_GIZMO_SDMMC1 0x80
60#define AHB_GIZMO_SDMMC2 0x84
61#define AHB_GIZMO_SDMMC3 0x88
62#define AHB_MEM_PREFETCH_CFG_X 0xd8
63#define AHB_ARBITRATION_XBAR_CTRL 0xdc
64#define AHB_MEM_PREFETCH_CFG3 0xe0
65#define AHB_MEM_PREFETCH_CFG4 0xe4
66#define AHB_MEM_PREFETCH_CFG1 0xec
67#define AHB_MEM_PREFETCH_CFG2 0xf0
68#define PREFETCH_ENB BIT(31)
69#define MST_ID(x) (((x) & 0x1f) << 26)
70#define AHBDMA_MST_ID MST_ID(5)
71#define USB_MST_ID MST_ID(6)
72#define USB2_MST_ID MST_ID(18)
73#define USB3_MST_ID MST_ID(17)
74#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
75#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
76
77#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xf8
78
79
80static inline unsigned long gizmo_readl(unsigned long offset)
81{
82 return readl(IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
83}
84
85static inline void gizmo_writel(unsigned long value, unsigned long offset)
86{
87 writel(value, IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
88}
89
90static u32 ahb_gizmo[29];
91
92#ifdef CONFIG_PM
93int tegra_ahbgizmo_suspend(void)
94{
95 ahb_gizmo[0] = gizmo_readl(AHB_ARBITRATION_DISABLE);
96 ahb_gizmo[1] = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
97 ahb_gizmo[2] = gizmo_readl(AHB_GIZMO_AHB_MEM);
98 ahb_gizmo[3] = gizmo_readl(AHB_GIZMO_APB_DMA);
99 ahb_gizmo[4] = gizmo_readl(AHB_GIZMO_IDE);
100 ahb_gizmo[5] = gizmo_readl(AHB_GIZMO_USB);
101 ahb_gizmo[6] = gizmo_readl(AHB_GIZMO_AHB_XBAR_BRIDGE);
102 ahb_gizmo[7] = gizmo_readl(AHB_GIZMO_CPU_AHB_BRIDGE);
103 ahb_gizmo[8] = gizmo_readl(AHB_GIZMO_COP_AHB_BRIDGE);
104 ahb_gizmo[9] = gizmo_readl(AHB_GIZMO_XBAR_APB_CTLR);
105 ahb_gizmo[10] = gizmo_readl(AHB_GIZMO_VCP_AHB_BRIDGE);
106 ahb_gizmo[11] = gizmo_readl(AHB_GIZMO_NAND);
107 ahb_gizmo[12] = gizmo_readl(AHB_GIZMO_SDMMC4);
108 ahb_gizmo[13] = gizmo_readl(AHB_GIZMO_XIO);
109 ahb_gizmo[14] = gizmo_readl(AHB_GIZMO_BSEV);
110 ahb_gizmo[15] = gizmo_readl(AHB_GIZMO_BSEA);
111 ahb_gizmo[16] = gizmo_readl(AHB_GIZMO_NOR);
112 ahb_gizmo[17] = gizmo_readl(AHB_GIZMO_USB2);
113 ahb_gizmo[18] = gizmo_readl(AHB_GIZMO_USB3);
114 ahb_gizmo[19] = gizmo_readl(AHB_GIZMO_SDMMC1);
115 ahb_gizmo[20] = gizmo_readl(AHB_GIZMO_SDMMC2);
116 ahb_gizmo[21] = gizmo_readl(AHB_GIZMO_SDMMC3);
117 ahb_gizmo[22] = gizmo_readl(AHB_MEM_PREFETCH_CFG_X);
118 ahb_gizmo[23] = gizmo_readl(AHB_ARBITRATION_XBAR_CTRL);
119 ahb_gizmo[24] = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
120 ahb_gizmo[25] = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
121 ahb_gizmo[26] = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
122 ahb_gizmo[27] = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
123 ahb_gizmo[28] = gizmo_readl(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID);
124 return 0;
125}
126
127void tegra_ahbgizmo_resume(void)
128{
129 gizmo_writel(ahb_gizmo[0], AHB_ARBITRATION_DISABLE);
130 gizmo_writel(ahb_gizmo[1], AHB_ARBITRATION_PRIORITY_CTRL);
131 gizmo_writel(ahb_gizmo[2], AHB_GIZMO_AHB_MEM);
132 gizmo_writel(ahb_gizmo[3], AHB_GIZMO_APB_DMA);
133 gizmo_writel(ahb_gizmo[4], AHB_GIZMO_IDE);
134 gizmo_writel(ahb_gizmo[5], AHB_GIZMO_USB);
135 gizmo_writel(ahb_gizmo[6], AHB_GIZMO_AHB_XBAR_BRIDGE);
136 gizmo_writel(ahb_gizmo[7], AHB_GIZMO_CPU_AHB_BRIDGE);
137 gizmo_writel(ahb_gizmo[8], AHB_GIZMO_COP_AHB_BRIDGE);
138 gizmo_writel(ahb_gizmo[9], AHB_GIZMO_XBAR_APB_CTLR);
139 gizmo_writel(ahb_gizmo[10], AHB_GIZMO_VCP_AHB_BRIDGE);
140 gizmo_writel(ahb_gizmo[11], AHB_GIZMO_NAND);
141 gizmo_writel(ahb_gizmo[12], AHB_GIZMO_SDMMC4);
142 gizmo_writel(ahb_gizmo[13], AHB_GIZMO_XIO);
143 gizmo_writel(ahb_gizmo[14], AHB_GIZMO_BSEV);
144 gizmo_writel(ahb_gizmo[15], AHB_GIZMO_BSEA);
145 gizmo_writel(ahb_gizmo[16], AHB_GIZMO_NOR);
146 gizmo_writel(ahb_gizmo[17], AHB_GIZMO_USB2);
147 gizmo_writel(ahb_gizmo[18], AHB_GIZMO_USB3);
148 gizmo_writel(ahb_gizmo[19], AHB_GIZMO_SDMMC1);
149 gizmo_writel(ahb_gizmo[20], AHB_GIZMO_SDMMC2);
150 gizmo_writel(ahb_gizmo[21], AHB_GIZMO_SDMMC3);
151 gizmo_writel(ahb_gizmo[22], AHB_MEM_PREFETCH_CFG_X);
152 gizmo_writel(ahb_gizmo[23], AHB_ARBITRATION_XBAR_CTRL);
153 gizmo_writel(ahb_gizmo[24], AHB_MEM_PREFETCH_CFG3);
154 gizmo_writel(ahb_gizmo[25], AHB_MEM_PREFETCH_CFG4);
155 gizmo_writel(ahb_gizmo[26], AHB_MEM_PREFETCH_CFG1);
156 gizmo_writel(ahb_gizmo[27], AHB_MEM_PREFETCH_CFG2);
157 gizmo_writel(ahb_gizmo[28], AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID);
158}
159#else
160#define tegra_ahbgizmo_suspend NULL
161#define tegra_ahbgizmo_resume NULL
162#endif
163
164static struct syscore_ops tegra_ahbgizmo_syscore_ops = {
165 .suspend = tegra_ahbgizmo_suspend,
166 .resume = tegra_ahbgizmo_resume,
167};
168
169static int __init tegra_init_ahb_gizmo_settings(void)
170{
171 unsigned long val;
172
173 val = gizmo_readl(AHB_GIZMO_AHB_MEM);
174 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
175 gizmo_writel(val, AHB_GIZMO_AHB_MEM);
176
177 val = gizmo_readl(AHB_GIZMO_USB);
178 val |= IMMEDIATE;
179 gizmo_writel(val, AHB_GIZMO_USB);
180
181 val = gizmo_readl(AHB_GIZMO_USB2);
182 val |= IMMEDIATE;
183 gizmo_writel(val, AHB_GIZMO_USB2);
184
185 val = gizmo_readl(AHB_GIZMO_USB3);
186 val |= IMMEDIATE;
187 gizmo_writel(val, AHB_GIZMO_USB3);
188
189 val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
190 val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3
191 | AHB_PRIORITY_WEIGHT(7);
192 gizmo_writel(val, AHB_ARBITRATION_PRIORITY_CTRL);
193
194 val = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
195 val &= ~MST_ID(~0);
196 val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
197 gizmo_writel(val, AHB_MEM_PREFETCH_CFG1);
198
199 val = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
200 val &= ~MST_ID(~0);
201 val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
202 gizmo_writel(val, AHB_MEM_PREFETCH_CFG2);
203
204 val = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
205 val &= ~MST_ID(~0);
206 val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
207 gizmo_writel(val, AHB_MEM_PREFETCH_CFG3);
208
209 val = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
210 val &= ~MST_ID(~0);
211 val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
212 gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
213
214 register_syscore_ops(&tegra_ahbgizmo_syscore_ops);
215
216 return 0;
217}
218postcore_initcall(tegra_init_ahb_gizmo_settings);
diff --git a/arch/arm/mach-tegra/arb_sema.c b/arch/arm/mach-tegra/arb_sema.c
new file mode 100644
index 00000000000..eecdee5967c
--- /dev/null
+++ b/arch/arm/mach-tegra/arb_sema.c
@@ -0,0 +1,243 @@
1/*
2 * Copyright (C) 2010, NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/io.h>
21#include <linux/mutex.h>
22#include <linux/err.h>
23#include <linux/delay.h>
24#include <linux/completion.h>
25
26#include <mach/arb_sema.h>
27#include <mach/irqs.h>
28#include <mach/iomap.h>
29
30#define TEGRA_RPC_MAX_SEM 32
31
32/* arb_gnt ictrl */
33#define ARB_CPU_INT_EN 0x4
34
35/* arb_sema */
36#define ARB_GRANT_STATUS 0x0
37#define ARB_GRANT_REQUEST 0x4
38#define ARB_GRANT_RELEASE 0x8
39#define ARB_GRANT_PENDING 0xC
40
41struct tegra_arb_dev {
42 void __iomem *sema_base;
43 void __iomem *gnt_base;
44 spinlock_t lock;
45 struct completion arb_gnt_complete[TEGRA_RPC_MAX_SEM];
46 struct mutex mutexes[TEGRA_RPC_MAX_SEM];
47 int irq;
48 int status;
49 bool suspended;
50};
51
52static struct tegra_arb_dev *arb;
53
54static inline u32 arb_sema_read(u32 offset)
55{
56 return readl(arb->sema_base + offset);
57}
58
59static inline void arb_sema_write(u32 value, u32 offset)
60{
61 writel(value, arb->sema_base + offset);
62}
63
64static inline u32 arb_gnt_read(u32 offset)
65{
66 return readl(arb->gnt_base + offset);
67}
68
69static inline void arb_gnt_write(u32 value, u32 offset)
70{
71 writel(value, arb->gnt_base + offset);
72}
73
74static void request_arb_sem(enum tegra_arb_module lock)
75{
76 unsigned long flags;
77 u32 value;
78
79 spin_lock_irqsave(&arb->lock, flags);
80
81 arb_sema_write(1 << lock, ARB_GRANT_REQUEST);
82 value = arb_gnt_read(ARB_CPU_INT_EN);
83 value |= (1 << lock);
84 arb_gnt_write(value, ARB_CPU_INT_EN);
85
86 spin_unlock_irqrestore(&arb->lock, flags);
87}
88
89static void cancel_arb_sem(enum tegra_arb_module lock)
90{
91 unsigned long flags;
92 u32 value;
93
94 spin_lock_irqsave(&arb->lock, flags);
95
96 arb_sema_write(1 << lock, ARB_GRANT_RELEASE);
97 value = arb_gnt_read(ARB_CPU_INT_EN);
98 value &= ~(1 << lock);
99 arb_gnt_write(value, ARB_CPU_INT_EN);
100
101 spin_unlock_irqrestore(&arb->lock, flags);
102}
103
104int tegra_arb_mutex_lock_timeout(enum tegra_arb_module lock, int msecs)
105{
106 int ret;
107
108 if (!arb)
109 return -ENODEV;
110
111 if (arb->suspended) {
112 pr_err("device in suspend\n");
113 return -ETIMEDOUT;
114 }
115
116 mutex_lock(&arb->mutexes[lock]);
117 INIT_COMPLETION(arb->arb_gnt_complete[lock]);
118 request_arb_sem(lock);
119 ret = wait_for_completion_timeout(&arb->arb_gnt_complete[lock], msecs_to_jiffies(msecs));
120 if (ret == 0) {
121 pr_err("timed out. pending:0x%x\n", arb_sema_read(ARB_GRANT_PENDING));
122 cancel_arb_sem(lock);
123 mutex_unlock(&arb->mutexes[lock]);
124 return -ETIMEDOUT;
125 }
126
127 return 0;
128}
129EXPORT_SYMBOL(tegra_arb_mutex_lock_timeout);
130
131int tegra_arb_mutex_unlock(enum tegra_arb_module lock)
132{
133 if (!arb)
134 return -ENODEV;
135
136 if (arb->suspended) {
137 pr_err("device in suspend\n");
138 return -ETIMEDOUT;
139 }
140
141 cancel_arb_sem(lock);
142 mutex_unlock(&arb->mutexes[lock]);
143 return 0;
144}
145EXPORT_SYMBOL(tegra_arb_mutex_unlock);
146
147static irqreturn_t arb_gnt_isr(int irq, void *dev_id)
148{
149 struct tegra_arb_dev *dev = dev_id;
150 unsigned long status;
151 u32 cpu_int_en;
152 unsigned int bit;
153 unsigned long flags;
154
155 spin_lock_irqsave(&arb->lock, flags);
156
157 status = arb_sema_read(ARB_GRANT_STATUS);
158 pr_debug("%s: 0x%lx\n", __func__, status);
159
160 /* disable the arb semaphores which were signalled */
161 cpu_int_en = arb_gnt_read(ARB_CPU_INT_EN);
162 arb_gnt_write((cpu_int_en & ~(status & cpu_int_en)),
163 ARB_CPU_INT_EN);
164
165 status &= cpu_int_en;
166 for_each_set_bit(bit, &status, BITS_PER_LONG)
167 complete(&dev->arb_gnt_complete[bit]);
168
169 spin_unlock_irqrestore(&arb->lock, flags);
170 return IRQ_HANDLED;
171}
172
173int tegra_arb_suspend(void)
174{
175 unsigned long status = arb_sema_read(ARB_GRANT_STATUS);
176
177 if (WARN_ON(status != 0)) {
178 pr_err("%s: suspending while holding arbitration "
179 "semaphore: %08lx\n", __func__, status);
180 }
181 arb->suspended = true;
182
183 return status ? -EBUSY : 0;
184}
185
186int tegra_arb_resume(void)
187{
188 arb->suspended = false;
189 return 0;
190}
191
192static int __init tegra_arb_init(void)
193{
194 struct tegra_arb_dev *dev = NULL;
195 int err, i;
196
197 dev = kzalloc(sizeof(struct tegra_arb_dev), GFP_KERNEL);
198 if (dev == NULL) {
199 pr_err("%s: unable to alloc data struct.\n", __func__);
200 return -ENOMEM;
201 }
202
203 for (i = 0; i < TEGRA_RPC_MAX_SEM; i++) {
204 mutex_init(&dev->mutexes[i]);
205 init_completion(&dev->arb_gnt_complete[i]);
206 }
207
208 dev->sema_base = IO_ADDRESS(TEGRA_ARB_SEMA_BASE);
209 if (!dev->sema_base) {
210 pr_err("%s: can't get arb sema_base\n", __func__);
211 err = -ENOMEM;
212 goto out;
213 }
214
215 dev->gnt_base = IO_ADDRESS(TEGRA_ARBGNT_ICTLR_BASE);
216 if (!dev->gnt_base) {
217 pr_err("%s: can't ioremap gnt_base\n", __func__);
218 err = -ENOMEM;
219 goto out;
220 }
221
222 dev->irq = INT_GNT_1;
223 err = request_irq(dev->irq, arb_gnt_isr, 0, "rpc-arbsema", dev);
224 if (err) {
225 pr_err("%s: request_irq(%d) failed(%d)\n", __func__,
226 dev->irq, err);
227 goto out;
228 }
229
230 spin_lock_init(&dev->lock);
231 arb = dev;
232
233 pr_info("%s: initialized\n", __func__);
234 return 0;
235
236out:
237 kfree(dev);
238 pr_err("%s: initialization failed.\n", __func__);
239 return err;
240}
241subsys_initcall(tegra_arb_init);
242
243MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-tegra/asm_macros.h b/arch/arm/mach-tegra/asm_macros.h
new file mode 100644
index 00000000000..2463d797ce3
--- /dev/null
+++ b/arch/arm/mach-tegra/asm_macros.h
@@ -0,0 +1,72 @@
1/*
2 * arch/arm/mach-tegra/include/mach/asm_macros.h
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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_ASM_MACROS_H_
18#define _MACH_TEGRA_ASM_MACROS_H_
19
20#ifdef __ASSEMBLY__
21
22/* waits until the microsecond counter (base) ticks, for exact timing loops */
23.macro wait_for_us, rd, base, tmp
24 ldr \rd, [\base]
251001: ldr \tmp, [\base]
26 cmp \rd, \tmp
27 beq 1001b
28 mov \tmp, \rd
29.endm
30
31/* waits until the microsecond counter (base) is > rn */
32.macro wait_until, rn, base, tmp
33 add \rn, \rn, #1
341002: ldr \tmp, [\base]
35 sub \tmp, \tmp, \rn
36 ands \tmp, \tmp, #0x80000000
37 dmb
38 bne 1002b
39.endm
40
41/* returns the offset of the flow controller halt register for a cpu */
42.macro cpu_to_halt_reg rd, rcpu
43 cmp \rcpu, #0
44 subne \rd, \rcpu, #1
45 movne \rd, \rd, lsl #3
46 addne \rd, \rd, #0x14
47 moveq \rd, #0
48.endm
49
50/* returns the offset of the flow controller csr register for a cpu */
51.macro cpu_to_csr_reg rd, rcpu
52 cmp \rcpu, #0
53 subne \rd, \rcpu, #1
54 movne \rd, \rd, lsl #3
55 addne \rd, \rd, #0x18
56 moveq \rd, #8
57.endm
58
59/* returns the ID of the current processor */
60.macro cpu_id, rd
61 mrc p15, 0, \rd, c0, c0, 5
62 and \rd, \rd, #0xF
63.endm
64
65/* loads a 32-bit value into a register without a data access */
66.macro mov32, reg, val
67 movw \reg, #:lower16:\val
68 movt \reg, #:upper16:\val
69.endm
70
71#endif
72#endif
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c
new file mode 100644
index 00000000000..7d5c527cab8
--- /dev/null
+++ b/arch/arm/mach-tegra/baseband-xmm-power.c
@@ -0,0 +1,1063 @@
1/*
2 * arch/arm/mach-tegra/baseband-xmm-power.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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/module.h>
20#include <linux/moduleparam.h>
21#include <linux/platform_device.h>
22#include <linux/gpio.h>
23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/fs.h>
28#include <linux/uaccess.h>
29#include <linux/wakelock.h>
30#include <linux/spinlock.h>
31#include <linux/usb.h>
32#include <linux/pm_runtime.h>
33#include <mach/usb_phy.h>
34#include "board.h"
35#include "devices.h"
36#include "gpio-names.h"
37#include "baseband-xmm-power.h"
38
39MODULE_LICENSE("GPL");
40
41unsigned long modem_ver = XMM_MODEM_VER_1130;
42EXPORT_SYMBOL(modem_ver);
43
44unsigned long modem_flash;
45EXPORT_SYMBOL(modem_flash);
46
47unsigned long modem_pm = 1;
48EXPORT_SYMBOL(modem_pm);
49
50unsigned long enum_delay_ms = 1000; /* ignored if !modem_flash */
51
52module_param(modem_ver, ulong, 0644);
53MODULE_PARM_DESC(modem_ver,
54 "baseband xmm power - modem software version");
55module_param(modem_flash, ulong, 0644);
56MODULE_PARM_DESC(modem_flash,
57 "baseband xmm power - modem flash (1 = flash, 0 = flashless)");
58module_param(modem_pm, ulong, 0644);
59MODULE_PARM_DESC(modem_pm,
60 "baseband xmm power - modem power management (1 = pm, 0 = no pm)");
61module_param(enum_delay_ms, ulong, 0644);
62MODULE_PARM_DESC(enum_delay_ms,
63 "baseband xmm power - delay in ms between modem on and enumeration");
64
65static struct usb_device_id xmm_pm_ids[] = {
66 { USB_DEVICE(VENDOR_ID, PRODUCT_ID),
67 .driver_info = 0 },
68 {}
69};
70
71
72static struct gpio tegra_baseband_gpios[] = {
73 { -1, GPIOF_OUT_INIT_LOW, "BB_RSTn" },
74 { -1, GPIOF_OUT_INIT_LOW, "BB_ON" },
75 { -1, GPIOF_OUT_INIT_LOW, "IPC_BB_WAKE" },
76 { -1, GPIOF_IN, "IPC_AP_WAKE" },
77 { -1, GPIOF_OUT_INIT_HIGH, "IPC_HSIC_ACTIVE" },
78 { -1, GPIOF_IN, "IPC_HSIC_SUS_REQ" },
79};
80
81static enum {
82 IPC_AP_WAKE_UNINIT,
83 IPC_AP_WAKE_IRQ_READY,
84 IPC_AP_WAKE_INIT1,
85 IPC_AP_WAKE_INIT2,
86 IPC_AP_WAKE_L,
87 IPC_AP_WAKE_H,
88} ipc_ap_wake_state;
89
90enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
91static struct workqueue_struct *workqueue;
92static struct work_struct init1_work;
93static struct work_struct init2_work;
94static struct work_struct L2_resume_work;
95static struct baseband_power_platform_data *baseband_power_driver_data;
96static bool register_hsic_device;
97static struct wake_lock wakelock;
98static struct usb_device *usbdev;
99static bool CP_initiated_L2toL0;
100static bool modem_power_on;
101static int power_onoff;
102static int reenable_autosuspend;
103static struct work_struct autopm_resume_work;
104static bool wakeup_pending;
105static bool modem_sleep_flag;
106static spinlock_t xmm_lock;
107static DEFINE_MUTEX(xmm_onoff_mutex);
108
109static void baseband_xmm_power_L2_resume(void);
110static int baseband_xmm_power_driver_handle_resume(
111 struct baseband_power_platform_data *data);
112
113static int baseband_modem_power_on(struct baseband_power_platform_data *data)
114{
115 /* set IPC_HSIC_ACTIVE active */
116 gpio_set_value(baseband_power_driver_data->
117 modem.xmm.ipc_hsic_active, 1);
118
119 /* wait 20 ms */
120 mdelay(20);
121
122 /* reset / power on sequence */
123 mdelay(40);
124 gpio_set_value(data->modem.xmm.bb_rst, 1);
125 mdelay(1);
126 gpio_set_value(data->modem.xmm.bb_on, 1);
127 udelay(40);
128 gpio_set_value(data->modem.xmm.bb_on, 0);
129
130 return 0;
131}
132
133static int baseband_xmm_power_on(struct platform_device *device)
134{
135 struct baseband_power_platform_data *data
136 = (struct baseband_power_platform_data *)
137 device->dev.platform_data;
138 int ret;
139
140 pr_debug("%s {\n", __func__);
141
142 /* check for platform data */
143 if (!data) {
144 pr_err("%s: !data\n", __func__);
145 return -EINVAL;
146 }
147 if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
148 return -EINVAL;
149
150 /* reset the state machine */
151 baseband_xmm_powerstate = BBXMM_PS_INIT;
152 modem_sleep_flag = false;
153
154 if (modem_ver < XMM_MODEM_VER_1130)
155 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
156 else
157 ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
158
159 pr_debug("%s wake_st(%d) modem version %d\n", __func__,
160 ipc_ap_wake_state, modem_ver);
161
162 /* register usb host controller */
163 if (!modem_flash) {
164 pr_debug("%s - %d\n", __func__, __LINE__);
165 /* register usb host controller only once */
166 if (register_hsic_device) {
167 pr_debug("%s: register usb host controller\n",
168 __func__);
169 modem_power_on = true;
170 if (data->hsic_register)
171 data->modem.xmm.hsic_device =
172 data->hsic_register();
173 else
174 pr_err("%s: hsic_register is missing\n",
175 __func__);
176 register_hsic_device = false;
177 } else {
178 /* register usb host controller */
179 if (data->hsic_register)
180 data->modem.xmm.hsic_device =
181 data->hsic_register();
182 /* turn on modem */
183 pr_debug("%s call baseband_modem_power_on\n", __func__);
184 baseband_modem_power_on(data);
185 }
186 }
187 ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
188 if (ret < 0)
189 pr_err("%s: enable_irq_wake error\n", __func__);
190
191 pr_debug("%s }\n", __func__);
192
193 return 0;
194}
195
196static int baseband_xmm_power_off(struct platform_device *device)
197{
198 struct baseband_power_platform_data *data;
199 int ret;
200 unsigned long flags;
201
202 pr_debug("%s {\n", __func__);
203
204 if (baseband_xmm_powerstate == BBXMM_PS_UNINIT)
205 return -EINVAL;
206 /* check for device / platform data */
207 if (!device) {
208 pr_err("%s: !device\n", __func__);
209 return -EINVAL;
210 }
211 data = (struct baseband_power_platform_data *)
212 device->dev.platform_data;
213 if (!data) {
214 pr_err("%s: !data\n", __func__);
215 return -EINVAL;
216 }
217
218 ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
219 ret = disable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
220 if (ret < 0)
221 pr_err("%s: disable_irq_wake error\n", __func__);
222
223 /* unregister usb host controller */
224 if (data->hsic_unregister)
225 data->hsic_unregister(data->modem.xmm.hsic_device);
226 else
227 pr_err("%s: hsic_unregister is missing\n", __func__);
228
229
230 /* set IPC_HSIC_ACTIVE low */
231 gpio_set_value(baseband_power_driver_data->
232 modem.xmm.ipc_hsic_active, 0);
233
234 /* wait 20 ms */
235 mdelay(20);
236
237 /* drive bb_rst low */
238 gpio_set_value(data->modem.xmm.bb_rst, 0);
239 mdelay(1);
240
241 spin_lock_irqsave(&xmm_lock, flags);
242 baseband_xmm_powerstate = BBXMM_PS_UNINIT;
243 wakeup_pending = false;
244 modem_sleep_flag = false;
245 spin_unlock_irqrestore(&xmm_lock, flags);
246 /* start registration process once again on xmm on */
247 register_hsic_device = true;
248 pr_debug("%s }\n", __func__);
249
250 return 0;
251}
252
253static ssize_t baseband_xmm_onoff(struct device *dev,
254 struct device_attribute *attr,
255 const char *buf, size_t count)
256{
257 int pwr;
258 int size;
259 struct platform_device *device = to_platform_device(dev);
260
261 mutex_lock(&xmm_onoff_mutex);
262
263 pr_debug("%s\n", __func__);
264
265 /* check input */
266 if (buf == NULL) {
267 pr_err("%s: buf NULL\n", __func__);
268 mutex_unlock(&xmm_onoff_mutex);
269 return -EINVAL;
270 }
271 pr_debug("%s: count=%d\n", __func__, count);
272
273 /* parse input */
274 size = sscanf(buf, "%d", &pwr);
275 if (size != 1) {
276 pr_err("%s: size=%d -EINVAL\n", __func__, size);
277 mutex_unlock(&xmm_onoff_mutex);
278 return -EINVAL;
279 }
280
281 if (power_onoff == pwr) {
282 pr_err("%s: Ignored, due to same CP power state(%d)\n",
283 __func__, power_onoff);
284 mutex_unlock(&xmm_onoff_mutex);
285 return -EINVAL;
286 }
287 power_onoff = pwr;
288 pr_debug("%s power_onoff=%d\n", __func__, power_onoff);
289
290 if (power_onoff == 0)
291 baseband_xmm_power_off(device);
292 else if (power_onoff == 1)
293 baseband_xmm_power_on(device);
294
295 mutex_unlock(&xmm_onoff_mutex);
296
297 return count;
298}
299
300static DEVICE_ATTR(xmm_onoff, S_IRUSR | S_IWUSR | S_IRGRP,
301 NULL, baseband_xmm_onoff);
302
303
304void baseband_xmm_set_power_status(unsigned int status)
305{
306 struct baseband_power_platform_data *data = baseband_power_driver_data;
307 int value = 0;
308 unsigned long flags;
309
310 pr_debug("%s\n", __func__);
311
312 if (baseband_xmm_powerstate == status)
313 return;
314
315 switch (status) {
316 case BBXMM_PS_L0:
317 if (modem_sleep_flag) {
318 pr_info("%s Resume from L3 without calling resume"
319 "function\n", __func__);
320 baseband_xmm_power_driver_handle_resume(data);
321 }
322 pr_info("L0\n");
323 value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
324 pr_debug("before L0 ipc_hsic_active=%d\n", value);
325 if (!value) {
326 pr_debug("before L0 gpio set ipc_hsic_active=1 ->\n");
327 gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
328 }
329 if (modem_power_on) {
330 modem_power_on = false;
331 baseband_modem_power_on(data);
332 }
333
334 if (!wake_lock_active(&wakelock))
335 wake_lock(&wakelock);
336
337 pr_debug("gpio host active high->\n");
338 break;
339 case BBXMM_PS_L2:
340 pr_info("L2\n");
341 wake_unlock(&wakelock);
342 modem_sleep_flag = true;
343 break;
344 case BBXMM_PS_L3:
345 if (baseband_xmm_powerstate == BBXMM_PS_L2TOL0) {
346 if (!data->modem.xmm.ipc_ap_wake) {
347 spin_lock_irqsave(&xmm_lock, flags);
348 wakeup_pending = true;
349 spin_unlock_irqrestore(&xmm_lock, flags);
350 pr_info("%s: L2 race condition-CP wakeup"
351 " pending\n", __func__);
352 }
353 }
354 pr_info("L3\n");
355 if (wake_lock_active(&wakelock)) {
356 pr_info("%s: releasing wakelock before L3\n",
357 __func__);
358 wake_unlock(&wakelock);
359 }
360 gpio_set_value(data->modem.xmm.ipc_hsic_active, 0);
361 pr_debug("gpio host active low->\n");
362 break;
363 case BBXMM_PS_L2TOL0:
364 /* do this only from L2 state */
365 if (baseband_xmm_powerstate == BBXMM_PS_L2) {
366 baseband_xmm_powerstate = status;
367 pr_debug("BB XMM POWER STATE = %d\n", status);
368 baseband_xmm_power_L2_resume();
369 }
370 default:
371 break;
372 }
373 baseband_xmm_powerstate = status;
374 pr_debug("BB XMM POWER STATE = %d\n", status);
375}
376EXPORT_SYMBOL_GPL(baseband_xmm_set_power_status);
377
378irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
379{
380 int value;
381
382 value = gpio_get_value(baseband_power_driver_data->
383 modem.xmm.ipc_ap_wake);
384
385 pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);
386
387 if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
388 pr_err("%s - spurious irq\n", __func__);
389 } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
390 if (!value) {
391 pr_debug("%s - IPC_AP_WAKE_INIT1"
392 " - got falling edge\n",
393 __func__);
394 /* go to IPC_AP_WAKE_INIT1 state */
395 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
396 /* queue work */
397 queue_work(workqueue, &init1_work);
398 } else {
399 pr_debug("%s - IPC_AP_WAKE_INIT1"
400 " - wait for falling edge\n",
401 __func__);
402 }
403 } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
404 if (!value) {
405 pr_debug("%s - IPC_AP_WAKE_INIT2"
406 " - wait for rising edge\n",
407 __func__);
408 } else {
409 pr_debug("%s - IPC_AP_WAKE_INIT2"
410 " - got rising edge\n",
411 __func__);
412 /* go to IPC_AP_WAKE_INIT2 state */
413 ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
414 /* queue work */
415 queue_work(workqueue, &init2_work);
416 }
417 } else {
418 if (!value) {
419 pr_debug("%s - falling\n", __func__);
420 /* [ver < 1130] gpio protocol falling edge */
421 if (modem_ver < XMM_MODEM_VER_1130) {
422 pr_debug("gpio host wakeup done <-\n");
423 value = gpio_get_value
424 (baseband_power_driver_data->
425 modem.xmm.ipc_bb_wake);
426 if (value) {
427 /* Clear the slave wakeup request */
428 gpio_set_value
429 (baseband_power_driver_data->
430 modem.xmm.ipc_bb_wake, 0);
431 pr_debug("gpio slave wakeup done ->\n");
432 }
433 }
434 /* [ver >= 1130] gpio protocol falling edge */
435 if (modem_ver >= XMM_MODEM_VER_1130) {
436 if (baseband_xmm_powerstate == BBXMM_PS_L2) {
437 CP_initiated_L2toL0 = true;
438 baseband_xmm_set_power_status
439 (BBXMM_PS_L2TOL0);
440 } else if (baseband_xmm_powerstate ==
441 BBXMM_PS_L3) {
442 spin_lock(&xmm_lock);
443 wakeup_pending = true;
444 spin_unlock(&xmm_lock);
445 pr_info("CP L3 -> L0\n");
446 }
447 }
448 /* save gpio state */
449 ipc_ap_wake_state = IPC_AP_WAKE_L;
450 } else {
451 pr_debug("%s - rising\n", __func__);
452 /* [ver >= 1130] gpio protocol rising edge */
453 if (modem_ver >= XMM_MODEM_VER_1130) {
454 pr_debug("gpio host wakeup done <-\n");
455 value = gpio_get_value
456 (baseband_power_driver_data->
457 modem.xmm.ipc_bb_wake);
458 if (value) {
459 /* Clear the slave wakeup request */
460 gpio_set_value
461 (baseband_power_driver_data->
462 modem.xmm.ipc_bb_wake, 0);
463 pr_debug("gpio slave wakeup done ->\n");
464 if (reenable_autosuspend && usbdev) {
465 reenable_autosuspend = false;
466 queue_work(workqueue,
467 &autopm_resume_work);
468 }
469 }
470 if ((baseband_xmm_powerstate ==
471 BBXMM_PS_L2TOL0) ||
472 (baseband_xmm_powerstate ==
473 BBXMM_PS_L3TOL0))
474 baseband_xmm_set_power_status(
475 BBXMM_PS_L0);
476 else
477 pr_info("%s:no state"
478 "change required\n", __func__);
479 }
480 /* save gpio state */
481 ipc_ap_wake_state = IPC_AP_WAKE_H;
482 }
483 }
484
485 return IRQ_HANDLED;
486}
487EXPORT_SYMBOL(baseband_xmm_power_ipc_ap_wake_irq);
488
489static void baseband_xmm_power_init1_work(struct work_struct *work)
490{
491 int value;
492
493 pr_debug("%s {\n", __func__);
494
495 /* check if IPC_HSIC_ACTIVE high */
496 value = gpio_get_value(baseband_power_driver_data->
497 modem.xmm.ipc_hsic_active);
498 if (value != 1) {
499 pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
500 return;
501 }
502
503 /* wait 100 ms */
504 mdelay(100);
505
506 /* set IPC_HSIC_ACTIVE low */
507 gpio_set_value(baseband_power_driver_data->
508 modem.xmm.ipc_hsic_active, 0);
509
510 /* wait 10 ms */
511 mdelay(10);
512
513 /* set IPC_HSIC_ACTIVE high */
514 gpio_set_value(baseband_power_driver_data->
515 modem.xmm.ipc_hsic_active, 1);
516
517 /* wait 20 ms */
518 mdelay(20);
519
520 pr_debug("%s }\n", __func__);
521}
522
523static void baseband_xmm_power_init2_work(struct work_struct *work)
524{
525 struct baseband_power_platform_data *data = baseband_power_driver_data;
526
527 pr_debug("%s\n", __func__);
528
529 /* check input */
530 if (!data)
531 return;
532
533 /* register usb host controller only once */
534 if (register_hsic_device) {
535 if (data->hsic_register)
536 data->modem.xmm.hsic_device = data->hsic_register();
537 else
538 pr_err("%s: hsic_register is missing\n", __func__);
539 register_hsic_device = false;
540 }
541
542}
543
544static void baseband_xmm_power_autopm_resume(struct work_struct *work)
545{
546 struct usb_interface *intf;
547
548 pr_debug("%s\n", __func__);
549 if (usbdev) {
550 usb_lock_device(usbdev);
551 intf = usb_ifnum_to_if(usbdev, 0);
552 usb_autopm_get_interface(intf);
553 usb_autopm_put_interface(intf);
554 usb_unlock_device(usbdev);
555 }
556}
557
558
559/* Do the work for AP/CP initiated L2->L0 */
560static void baseband_xmm_power_L2_resume(void)
561{
562 struct baseband_power_platform_data *data = baseband_power_driver_data;
563 int value;
564 int delay = 1000; /* maxmum delay in msec */
565
566 pr_debug("%s\n", __func__);
567
568 if (!baseband_power_driver_data)
569 return;
570
571 modem_sleep_flag = false;
572
573 if (CP_initiated_L2toL0) {
574 pr_info("CP L2->L0\n");
575 CP_initiated_L2toL0 = false;
576 queue_work(workqueue, &L2_resume_work);
577 } else {
578 /* set the slave wakeup request */
579 pr_info("AP L2->L0\n");
580 gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
581 pr_debug("waiting for host wakeup from CP...\n");
582 do {
583 mdelay(1);
584 value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
585 delay--;
586 } while ((value) && (delay));
587 if (delay)
588 pr_debug("gpio host wakeup low <-\n");
589 else
590 pr_info("!!AP L2->L0 Failed\n");
591 }
592}
593
594/* Do the work for CP initiated L2->L0 */
595static void baseband_xmm_power_L2_resume_work(struct work_struct *work)
596{
597 struct usb_interface *intf;
598
599 pr_debug("%s {\n", __func__);
600
601 if (!usbdev)
602 return;
603 usb_lock_device(usbdev);
604 intf = usb_ifnum_to_if(usbdev, 0);
605 if (usb_autopm_get_interface(intf) == 0)
606 usb_autopm_put_interface(intf);
607 usb_unlock_device(usbdev);
608
609 pr_debug("} %s\n", __func__);
610}
611
612static void baseband_xmm_power_reset_on(void)
613{
614 /* reset / power on sequence */
615 mdelay(40);
616 gpio_set_value(baseband_power_driver_data->modem.xmm.bb_rst, 1);
617 mdelay(1);
618 gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 1);
619 udelay(40);
620 gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 0);
621}
622
623static struct baseband_xmm_power_work_t *baseband_xmm_power_work;
624
625static void baseband_xmm_power_work_func(struct work_struct *work)
626{
627 struct baseband_xmm_power_work_t *bbxmm_work
628 = (struct baseband_xmm_power_work_t *) work;
629
630 pr_debug("%s\n", __func__);
631
632 switch (bbxmm_work->state) {
633 case BBXMM_WORK_UNINIT:
634 pr_debug("BBXMM_WORK_UNINIT\n");
635 break;
636 case BBXMM_WORK_INIT:
637 pr_debug("BBXMM_WORK_INIT\n");
638 /* go to next state */
639 bbxmm_work->state = (modem_flash && !modem_pm)
640 ? BBXMM_WORK_INIT_FLASH_STEP1
641 : (modem_flash && modem_pm)
642 ? BBXMM_WORK_INIT_FLASH_PM_STEP1
643 : (!modem_flash && modem_pm)
644 ? BBXMM_WORK_INIT_FLASHLESS_PM_STEP1
645 : BBXMM_WORK_UNINIT;
646 pr_debug("Go to next state %d\n", bbxmm_work->state);
647 queue_work(workqueue, work);
648 break;
649 case BBXMM_WORK_INIT_FLASH_STEP1:
650 pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
651 /* register usb host controller */
652 pr_debug("%s: register usb host controller\n", __func__);
653 if (baseband_power_driver_data->hsic_register)
654 baseband_power_driver_data->modem.xmm.hsic_device =
655 baseband_power_driver_data->hsic_register();
656 else
657 pr_err("%s: hsic_register is missing\n", __func__);
658 break;
659 case BBXMM_WORK_INIT_FLASH_PM_STEP1:
660 pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
661 /* [modem ver >= 1130] start with IPC_HSIC_ACTIVE low */
662 if (modem_ver >= XMM_MODEM_VER_1130) {
663 pr_debug("%s: ver > 1130:"
664 " ipc_hsic_active -> 0\n", __func__);
665 gpio_set_value(baseband_power_driver_data->
666 modem.xmm.ipc_hsic_active, 0);
667 }
668 /* reset / power on sequence */
669 baseband_xmm_power_reset_on();
670 /* set power status as on */
671 power_onoff = 1;
672 /* optional delay
673 * 0 = flashless
674 * ==> causes next step to enumerate modem boot rom
675 * (058b / 0041)
676 * some delay > boot rom timeout
677 * ==> causes next step to enumerate modem software
678 * (1519 / 0020)
679 * (requires modem to be flash version, not flashless
680 * version)
681 */
682 if (enum_delay_ms)
683 mdelay(enum_delay_ms);
684 /* register usb host controller */
685 pr_debug("%s: register usb host controller\n", __func__);
686 if (baseband_power_driver_data->hsic_register)
687 baseband_power_driver_data->modem.xmm.hsic_device =
688 baseband_power_driver_data->hsic_register();
689 else
690 pr_err("%s: hsic_register is missing\n", __func__);
691 /* go to next state */
692 bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
693 ? BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1
694 : BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1;
695 queue_work(workqueue, work);
696 pr_debug("Go to next state %d\n", bbxmm_work->state);
697 break;
698 case BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1:
699 pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1\n");
700 break;
701 case BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1:
702 pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1\n");
703 break;
704 case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
705 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
706 /* go to next state */
707 bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
708 ? BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ
709 : BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
710 queue_work(workqueue, work);
711 break;
712 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1:
713 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
714 break;
715 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
716 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
717 break;
718 default:
719 break;
720 }
721
722}
723
724static void baseband_xmm_device_add_handler(struct usb_device *udev)
725{
726 struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
727 const struct usb_device_id *id;
728
729 if (intf == NULL)
730 return;
731
732 id = usb_match_id(intf, xmm_pm_ids);
733
734 if (id) {
735 pr_debug("persist_enabled: %u\n", udev->persist_enabled);
736 pr_info("Add device %d <%s %s>\n", udev->devnum,
737 udev->manufacturer, udev->product);
738 usbdev = udev;
739 usb_enable_autosuspend(udev);
740 pr_info("enable autosuspend\n");
741 }
742}
743
744static void baseband_xmm_device_remove_handler(struct usb_device *udev)
745{
746 if (usbdev == udev) {
747 pr_info("Remove device %d <%s %s>\n", udev->devnum,
748 udev->manufacturer, udev->product);
749 usbdev = 0;
750 }
751
752}
753
754static int usb_xmm_notify(struct notifier_block *self, unsigned long action,
755 void *blob)
756{
757 switch (action) {
758 case USB_DEVICE_ADD:
759 baseband_xmm_device_add_handler(blob);
760 break;
761 case USB_DEVICE_REMOVE:
762 baseband_xmm_device_remove_handler(blob);
763 break;
764 }
765
766 return NOTIFY_OK;
767}
768
769
770static struct notifier_block usb_xmm_nb = {
771 .notifier_call = usb_xmm_notify,
772};
773
774static int baseband_xmm_power_driver_probe(struct platform_device *device)
775{
776 struct baseband_power_platform_data *data
777 = (struct baseband_power_platform_data *)
778 device->dev.platform_data;
779 struct device *dev = &device->dev;
780 unsigned long flags;
781 int err;
782
783 pr_debug("%s\n", __func__);
784 pr_debug("[XMM] enum_delay_ms=%ld\n", enum_delay_ms);
785
786 /* check for platform data */
787 if (!data)
788 return -ENODEV;
789
790 /* check if supported modem */
791 if (data->baseband_type != BASEBAND_XMM) {
792 pr_err("unsuppported modem\n");
793 return -ENODEV;
794 }
795
796 /* save platform data */
797 baseband_power_driver_data = data;
798
799 /* create device file */
800 err = device_create_file(dev, &dev_attr_xmm_onoff);
801 if (err < 0) {
802 pr_err("%s - device_create_file failed\n", __func__);
803 return -ENODEV;
804 }
805
806 /* init wake lock */
807 wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "baseband_xmm_power");
808
809 /* init spin lock */
810 spin_lock_init(&xmm_lock);
811 /* request baseband gpio(s) */
812 tegra_baseband_gpios[0].gpio = baseband_power_driver_data
813 ->modem.xmm.bb_rst;
814 tegra_baseband_gpios[1].gpio = baseband_power_driver_data
815 ->modem.xmm.bb_on;
816 tegra_baseband_gpios[2].gpio = baseband_power_driver_data
817 ->modem.xmm.ipc_bb_wake;
818 tegra_baseband_gpios[3].gpio = baseband_power_driver_data
819 ->modem.xmm.ipc_ap_wake;
820 tegra_baseband_gpios[4].gpio = baseband_power_driver_data
821 ->modem.xmm.ipc_hsic_active;
822 tegra_baseband_gpios[5].gpio = baseband_power_driver_data
823 ->modem.xmm.ipc_hsic_sus_req;
824 err = gpio_request_array(tegra_baseband_gpios,
825 ARRAY_SIZE(tegra_baseband_gpios));
826 if (err < 0) {
827 pr_err("%s - request gpio(s) failed\n", __func__);
828 return -ENODEV;
829 }
830
831 /* request baseband irq(s) */
832 if (modem_flash && modem_pm) {
833 pr_debug("%s: request_irq IPC_AP_WAKE_IRQ\n", __func__);
834 ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
835 err = request_threaded_irq(
836 gpio_to_irq(data->modem.xmm.ipc_ap_wake),
837 NULL,
838 baseband_xmm_power_ipc_ap_wake_irq,
839 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
840 "IPC_AP_WAKE_IRQ",
841 NULL);
842 if (err < 0) {
843 pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
844 __func__);
845 return err;
846 }
847 err = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
848 if (err < 0)
849 pr_err("%s: enable_irq_wake error\n", __func__);
850 ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
851 if (modem_ver >= XMM_MODEM_VER_1130) {
852 pr_debug("%s: ver > 1130: AP_WAKE_INIT1\n", __func__);
853 /* ver 1130 or later starts in INIT1 state */
854 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
855 }
856 }
857
858 /* init work queue */
859 workqueue = create_singlethread_workqueue
860 ("baseband_xmm_power_workqueue");
861 if (!workqueue) {
862 pr_err("cannot create workqueue\n");
863 return -1;
864 }
865 baseband_xmm_power_work = (struct baseband_xmm_power_work_t *)
866 kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
867 if (!baseband_xmm_power_work) {
868 pr_err("cannot allocate baseband_xmm_power_work\n");
869 return -1;
870 }
871 INIT_WORK((struct work_struct *) baseband_xmm_power_work,
872 baseband_xmm_power_work_func);
873 baseband_xmm_power_work->state = BBXMM_WORK_INIT;
874 queue_work(workqueue,
875 (struct work_struct *) baseband_xmm_power_work);
876
877 /* init work objects */
878 INIT_WORK(&init1_work, baseband_xmm_power_init1_work);
879 INIT_WORK(&init2_work, baseband_xmm_power_init2_work);
880 INIT_WORK(&L2_resume_work, baseband_xmm_power_L2_resume_work);
881 INIT_WORK(&autopm_resume_work, baseband_xmm_power_autopm_resume);
882
883 /* init state variables */
884 register_hsic_device = true;
885 CP_initiated_L2toL0 = false;
886 spin_lock_irqsave(&xmm_lock, flags);
887 baseband_xmm_powerstate = BBXMM_PS_UNINIT;
888 wakeup_pending = false;
889 spin_unlock_irqrestore(&xmm_lock, flags);
890
891 usb_register_notify(&usb_xmm_nb);
892
893 pr_debug("%s }\n", __func__);
894 return 0;
895}
896
897static int baseband_xmm_power_driver_remove(struct platform_device *device)
898{
899 struct baseband_power_platform_data *data
900 = (struct baseband_power_platform_data *)
901 device->dev.platform_data;
902 struct device *dev = &device->dev;
903
904 pr_debug("%s\n", __func__);
905
906 /* check for platform data */
907 if (!data)
908 return 0;
909
910 usb_unregister_notify(&usb_xmm_nb);
911
912 /* free work structure */
913 kfree(baseband_xmm_power_work);
914 baseband_xmm_power_work = (struct baseband_xmm_power_work_t *) 0;
915
916 /* free baseband irq(s) */
917 if (modem_flash && modem_pm) {
918 free_irq(gpio_to_irq(baseband_power_driver_data
919 ->modem.xmm.ipc_ap_wake), NULL);
920 }
921
922 /* free baseband gpio(s) */
923 gpio_free_array(tegra_baseband_gpios,
924 ARRAY_SIZE(tegra_baseband_gpios));
925
926 /* destroy wake lock */
927 wake_lock_destroy(&wakelock);
928
929 /* delete device file */
930 device_remove_file(dev, &dev_attr_xmm_onoff);
931
932 /* unregister usb host controller */
933 if (data->hsic_unregister)
934 data->hsic_unregister(data->modem.xmm.hsic_device);
935 else
936 pr_err("%s: hsic_unregister is missing\n", __func__);
937
938 return 0;
939}
940
941static int baseband_xmm_power_driver_handle_resume(
942 struct baseband_power_platform_data *data)
943{
944 int value;
945 int delay = 1000; /* maxmum delay in msec */
946 unsigned long flags;
947
948 pr_debug("%s\n", __func__);
949 if (!data)
950 return 0;
951
952 /* check if modem is on */
953 if (power_onoff == 0) {
954 pr_debug("%s - flight mode - nop\n", __func__);
955 return 0;
956 }
957
958 modem_sleep_flag = false;
959
960 /* L3->L0 */
961 baseband_xmm_set_power_status(BBXMM_PS_L3TOL0);
962 value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
963 if (value) {
964 pr_info("AP L3 -> L0\n");
965 /* wake bb */
966 gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
967
968 pr_debug("waiting for host wakeup...\n");
969 do {
970 mdelay(1);
971 value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
972 delay--;
973 } while ((value) && (delay));
974 if (delay)
975 pr_debug("gpio host wakeup low <-\n");
976 } else {
977 pr_info("CP L3 -> L0\n");
978 spin_lock_irqsave(&xmm_lock, flags);
979 /* Clear wakeup pending flag */
980 wakeup_pending = false;
981 spin_unlock_irqrestore(&xmm_lock, flags);
982 }
983 reenable_autosuspend = true;
984
985 return 0;
986
987}
988
989#ifdef CONFIG_PM
990static int baseband_xmm_power_driver_suspend(struct device *dev)
991{
992 pr_debug("%s\n", __func__);
993 return 0;
994}
995
996static int baseband_xmm_power_driver_resume(struct device *dev)
997{
998 struct platform_device *pdev = to_platform_device(dev);
999 struct baseband_power_platform_data *data
1000 = (struct baseband_power_platform_data *)
1001 pdev->dev.platform_data;
1002
1003 pr_debug("%s\n", __func__);
1004 baseband_xmm_power_driver_handle_resume(data);
1005
1006 return 0;
1007}
1008
1009static int baseband_xmm_power_suspend_noirq(struct device *dev)
1010{
1011 unsigned long flags;
1012
1013 pr_debug("%s\n", __func__);
1014 spin_lock_irqsave(&xmm_lock, flags);
1015 if (wakeup_pending) {
1016 wakeup_pending = false;
1017 spin_unlock_irqrestore(&xmm_lock, flags);
1018 pr_info("%s:**Abort Suspend: reason CP WAKEUP**\n", __func__);
1019 return -EBUSY;
1020 }
1021 spin_unlock_irqrestore(&xmm_lock, flags);
1022 return 0;
1023}
1024
1025static int baseband_xmm_power_resume_noirq(struct device *dev)
1026{
1027 pr_debug("%s\n", __func__);
1028 return 0;
1029}
1030
1031static const struct dev_pm_ops baseband_xmm_power_dev_pm_ops = {
1032 .suspend_noirq = baseband_xmm_power_suspend_noirq,
1033 .resume_noirq = baseband_xmm_power_resume_noirq,
1034 .suspend = baseband_xmm_power_driver_suspend,
1035 .resume = baseband_xmm_power_driver_resume,
1036};
1037#endif
1038
1039static struct platform_driver baseband_power_driver = {
1040 .probe = baseband_xmm_power_driver_probe,
1041 .remove = baseband_xmm_power_driver_remove,
1042 .driver = {
1043 .name = "baseband_xmm_power",
1044#ifdef CONFIG_PM
1045 .pm = &baseband_xmm_power_dev_pm_ops,
1046#endif
1047 },
1048};
1049
1050static int __init baseband_xmm_power_init(void)
1051{
1052 pr_debug("%s\n", __func__);
1053 return platform_driver_register(&baseband_power_driver);
1054}
1055
1056static void __exit baseband_xmm_power_exit(void)
1057{
1058 pr_debug("%s\n", __func__);
1059 platform_driver_unregister(&baseband_power_driver);
1060}
1061
1062module_init(baseband_xmm_power_init)
1063module_exit(baseband_xmm_power_exit)
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.h b/arch/arm/mach-tegra/baseband-xmm-power.h
new file mode 100644
index 00000000000..0768ed191b0
--- /dev/null
+++ b/arch/arm/mach-tegra/baseband-xmm-power.h
@@ -0,0 +1,111 @@
1/*
2 * arch/arm/mach-tegra/baseband-xmm-power.h
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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 BASEBAND_XMM_POWER_H
18#define BASREBAND_XMM_POWER_H
19
20#include <linux/pm.h>
21#include <linux/suspend.h>
22
23#define VENDOR_ID 0x1519
24#define PRODUCT_ID 0x0020
25#define TEGRA_EHCI_DEVICE "/sys/devices/platform/tegra-ehci.1/ehci_power"
26
27#define XMM_MODEM_VER_1121 0x1121
28#define XMM_MODEM_VER_1130 0x1130
29
30/* shared between baseband-xmm-* modules so they can agree on same
31 * modem configuration
32 */
33extern unsigned long modem_ver;
34extern unsigned long modem_flash;
35extern unsigned long modem_pm;
36
37enum baseband_type {
38 BASEBAND_XMM,
39};
40
41struct baseband_power_platform_data {
42 enum baseband_type baseband_type;
43 struct platform_device* (*hsic_register)(void);
44 void (*hsic_unregister)(struct platform_device *);
45 union {
46 struct {
47 int mdm_reset;
48 int mdm_on;
49 int ap2mdm_ack;
50 int mdm2ap_ack;
51 int ap2mdm_ack2;
52 int mdm2ap_ack2;
53 struct platform_device *device;
54 } generic;
55 struct {
56 int bb_rst;
57 int bb_on;
58 int ipc_bb_wake;
59 int ipc_ap_wake;
60 int ipc_hsic_active;
61 int ipc_hsic_sus_req;
62 struct platform_device *hsic_device;
63 } xmm;
64 } modem;
65};
66
67enum baseband_xmm_power_work_state_t {
68 BBXMM_WORK_UNINIT,
69 BBXMM_WORK_INIT,
70 /* initialize flash modem */
71 BBXMM_WORK_INIT_FLASH_STEP1,
72 /* initialize flash (with power management support) modem */
73 BBXMM_WORK_INIT_FLASH_PM_STEP1,
74 BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1,
75 BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1,
76 /* initialize flashless (with power management support) modem */
77 BBXMM_WORK_INIT_FLASHLESS_PM_STEP1,
78 BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ,
79 BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1,
80 BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2,
81 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1,
82 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2,
83 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3,
84 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4,
85};
86
87struct baseband_xmm_power_work_t {
88 /* work structure must be first structure member */
89 struct work_struct work;
90 /* xmm modem state */
91 enum baseband_xmm_power_work_state_t state;
92};
93
94enum baseband_xmm_powerstate_t {
95 BBXMM_PS_UNINIT = 0,
96 BBXMM_PS_INIT = 1,
97 BBXMM_PS_L0 = 2,
98 BBXMM_PS_L0TOL2 = 3,
99 BBXMM_PS_L2 = 4,
100 BBXMM_PS_L2TOL0 = 5,
101 BBXMM_PS_L2TOL3 = 6,
102 BBXMM_PS_L3 = 7,
103 BBXMM_PS_L3TOL0 = 8,
104 BBXMM_PS_LAST = -1,
105};
106
107irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id);
108
109void baseband_xmm_set_power_status(unsigned int status);
110
111#endif /* BASREBAND_XMM_POWER_H */
diff --git a/arch/arm/mach-tegra/baseband-xmm-power2.c b/arch/arm/mach-tegra/baseband-xmm-power2.c
new file mode 100644
index 00000000000..4295b395820
--- /dev/null
+++ b/arch/arm/mach-tegra/baseband-xmm-power2.c
@@ -0,0 +1,681 @@
1/*
2 * arch/arm/mach-tegra/baseband-xmm-power2.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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/module.h>
20#include <linux/moduleparam.h>
21#include <linux/platform_device.h>
22#include <linux/gpio.h>
23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/fs.h>
28#include <linux/uaccess.h>
29#include <linux/wakelock.h>
30#include <mach/usb_phy.h>
31#include "baseband-xmm-power.h"
32#include "board.h"
33#include "devices.h"
34
35MODULE_LICENSE("GPL");
36
37static unsigned long XYZ = 1000 * 1000000 + 800 * 1000 + 500;
38
39module_param(modem_ver, ulong, 0644);
40MODULE_PARM_DESC(modem_ver,
41 "baseband xmm power2 - modem software version");
42module_param(modem_flash, ulong, 0644);
43MODULE_PARM_DESC(modem_flash,
44 "baseband xmm power2 - modem flash (1 = flash, 0 = flashless)");
45module_param(modem_pm, ulong, 0644);
46MODULE_PARM_DESC(modem_pm,
47 "baseband xmm power2 - modem power management (1 = pm, 0 = no pm)");
48module_param(XYZ, ulong, 0644);
49MODULE_PARM_DESC(XYZ,
50 "baseband xmm power2 - timing parameters X/Y/Z delay in ms");
51
52static struct baseband_power_platform_data *baseband_power2_driver_data;
53static struct workqueue_struct *workqueue;
54static struct baseband_xmm_power_work_t *baseband_xmm_power2_work;
55
56static enum {
57 IPC_AP_WAKE_UNINIT,
58 IPC_AP_WAKE_IRQ_READY,
59 IPC_AP_WAKE_INIT1,
60 IPC_AP_WAKE_INIT2,
61 IPC_AP_WAKE_L,
62 IPC_AP_WAKE_H,
63} ipc_ap_wake_state;
64
65static irqreturn_t baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
66 (int irq, void *dev_id)
67{
68 int value;
69
70 pr_debug("%s\n", __func__);
71
72 /* check for platform data */
73 if (!baseband_power2_driver_data)
74 return IRQ_HANDLED;
75
76 value = gpio_get_value(baseband_power2_driver_data->
77 modem.xmm.ipc_ap_wake);
78
79 /* IPC_AP_WAKE state machine */
80 if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
81 pr_err("%s - spurious irq\n", __func__);
82 } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
83 if (!value) {
84 pr_debug("%s - IPC_AP_WAKE_INIT1"
85 " - got falling edge\n",
86 __func__);
87 /* go to IPC_AP_WAKE_INIT1 state */
88 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
89 /* queue work */
90 baseband_xmm_power2_work->state =
91 BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1;
92 queue_work(workqueue, (struct work_struct *)
93 baseband_xmm_power2_work);
94 } else {
95 pr_debug("%s - IPC_AP_WAKE_INIT1"
96 " - wait for falling edge\n",
97 __func__);
98 }
99 } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
100 if (!value) {
101 pr_debug("%s - IPC_AP_WAKE_INIT2"
102 " - wait for rising edge\n",
103 __func__);
104 } else {
105 pr_debug("%s - IPC_AP_WAKE_INIT2"
106 " - got rising edge\n",
107 __func__);
108 /* go to IPC_AP_WAKE_INIT2 state */
109 ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
110 /* queue work */
111 baseband_xmm_power2_work->state =
112 BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2;
113 queue_work(workqueue, (struct work_struct *)
114 baseband_xmm_power2_work);
115 }
116 } else {
117 if (!value) {
118 pr_debug("%s - falling\n", __func__);
119 ipc_ap_wake_state = IPC_AP_WAKE_L;
120 } else {
121 pr_debug("%s - rising\n", __func__);
122 ipc_ap_wake_state = IPC_AP_WAKE_H;
123 }
124 return baseband_xmm_power_ipc_ap_wake_irq(irq, dev_id);
125 }
126
127 return IRQ_HANDLED;
128}
129
130static irqreturn_t baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2
131 (int irq, void *dev_id)
132{
133 int value;
134
135 pr_debug("%s\n", __func__);
136
137 /* check for platform data */
138 if (!baseband_power2_driver_data)
139 return IRQ_HANDLED;
140
141 value = gpio_get_value(baseband_power2_driver_data->
142 modem.xmm.ipc_ap_wake);
143
144 /* IPC_AP_WAKE state machine */
145 if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
146 pr_err("%s - spurious irq\n", __func__);
147 } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
148 if (!value) {
149 pr_debug("%s - IPC_AP_WAKE_INIT1"
150 " - got falling edge\n",
151 __func__);
152 /* go to IPC_AP_WAKE_INIT2 state */
153 ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
154 /* queue work */
155 baseband_xmm_power2_work->state =
156 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2;
157 queue_work(workqueue, (struct work_struct *)
158 baseband_xmm_power2_work);
159 } else {
160 pr_debug("%s - IPC_AP_WAKE_INIT1"
161 " - wait for falling edge\n",
162 __func__);
163 }
164 } else {
165 if (!value) {
166 pr_debug("%s - falling\n", __func__);
167 ipc_ap_wake_state = IPC_AP_WAKE_L;
168 } else {
169 pr_debug("%s - rising\n", __func__);
170 ipc_ap_wake_state = IPC_AP_WAKE_H;
171 }
172 return baseband_xmm_power_ipc_ap_wake_irq(irq, dev_id);
173 }
174
175 return IRQ_HANDLED;
176}
177
178static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step1
179 (struct work_struct *work)
180{
181 int value;
182
183 pr_debug("%s {\n", __func__);
184
185 /* check for platform data */
186 if (!baseband_power2_driver_data)
187 return;
188
189 /* check if IPC_HSIC_ACTIVE high */
190 value = gpio_get_value(baseband_power2_driver_data->
191 modem.xmm.ipc_hsic_active);
192 if (value != 1) {
193 pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
194 return;
195 }
196
197 /* wait 30 ms */
198 mdelay(30);
199
200 /* set IPC_HSIC_ACTIVE low */
201 gpio_set_value(baseband_power2_driver_data->
202 modem.xmm.ipc_hsic_active, 0);
203
204 pr_debug("%s }\n", __func__);
205}
206
207static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step2
208 (struct work_struct *work)
209{
210 int value;
211
212 pr_debug("%s {\n", __func__);
213
214 /* check for platform data */
215 if (!baseband_power2_driver_data)
216 return;
217
218 /* check if IPC_HSIC_ACTIVE low */
219 value = gpio_get_value(baseband_power2_driver_data->
220 modem.xmm.ipc_hsic_active);
221 if (value != 0) {
222 pr_err("%s - expected IPC_HSIC_ACTIVE low!\n", __func__);
223 return;
224 }
225
226 /* wait 1 ms */
227 mdelay(1);
228
229 /* unregister usb host controller */
230 if (baseband_power2_driver_data->hsic_unregister)
231 baseband_power2_driver_data->hsic_unregister(
232 baseband_power2_driver_data->modem.xmm.hsic_device);
233 else
234 pr_err("%s: hsic_unregister is missing\n", __func__);
235
236 /* set IPC_HSIC_ACTIVE high */
237 gpio_set_value(baseband_power2_driver_data->
238 modem.xmm.ipc_hsic_active, 1);
239
240 /* wait 20 ms */
241 mdelay(20);
242
243 /* set IPC_HSIC_ACTIVE low */
244 gpio_set_value(baseband_power2_driver_data->
245 modem.xmm.ipc_hsic_active, 0);
246
247 /* wait 20 ms */
248 mdelay(20);
249
250 /* set IPC_HSIC_ACTIVE high */
251 gpio_set_value(baseband_power2_driver_data->
252 modem.xmm.ipc_hsic_active, 1);
253
254 pr_debug("%s }\n", __func__);
255}
256
257static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step1
258 (struct work_struct *work)
259{
260 int X = XYZ / 1000000;
261 int Y = XYZ / 1000 - X * 1000;
262 int Z = XYZ % 1000;
263
264 pr_info("%s {\n", __func__);
265
266 pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
267
268 /* check for platform data */
269 if (!baseband_power2_driver_data)
270 return;
271
272 /* unregister usb host controller */
273 if (baseband_power2_driver_data->hsic_unregister)
274 baseband_power2_driver_data->hsic_unregister(
275 baseband_power2_driver_data->modem.xmm.hsic_device);
276 else
277 pr_err("%s: hsic_unregister is missing\n", __func__);
278
279 /* wait X ms */
280 mdelay(X);
281
282 /* set IPC_HSIC_ACTIVE low */
283 gpio_set_value(baseband_power2_driver_data->
284 modem.xmm.ipc_hsic_active, 0);
285
286 pr_info("%s }\n", __func__);
287}
288
289static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step2
290 (struct work_struct *work)
291{
292 int X = XYZ / 1000000;
293 int Y = XYZ / 1000 - X * 1000;
294 int Z = XYZ % 1000;
295
296 pr_info("%s {\n", __func__);
297
298 pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
299
300 /* check for platform data */
301 if (!baseband_power2_driver_data)
302 return;
303
304 /* wait Y ms */
305 mdelay(Y);
306
307 /* register usb host controller */
308 if (baseband_power2_driver_data->hsic_register)
309 baseband_power2_driver_data->modem.xmm.hsic_device =
310 baseband_power2_driver_data->hsic_register();
311 else
312 pr_err("%s: hsic_register is missing\n", __func__);
313
314 /* wait Z ms */
315 mdelay(Z);
316
317 /* set IPC_HSIC_ACTIVE high */
318 gpio_set_value(baseband_power2_driver_data->
319 modem.xmm.ipc_hsic_active, 1);
320
321 /* queue work function to check if enumeration succeeded */
322 baseband_xmm_power2_work->state =
323 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3;
324 queue_work(workqueue, (struct work_struct *)
325 baseband_xmm_power2_work);
326
327 pr_info("%s }\n", __func__);
328}
329
330static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step3
331 (struct work_struct *work)
332{
333 int X = XYZ / 1000000;
334 int Y = XYZ / 1000 - X * 1000;
335 int Z = XYZ % 1000;
336 int enum_success = 0;
337
338 pr_info("%s {\n", __func__);
339
340 pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
341
342 /* check for platform data */
343 if (!baseband_power2_driver_data)
344 return;
345
346 /* wait 500 ms */
347 mdelay(500);
348
349 /* check if enumeration succeeded */
350 {
351 mm_segment_t oldfs;
352 struct file *filp;
353 oldfs = get_fs();
354 set_fs(KERNEL_DS);
355 filp = filp_open("/dev/ttyACM0",
356 O_RDONLY, 0);
357 if (IS_ERR(filp) || (filp == NULL)) {
358 pr_err("/dev/ttyACM0 %ld\n",
359 PTR_ERR(filp));
360 } else {
361 filp_close(filp, NULL);
362 enum_success = 1;
363 }
364 set_fs(oldfs);
365 }
366
367 /* if enumeration failed, attempt recovery pulse */
368 if (!enum_success) {
369 pr_info("attempting recovery pulse...\n");
370 /* wait 20 ms */
371 mdelay(20);
372 /* set IPC_HSIC_ACTIVE low */
373 gpio_set_value(baseband_power2_driver_data->
374 modem.xmm.ipc_hsic_active, 0);
375 /* wait 20 ms */
376 mdelay(20);
377 /* set IPC_HSIC_ACTIVE high */
378 gpio_set_value(baseband_power2_driver_data->
379 modem.xmm.ipc_hsic_active, 1);
380 /* check if recovery pulse worked */
381 baseband_xmm_power2_work->state =
382 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4;
383 queue_work(workqueue, (struct work_struct *)
384 baseband_xmm_power2_work);
385 }
386
387 pr_info("%s }\n", __func__);
388}
389
390static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step4
391 (struct work_struct *work)
392{
393 int X = XYZ / 1000000;
394 int Y = XYZ / 1000 - X * 1000;
395 int Z = XYZ % 1000;
396 int enum_success = 0;
397
398 pr_info("%s {\n", __func__);
399
400 pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
401
402 /* check for platform data */
403 if (!baseband_power2_driver_data)
404 return;
405
406 /* wait 500 ms */
407 mdelay(500);
408
409 /* check if enumeration succeeded */
410 {
411 mm_segment_t oldfs;
412 struct file *filp;
413 oldfs = get_fs();
414 set_fs(KERNEL_DS);
415 filp = filp_open("/dev/ttyACM0",
416 O_RDONLY, 0);
417 if (IS_ERR(filp) || (filp == NULL)) {
418 pr_err("open /dev/ttyACM0 failed %ld\n",
419 PTR_ERR(filp));
420 } else {
421 filp_close(filp, NULL);
422 enum_success = 1;
423 }
424 set_fs(oldfs);
425 }
426
427 /* if recovery pulse did not fix enumeration, retry from beginning */
428 if (!enum_success) {
429 static int retry = 3;
430 if (!retry) {
431 pr_info("failed to enumerate modem software"
432 " - too many retry attempts\n");
433 } else {
434 pr_info("recovery pulse failed to fix modem"
435 " enumeration..."
436 " restarting from beginning"
437 " - attempt #%d\n",
438 retry);
439 --retry;
440 ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
441 baseband_xmm_power2_work->state =
442 BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
443 queue_work(workqueue, (struct work_struct *)
444 baseband_xmm_power2_work);
445 }
446 }
447
448 pr_info("%s }\n", __func__);
449}
450
451static int free_ipc_ap_wake_irq;
452
453static void baseband_xmm_power2_work_func(struct work_struct *work)
454{
455 struct baseband_xmm_power_work_t *bbxmm_work
456 = (struct baseband_xmm_power_work_t *) work;
457 int err;
458
459 pr_debug("%s bbxmm_work->state=%d\n", __func__, bbxmm_work->state);
460
461 switch (bbxmm_work->state) {
462 case BBXMM_WORK_UNINIT:
463 pr_debug("BBXMM_WORK_UNINIT\n");
464 /* free baseband irq(s) */
465 if (free_ipc_ap_wake_irq) {
466 free_irq(gpio_to_irq(baseband_power2_driver_data
467 ->modem.xmm.ipc_ap_wake), NULL);
468 free_ipc_ap_wake_irq = 0;
469 }
470 break;
471 case BBXMM_WORK_INIT:
472 pr_debug("BBXMM_WORK_INIT\n");
473 /* request baseband irq(s) */
474 ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
475 err = request_threaded_irq(
476 gpio_to_irq(baseband_power2_driver_data->
477 modem.xmm.ipc_ap_wake),
478 NULL,
479 (modem_ver < XMM_MODEM_VER_1130)
480 ? baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
481 : baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2,
482 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
483 "BBXMM_POWER2_IPC_AP_WAKE_IRQ",
484 NULL);
485 if (err < 0) {
486 pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
487 __func__);
488 return;
489 }
490 free_ipc_ap_wake_irq = 1;
491 ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
492 /* go to next state */
493 bbxmm_work->state = (modem_flash && !modem_pm)
494 ? BBXMM_WORK_INIT_FLASH_STEP1
495 : (modem_flash && modem_pm)
496 ? BBXMM_WORK_INIT_FLASH_PM_STEP1
497 : (!modem_flash && modem_pm)
498 ? BBXMM_WORK_INIT_FLASHLESS_PM_STEP1
499 : BBXMM_WORK_UNINIT;
500 queue_work(workqueue, work);
501 break;
502 case BBXMM_WORK_INIT_FLASH_STEP1:
503 pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
504 break;
505 case BBXMM_WORK_INIT_FLASH_PM_STEP1:
506 pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
507 /* go to next state */
508 bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
509 ? BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1
510 : BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1;
511 queue_work(workqueue, work);
512 break;
513 case BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1:
514 pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1\n");
515 break;
516 case BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1:
517 pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1\n");
518 break;
519 case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
520 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
521 /* go to next state */
522 bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
523 ? BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ
524 : BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
525 queue_work(workqueue, work);
526 break;
527 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ:
528 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ"
529 " - waiting for IPC_AP_WAKE_IRQ to trigger step1\n");
530 break;
531 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1:
532 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
533 baseband_xmm_power2_flashless_pm_ver_lt_1130_step1(work);
534 break;
535 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2:
536 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2\n");
537 baseband_xmm_power2_flashless_pm_ver_lt_1130_step2(work);
538 break;
539 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
540 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
541 baseband_xmm_power2_flashless_pm_ver_ge_1130_step1(work);
542 break;
543 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2:
544 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2\n");
545 baseband_xmm_power2_flashless_pm_ver_ge_1130_step2(work);
546 break;
547 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3:
548 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3\n");
549 baseband_xmm_power2_flashless_pm_ver_ge_1130_step3(work);
550 break;
551 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4:
552 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4\n");
553 baseband_xmm_power2_flashless_pm_ver_ge_1130_step4(work);
554 break;
555 }
556
557}
558
559static int baseband_xmm_power2_driver_probe(struct platform_device *device)
560{
561 struct baseband_power_platform_data *data
562 = (struct baseband_power_platform_data *)
563 device->dev.platform_data;
564
565 pr_debug("%s\n", __func__);
566
567 /* save platform data */
568 baseband_power2_driver_data = data;
569
570 /* init work queue */
571 pr_debug("%s: init work queue\n", __func__);
572 workqueue = create_singlethread_workqueue
573 ("baseband_xmm_power2_workqueue");
574 if (!workqueue) {
575 pr_err("cannot create workqueue\n");
576 return -1;
577 }
578 baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *)
579 kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
580 if (!baseband_xmm_power2_work) {
581 pr_err("cannot allocate baseband_xmm_power2_work\n");
582 return -1;
583 }
584 pr_debug("%s: BBXMM_WORK_INIT\n", __func__);
585 INIT_WORK((struct work_struct *) baseband_xmm_power2_work,
586 baseband_xmm_power2_work_func);
587 baseband_xmm_power2_work->state = BBXMM_WORK_INIT;
588 queue_work(workqueue,
589 (struct work_struct *) baseband_xmm_power2_work);
590 return 0;
591}
592
593static int baseband_xmm_power2_driver_remove(struct platform_device *device)
594{
595 struct baseband_power_platform_data *data
596 = (struct baseband_power_platform_data *)
597 device->dev.platform_data;
598
599 pr_debug("%s\n", __func__);
600
601 /* check for platform data */
602 if (!data)
603 return 0;
604
605 /* free irq */
606 if (free_ipc_ap_wake_irq) {
607 free_irq(gpio_to_irq(data->modem.xmm.ipc_ap_wake), NULL);
608 free_ipc_ap_wake_irq = 0;
609 }
610
611 /* free work structure */
612 if (workqueue) {
613 cancel_work_sync(baseband_xmm_power2_work);
614 destroy_workqueue(workqueue);
615 }
616 kfree(baseband_xmm_power2_work);
617 baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *) 0;
618
619 return 0;
620}
621
622#ifdef CONFIG_PM
623static int baseband_xmm_power2_driver_suspend(struct platform_device *device,
624 pm_message_t state)
625{
626 struct baseband_power_platform_data *data
627 = (struct baseband_power_platform_data *)
628 device->dev.platform_data;
629
630 pr_debug("%s - nop\n", __func__);
631
632 /* check for platform data */
633 if (!data)
634 return 0;
635
636 return 0;
637}
638
639static int baseband_xmm_power2_driver_resume(struct platform_device *device)
640{
641 struct baseband_power_platform_data *data
642 = (struct baseband_power_platform_data *)
643 device->dev.platform_data;
644
645 pr_debug("%s - nop\n", __func__);
646
647 /* check for platform data */
648 if (!data)
649 return 0;
650
651 return 0;
652}
653#endif
654
655static struct platform_driver baseband_power2_driver = {
656 .probe = baseband_xmm_power2_driver_probe,
657 .remove = baseband_xmm_power2_driver_remove,
658#ifdef CONFIG_PM
659 .suspend = baseband_xmm_power2_driver_suspend,
660 .resume = baseband_xmm_power2_driver_resume,
661#endif
662 .driver = {
663 .name = "baseband_xmm_power2",
664 },
665};
666
667static int __init baseband_xmm_power2_init(void)
668{
669 pr_debug("%s\n", __func__);
670
671 return platform_driver_register(&baseband_power2_driver);
672}
673
674static void __exit baseband_xmm_power2_exit(void)
675{
676 pr_debug("%s\n", __func__);
677 platform_driver_unregister(&baseband_power2_driver);
678}
679
680module_init(baseband_xmm_power2_init)
681module_exit(baseband_xmm_power2_exit)
diff --git a/arch/arm/mach-tegra/board-aruba-panel.c b/arch/arm/mach-tegra/board-aruba-panel.c
new file mode 100644
index 00000000000..b014326fc91
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba-panel.c
@@ -0,0 +1,256 @@
1/*
2 * arch/arm/mach-tegra/board-aruba-panel.c
3 *
4 * Copyright (c) 2010-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/resource.h>
25#include <asm/mach-types.h>
26#include <linux/platform_device.h>
27#include <linux/pwm_backlight.h>
28#include <linux/nvhost.h>
29#include <mach/nvmap.h>
30#include <mach/irqs.h>
31#include <mach/iomap.h>
32#include <mach/dc.h>
33#include <mach/fb.h>
34
35#include "board.h"
36#include "devices.h"
37#include "gpio-names.h"
38
39#define aruba_lvds_shutdown TEGRA_GPIO_PB2
40#define aruba_bl_enb TEGRA_GPIO_PW1
41
42static int aruba_backlight_init(struct device *dev) {
43 int ret;
44
45 ret = gpio_request(aruba_bl_enb, "backlight_enb");
46 if (ret < 0)
47 return ret;
48
49 ret = gpio_direction_output(aruba_bl_enb, 1);
50 if (ret < 0)
51 gpio_free(aruba_bl_enb);
52 else
53 tegra_gpio_enable(aruba_bl_enb);
54
55 return ret;
56};
57
58static void aruba_backlight_exit(struct device *dev) {
59 gpio_set_value(aruba_bl_enb, 0);
60 gpio_free(aruba_bl_enb);
61 tegra_gpio_disable(aruba_bl_enb);
62}
63
64static int aruba_backlight_notify(struct device *unused, int brightness)
65{
66 gpio_set_value(aruba_bl_enb, !!brightness);
67 return brightness;
68}
69
70static struct platform_pwm_backlight_data aruba_backlight_data = {
71 .pwm_id = 2,
72 .max_brightness = 255,
73 .dft_brightness = 224,
74 .pwm_period_ns = 5000000,
75 .init = aruba_backlight_init,
76 .exit = aruba_backlight_exit,
77 .notify = aruba_backlight_notify,
78};
79
80static struct platform_device aruba_backlight_device = {
81 .name = "pwm-backlight",
82 .id = -1,
83 .dev = {
84 .platform_data = &aruba_backlight_data,
85 },
86};
87
88#ifdef CONFIG_TEGRA_DC
89static int aruba_panel_enable(void)
90{
91 static struct regulator *reg = NULL;
92
93 if (reg == NULL) {
94 reg = regulator_get(NULL, "avdd_lvds");
95 if (WARN_ON(IS_ERR(reg)))
96 pr_err("%s: couldn't get regulator avdd_lvds: %ld\n",
97 __func__, PTR_ERR(reg));
98 else
99 regulator_enable(reg);
100 }
101
102 gpio_set_value(aruba_lvds_shutdown, 1);
103 return 0;
104}
105
106static int aruba_panel_disable(void)
107{
108 gpio_set_value(aruba_lvds_shutdown, 0);
109 return 0;
110}
111
112static struct resource aruba_disp1_resources[] = {
113 {
114 .name = "irq",
115 .start = INT_DISPLAY_GENERAL,
116 .end = INT_DISPLAY_GENERAL,
117 .flags = IORESOURCE_IRQ,
118 },
119 {
120 .name = "regs",
121 .start = TEGRA_DISPLAY_BASE,
122 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
123 .flags = IORESOURCE_MEM,
124 },
125 {
126 .name = "fbmem",
127 .start = 0, /* Filled in by aruba_panel_init() */
128 .end = 0, /* Filled in by aruba_panel_init() */
129 .flags = IORESOURCE_MEM,
130 },
131};
132
133static struct tegra_dc_mode aruba_panel_modes[] = {
134 {
135 .pclk = 18000000,
136 .h_ref_to_sync = 8,
137 .v_ref_to_sync = 2,
138 .h_sync_width = 4,
139 .v_sync_width = 1,
140 .h_back_porch = 20,
141 .v_back_porch = 7,
142 .h_active = 480,
143 .v_active = 640,
144 .h_front_porch = 8,
145 .v_front_porch = 8,
146 },
147};
148
149static struct tegra_fb_data aruba_fb_data = {
150 .win = 0,
151 .xres = 480,
152 .yres = 640,
153 .bits_per_pixel = 16,
154};
155
156static struct tegra_dc_out aruba_disp1_out = {
157 .type = TEGRA_DC_OUT_RGB,
158
159 .align = TEGRA_DC_ALIGN_MSB,
160 .order = TEGRA_DC_ORDER_RED_BLUE,
161
162 .modes = aruba_panel_modes,
163 .n_modes = ARRAY_SIZE(aruba_panel_modes),
164
165 .enable = aruba_panel_enable,
166 .disable = aruba_panel_disable,
167};
168
169static struct tegra_dc_platform_data aruba_disp1_pdata = {
170 .flags = TEGRA_DC_FLAG_ENABLED,
171 .default_out = &aruba_disp1_out,
172 .fb = &aruba_fb_data,
173};
174
175static struct nvhost_device aruba_disp1_device = {
176 .name = "tegradc",
177 .id = 0,
178 .resource = aruba_disp1_resources,
179 .num_resources = ARRAY_SIZE(aruba_disp1_resources),
180 .dev = {
181 .platform_data = &aruba_disp1_pdata,
182 },
183};
184#endif
185
186#if defined(CONFIG_TEGRA_NVMAP)
187static struct nvmap_platform_carveout aruba_carveouts[] = {
188 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
189 [1] = {
190 .name = "generic-0",
191 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
192 .base = 0, /* Filled in by aruba_panel_init() */
193 .size = 0, /* Filled in by aruba_panel_init() */
194 .buddy_size = SZ_32K,
195 },
196};
197
198static struct nvmap_platform_data aruba_nvmap_data = {
199 .carveouts = aruba_carveouts,
200 .nr_carveouts = ARRAY_SIZE(aruba_carveouts),
201};
202
203static struct platform_device aruba_nvmap_device = {
204 .name = "tegra-nvmap",
205 .id = -1,
206 .dev = {
207 .platform_data = &aruba_nvmap_data,
208 },
209};
210#endif
211
212static struct platform_device *aruba_gfx_devices[] __initdata = {
213#if defined(CONFIG_TEGRA_NVMAP)
214 &aruba_nvmap_device,
215#endif
216 &tegra_pwfm2_device,
217 &aruba_backlight_device,
218};
219
220int __init aruba_panel_init(void)
221{
222 int err;
223 struct resource __maybe_unused *res;
224
225#if defined(CONFIG_TEGRA_NVMAP)
226 aruba_carveouts[1].base = tegra_carveout_start;
227 aruba_carveouts[1].size = tegra_carveout_size;
228#endif
229
230#ifdef CONFIG_TEGRA_GRHOST
231 err = nvhost_device_register(&tegra_grhost_device);
232 if (err)
233 return err;
234#endif
235
236 err = platform_add_devices(aruba_gfx_devices,
237 ARRAY_SIZE(aruba_gfx_devices));
238
239#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
240 res = nvhost_get_resource_byname(&aruba_disp1_device,
241 IORESOURCE_MEM, "fbmem");
242 res->start = tegra_fb_start;
243 res->end = tegra_fb_start + tegra_fb_size - 1;
244#endif
245
246 /* Copy the bootloader fb to the fb. */
247 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
248 min(tegra_fb_size, tegra_bootloader_fb_size));
249
250#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
251 if (!err)
252 err = nvhost_device_register(&aruba_disp1_device);
253#endif
254
255 return err;
256}
diff --git a/arch/arm/mach-tegra/board-aruba-pinmux.c b/arch/arm/mach-tegra/board-aruba-pinmux.c
new file mode 100644
index 00000000000..3db2ede1eb1
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba-pinmux.c
@@ -0,0 +1,307 @@
1/*
2 * arch/arm/mach-tegra/board-aruba-pinmux.c
3 *
4 * Copyright (C) 2010 NVIDIA Corporation
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 <mach/pinmux.h>
20
21#define DEFAULT_DRIVE(_name) \
22 { \
23 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
24 .hsm = TEGRA_HSM_DISABLE, \
25 .schmitt = TEGRA_SCHMITT_ENABLE, \
26 .drive = TEGRA_DRIVE_DIV_1, \
27 .pull_down = TEGRA_PULL_31, \
28 .pull_up = TEGRA_PULL_31, \
29 .slew_rising = TEGRA_SLEW_SLOWEST, \
30 .slew_falling = TEGRA_SLEW_SLOWEST, \
31 }
32
33
34// !!!FIXME!!!! POPULATE THIS TABLE
35static __initdata struct tegra_drive_pingroup_config aruba_drive_pinmux[] = {
36 /* DEFAULT_DRIVE(<pin_group>), */
37};
38
39#define DEFAULT_PINMUX(_pingroup, _mux, _pupd, _tri, _io) \
40 { \
41 .pingroup = TEGRA_PINGROUP_##_pingroup, \
42 .func = TEGRA_MUX_##_mux, \
43 .pupd = TEGRA_PUPD_##_pupd, \
44 .tristate = TEGRA_TRI_##_tri, \
45 .io = TEGRA_PIN_##_io, \
46 }
47
48// !!!FIXME!!!! POPULATE THIS TABLE
49static __initdata struct tegra_pingroup_config aruba_pinmux[] = {
50 DEFAULT_PINMUX(ULPI_DATA0, UARTA, NORMAL, NORMAL, OUTPUT),
51 DEFAULT_PINMUX(ULPI_DATA1, UARTA, NORMAL, NORMAL, INPUT),
52 DEFAULT_PINMUX(ULPI_DATA2, UARTA, NORMAL, NORMAL, INPUT),
53 DEFAULT_PINMUX(ULPI_DATA3, UARTA, NORMAL, NORMAL, OUTPUT),
54 DEFAULT_PINMUX(ULPI_DATA4, UARTA, NORMAL, NORMAL, INPUT),
55 DEFAULT_PINMUX(ULPI_DATA5, UARTA, NORMAL, NORMAL, INPUT),
56 DEFAULT_PINMUX(ULPI_DATA6, UARTA, NORMAL, NORMAL, INPUT),
57 DEFAULT_PINMUX(ULPI_DATA7, UARTA, NORMAL, NORMAL, OUTPUT),
58 DEFAULT_PINMUX(ULPI_CLK, UARTD, NORMAL, NORMAL, OUTPUT),
59 DEFAULT_PINMUX(ULPI_DIR, UARTD, NORMAL, NORMAL, INPUT),
60 DEFAULT_PINMUX(ULPI_NXT, UARTD, NORMAL, NORMAL, INPUT),
61 DEFAULT_PINMUX(ULPI_STP, UARTD, NORMAL, NORMAL, OUTPUT),
62 DEFAULT_PINMUX(DAP3_FS, I2S2, NORMAL, NORMAL, INPUT),
63 DEFAULT_PINMUX(DAP3_DIN, I2S2, NORMAL, NORMAL, INPUT),
64 DEFAULT_PINMUX(DAP3_DOUT, I2S2, NORMAL, NORMAL, INPUT),
65 DEFAULT_PINMUX(DAP3_SCLK, I2S2, NORMAL, NORMAL, INPUT),
66 DEFAULT_PINMUX(SDMMC1_CLK, SDMMC1, NORMAL, NORMAL, INPUT),
67 DEFAULT_PINMUX(SDMMC1_CMD, SDMMC1, NORMAL, NORMAL, INPUT),
68 DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, NORMAL, NORMAL, INPUT),
69 DEFAULT_PINMUX(SDMMC1_DAT2, SDMMC1, NORMAL, NORMAL, INPUT),
70 DEFAULT_PINMUX(SDMMC1_DAT1, SDMMC1, NORMAL, NORMAL, INPUT),
71 DEFAULT_PINMUX(SDMMC1_DAT0, SDMMC1, NORMAL, NORMAL, INPUT),
72 DEFAULT_PINMUX(GPIO_PV2, OWR, NORMAL, NORMAL, OUTPUT),
73 DEFAULT_PINMUX(GPIO_PV3, CLK12, NORMAL, NORMAL, OUTPUT),
74 DEFAULT_PINMUX(CLK2_OUT, EXTPERIPH2, NORMAL, NORMAL, INPUT),
75 DEFAULT_PINMUX(CLK2_REQ, DAP, NORMAL, NORMAL, INPUT),
76 DEFAULT_PINMUX(LCD_PWR1, DISPLAYA, NORMAL, NORMAL, INPUT),
77 DEFAULT_PINMUX(LCD_PWR2, DISPLAYA, NORMAL, NORMAL, INPUT),
78 DEFAULT_PINMUX(LCD_SDIN, DISPLAYA, NORMAL, NORMAL, INPUT),
79 DEFAULT_PINMUX(LCD_SDOUT, DISPLAYA, NORMAL, NORMAL, INPUT),
80 DEFAULT_PINMUX(LCD_WR_N, DISPLAYA, NORMAL, NORMAL, INPUT),
81 DEFAULT_PINMUX(LCD_CS0_N, DISPLAYA, NORMAL, NORMAL, INPUT),
82 DEFAULT_PINMUX(LCD_DC0, DISPLAYA, NORMAL, NORMAL, INPUT),
83 DEFAULT_PINMUX(LCD_SCK, DISPLAYA, NORMAL, NORMAL, INPUT),
84 DEFAULT_PINMUX(LCD_PWR0, DISPLAYA, NORMAL, NORMAL, INPUT),
85 DEFAULT_PINMUX(LCD_PCLK, DISPLAYA, NORMAL, NORMAL, INPUT),
86 DEFAULT_PINMUX(LCD_DE, DISPLAYA, NORMAL, NORMAL, INPUT),
87 DEFAULT_PINMUX(LCD_HSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
88 DEFAULT_PINMUX(LCD_VSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
89 DEFAULT_PINMUX(LCD_D0, DISPLAYA, NORMAL, NORMAL, INPUT),
90 DEFAULT_PINMUX(LCD_D1, DISPLAYA, NORMAL, NORMAL, INPUT),
91 DEFAULT_PINMUX(LCD_D2, DISPLAYA, NORMAL, NORMAL, INPUT),
92 DEFAULT_PINMUX(LCD_D3, DISPLAYA, NORMAL, NORMAL, INPUT),
93 DEFAULT_PINMUX(LCD_D4, DISPLAYA, NORMAL, NORMAL, INPUT),
94 DEFAULT_PINMUX(LCD_D5, DISPLAYA, NORMAL, NORMAL, INPUT),
95 DEFAULT_PINMUX(LCD_D6, DISPLAYA, NORMAL, NORMAL, INPUT),
96 DEFAULT_PINMUX(LCD_D7, DISPLAYA, NORMAL, NORMAL, INPUT),
97 DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
98 DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
99 DEFAULT_PINMUX(LCD_D10, DISPLAYA, NORMAL, NORMAL, INPUT),
100 DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
101 DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
102 DEFAULT_PINMUX(LCD_D13, DISPLAYA, NORMAL, NORMAL, INPUT),
103 DEFAULT_PINMUX(LCD_D14, DISPLAYA, NORMAL, NORMAL, INPUT),
104 DEFAULT_PINMUX(LCD_D15, DISPLAYA, NORMAL, NORMAL, INPUT),
105 DEFAULT_PINMUX(LCD_D16, DISPLAYA, NORMAL, NORMAL, INPUT),
106 DEFAULT_PINMUX(LCD_D17, DISPLAYA, NORMAL, NORMAL, INPUT),
107 DEFAULT_PINMUX(LCD_D18, DISPLAYA, NORMAL, NORMAL, INPUT),
108 DEFAULT_PINMUX(LCD_D19, DISPLAYA, NORMAL, NORMAL, INPUT),
109 DEFAULT_PINMUX(LCD_D20, DISPLAYA, NORMAL, NORMAL, INPUT),
110 DEFAULT_PINMUX(LCD_D21, DISPLAYA, NORMAL, NORMAL, INPUT),
111 DEFAULT_PINMUX(LCD_D22, DISPLAYA, NORMAL, NORMAL, INPUT),
112 DEFAULT_PINMUX(LCD_D23, DISPLAYA, NORMAL, NORMAL, INPUT),
113 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
114 DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, INPUT),
115 DEFAULT_PINMUX(LCD_DC1, DISPLAYA, NORMAL, NORMAL, INPUT),
116 DEFAULT_PINMUX(DDC_SCL, I2C4, NORMAL, NORMAL, INPUT),
117 DEFAULT_PINMUX(DDC_SDA, I2C4, NORMAL, NORMAL, INPUT),
118 DEFAULT_PINMUX(CRT_HSYNC, CRT, NORMAL, NORMAL, OUTPUT),
119 DEFAULT_PINMUX(CRT_VSYNC, CRT, NORMAL, NORMAL, OUTPUT),
120 DEFAULT_PINMUX(VI_D0, RSVD1, NORMAL, NORMAL, INPUT),
121 DEFAULT_PINMUX(VI_D1, SDMMC2, NORMAL, NORMAL, INPUT),
122 DEFAULT_PINMUX(VI_D2, SDMMC2, NORMAL, NORMAL, INPUT),
123 DEFAULT_PINMUX(VI_D3, SDMMC2, NORMAL, NORMAL, INPUT),
124 DEFAULT_PINMUX(VI_D4, SDMMC2, NORMAL, NORMAL, INPUT),
125 DEFAULT_PINMUX(VI_D5, SDMMC2, NORMAL, NORMAL, INPUT),
126 DEFAULT_PINMUX(VI_D6, SDMMC2, NORMAL, NORMAL, INPUT),
127 DEFAULT_PINMUX(VI_D7, SDMMC2, NORMAL, NORMAL, INPUT),
128 DEFAULT_PINMUX(VI_D8, SDMMC2, NORMAL, NORMAL, INPUT),
129 DEFAULT_PINMUX(VI_D9, SDMMC2, NORMAL, NORMAL, INPUT),
130 DEFAULT_PINMUX(VI_D10, RSVD1, NORMAL, NORMAL, INPUT),
131 DEFAULT_PINMUX(VI_D11, RSVD1, NORMAL, NORMAL, INPUT),
132 DEFAULT_PINMUX(VI_PCLK, SDMMC2, NORMAL, NORMAL, INPUT),
133 DEFAULT_PINMUX(VI_MCLK, VI, NORMAL, NORMAL, INPUT),
134 DEFAULT_PINMUX(VI_VSYNC, RSVD1, NORMAL, NORMAL, INPUT),
135 DEFAULT_PINMUX(VI_HSYNC, RSVD1, NORMAL, NORMAL, INPUT),
136 DEFAULT_PINMUX(UART2_RXD, IRDA, NORMAL, NORMAL, INPUT),
137 DEFAULT_PINMUX(UART2_TXD, IRDA, NORMAL, NORMAL, OUTPUT),
138 DEFAULT_PINMUX(UART2_RTS_N, GMI, NORMAL, NORMAL, OUTPUT),
139 DEFAULT_PINMUX(UART2_CTS_N, GMI, NORMAL, NORMAL, OUTPUT),
140 DEFAULT_PINMUX(UART3_TXD, UARTC, NORMAL, NORMAL, OUTPUT),
141 DEFAULT_PINMUX(UART3_RXD, UARTC, NORMAL, NORMAL, INPUT),
142 DEFAULT_PINMUX(UART3_CTS_N, UARTC, NORMAL, NORMAL, INPUT),
143 DEFAULT_PINMUX(UART3_RTS_N, UARTC, NORMAL, NORMAL, OUTPUT),
144 DEFAULT_PINMUX(GPIO_PU0, RSVD1, NORMAL, NORMAL, INPUT),
145 DEFAULT_PINMUX(GPIO_PU1, RSVD1, NORMAL, NORMAL, INPUT),
146 DEFAULT_PINMUX(GPIO_PU2, RSVD1, NORMAL, NORMAL, INPUT),
147 DEFAULT_PINMUX(GPIO_PU3, PWM0, NORMAL, NORMAL, OUTPUT),
148 DEFAULT_PINMUX(GPIO_PU4, PWM1, NORMAL, NORMAL, OUTPUT),
149 DEFAULT_PINMUX(GPIO_PU5, PWM2, NORMAL, NORMAL, OUTPUT),
150 DEFAULT_PINMUX(GPIO_PU6, PWM3, NORMAL, NORMAL, OUTPUT),
151 DEFAULT_PINMUX(GEN1_I2C_SDA, I2C1, NORMAL, NORMAL, INPUT),
152 DEFAULT_PINMUX(GEN1_I2C_SCL, I2C1, NORMAL, NORMAL, INPUT),
153 DEFAULT_PINMUX(DAP4_FS, I2S3, NORMAL, NORMAL, INPUT),
154 DEFAULT_PINMUX(DAP4_DIN, I2S3, NORMAL, NORMAL, INPUT),
155 DEFAULT_PINMUX(DAP4_DOUT, I2S3, NORMAL, NORMAL, INPUT),
156 DEFAULT_PINMUX(DAP4_SCLK, I2S3, NORMAL, NORMAL, INPUT),
157 DEFAULT_PINMUX(CLK3_OUT, EXTPERIPH3, NORMAL, NORMAL, OUTPUT),
158 DEFAULT_PINMUX(CLK3_REQ, DEV3, NORMAL, NORMAL, INPUT),
159 DEFAULT_PINMUX(GMI_WP_N, RSVD1, NORMAL, NORMAL, INPUT),
160 DEFAULT_PINMUX(GMI_IORDY, NAND, NORMAL, NORMAL, OUTPUT),
161 DEFAULT_PINMUX(GMI_WAIT, NAND, NORMAL, NORMAL, INPUT),
162 DEFAULT_PINMUX(GMI_ADV_N, NAND, NORMAL, NORMAL, OUTPUT),
163 DEFAULT_PINMUX(GMI_CLK, NAND, NORMAL, NORMAL, OUTPUT),
164 DEFAULT_PINMUX(GMI_CS0_N, NAND, NORMAL, NORMAL, OUTPUT),
165 DEFAULT_PINMUX(GMI_CS1_N, NAND, NORMAL, NORMAL, OUTPUT),
166 DEFAULT_PINMUX(GMI_CS2_N, NAND, NORMAL, NORMAL, OUTPUT),
167 DEFAULT_PINMUX(GMI_CS3_N, NAND, NORMAL, NORMAL, OUTPUT),
168 DEFAULT_PINMUX(GMI_CS4_N, NAND, NORMAL, NORMAL, OUTPUT),
169 DEFAULT_PINMUX(GMI_CS6_N, NAND_ALT, NORMAL, NORMAL, OUTPUT),
170 DEFAULT_PINMUX(GMI_CS7_N, NAND_ALT, NORMAL, NORMAL, OUTPUT),
171 DEFAULT_PINMUX(GMI_AD0, NAND, NORMAL, NORMAL, INPUT),
172 DEFAULT_PINMUX(GMI_AD1, NAND, NORMAL, NORMAL, INPUT),
173 DEFAULT_PINMUX(GMI_AD2, NAND, NORMAL, NORMAL, INPUT),
174 DEFAULT_PINMUX(GMI_AD3, NAND, NORMAL, NORMAL, INPUT),
175 DEFAULT_PINMUX(GMI_AD4, NAND, NORMAL, NORMAL, INPUT),
176 DEFAULT_PINMUX(GMI_AD5, NAND, NORMAL, NORMAL, INPUT),
177 DEFAULT_PINMUX(GMI_AD6, NAND, NORMAL, NORMAL, INPUT),
178 DEFAULT_PINMUX(GMI_AD7, NAND, NORMAL, NORMAL, INPUT),
179 DEFAULT_PINMUX(GMI_AD8, NAND, NORMAL, NORMAL, INPUT),
180 DEFAULT_PINMUX(GMI_AD9, NAND, NORMAL, NORMAL, INPUT),
181 DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, INPUT),
182 DEFAULT_PINMUX(GMI_AD11, NAND, NORMAL, NORMAL, INPUT),
183 DEFAULT_PINMUX(GMI_AD12, NAND, NORMAL, NORMAL, INPUT),
184 DEFAULT_PINMUX(GMI_AD13, NAND, NORMAL, NORMAL, INPUT),
185 DEFAULT_PINMUX(GMI_AD14, NAND, NORMAL, NORMAL, INPUT),
186 DEFAULT_PINMUX(GMI_AD15, NAND, NORMAL, NORMAL, INPUT),
187 DEFAULT_PINMUX(GMI_A16, UARTD, NORMAL, NORMAL, OUTPUT),
188 DEFAULT_PINMUX(GMI_A17, UARTD, NORMAL, NORMAL, INPUT),
189 DEFAULT_PINMUX(GMI_A18, UARTD, NORMAL, NORMAL, INPUT),
190 DEFAULT_PINMUX(GMI_A19, UARTD, NORMAL, NORMAL, OUTPUT),
191 DEFAULT_PINMUX(GMI_WR_N, NAND, NORMAL, NORMAL, OUTPUT),
192 DEFAULT_PINMUX(GMI_OE_N, NAND, NORMAL, NORMAL, OUTPUT),
193 DEFAULT_PINMUX(GMI_DQS, NAND, NORMAL, NORMAL, INPUT),
194 DEFAULT_PINMUX(GMI_RST_N, RSVD3, NORMAL, NORMAL, INPUT),
195 DEFAULT_PINMUX(GEN2_I2C_SCL, I2C2, NORMAL, NORMAL, INPUT),
196 DEFAULT_PINMUX(GEN2_I2C_SDA, I2C2, NORMAL, NORMAL, INPUT),
197 DEFAULT_PINMUX(SDMMC4_CLK, SDMMC4, NORMAL, NORMAL, INPUT),
198 DEFAULT_PINMUX(SDMMC4_CMD, SDMMC4, NORMAL, NORMAL, INPUT),
199 DEFAULT_PINMUX(SDMMC4_DAT0, SDMMC4, NORMAL, NORMAL, INPUT),
200 DEFAULT_PINMUX(SDMMC4_DAT1, SDMMC4, NORMAL, NORMAL, INPUT),
201 DEFAULT_PINMUX(SDMMC4_DAT2, SDMMC4, NORMAL, NORMAL, INPUT),
202 DEFAULT_PINMUX(SDMMC4_DAT3, SDMMC4, NORMAL, NORMAL, INPUT),
203 DEFAULT_PINMUX(SDMMC4_DAT4, SDMMC4, NORMAL, NORMAL, INPUT),
204 DEFAULT_PINMUX(SDMMC4_DAT5, SDMMC4, NORMAL, NORMAL, INPUT),
205 DEFAULT_PINMUX(SDMMC4_DAT6, SDMMC4, NORMAL, NORMAL, INPUT),
206 DEFAULT_PINMUX(SDMMC4_DAT7, SDMMC4, NORMAL, NORMAL, INPUT),
207 DEFAULT_PINMUX(SDMMC4_RST_N, RSVD1, NORMAL, NORMAL, INPUT),
208 DEFAULT_PINMUX(CAM_MCLK, VI, NORMAL, NORMAL, INPUT),
209 DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, NORMAL, INPUT),
210 DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, NORMAL, INPUT),
211 DEFAULT_PINMUX(CAM_I2C_SCL, I2C3, NORMAL, NORMAL, INPUT),
212 DEFAULT_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT),
213 DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, NORMAL, INPUT),
214 DEFAULT_PINMUX(GPIO_PBB4, VGP4, NORMAL, NORMAL, INPUT),
215 DEFAULT_PINMUX(GPIO_PBB5, VGP5, NORMAL, NORMAL, INPUT),
216 DEFAULT_PINMUX(GPIO_PBB6, VGP6, NORMAL, NORMAL, INPUT),
217 DEFAULT_PINMUX(GPIO_PBB7, I2S4, NORMAL, NORMAL, INPUT),
218 DEFAULT_PINMUX(GPIO_PCC2, I2S4, NORMAL, NORMAL, INPUT),
219 DEFAULT_PINMUX(JTAG_RTCK, RTCK, NORMAL, NORMAL, OUTPUT),
220 DEFAULT_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT),
221 DEFAULT_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT),
222 DEFAULT_PINMUX(KB_ROW0, KBC, NORMAL, NORMAL, INPUT),
223 DEFAULT_PINMUX(KB_ROW1, KBC, NORMAL, NORMAL, INPUT),
224 DEFAULT_PINMUX(KB_ROW2, KBC, NORMAL, NORMAL, INPUT),
225 DEFAULT_PINMUX(KB_ROW3, KBC, NORMAL, NORMAL, INPUT),
226 DEFAULT_PINMUX(KB_ROW4, KBC, NORMAL, NORMAL, INPUT),
227 DEFAULT_PINMUX(KB_ROW5, KBC, NORMAL, NORMAL, INPUT),
228 DEFAULT_PINMUX(KB_ROW6, KBC, NORMAL, NORMAL, INPUT),
229 DEFAULT_PINMUX(KB_ROW7, KBC, NORMAL, NORMAL, INPUT),
230 DEFAULT_PINMUX(KB_ROW8, KBC, NORMAL, NORMAL, INPUT),
231 DEFAULT_PINMUX(KB_ROW9, KBC, NORMAL, NORMAL, INPUT),
232 DEFAULT_PINMUX(KB_ROW10, KBC, NORMAL, NORMAL, INPUT),
233 DEFAULT_PINMUX(KB_ROW11, KBC, NORMAL, NORMAL, INPUT),
234 DEFAULT_PINMUX(KB_ROW12, KBC, NORMAL, NORMAL, INPUT),
235 DEFAULT_PINMUX(KB_ROW13, KBC, NORMAL, NORMAL, INPUT),
236 DEFAULT_PINMUX(KB_ROW14, KBC, NORMAL, NORMAL, INPUT),
237 DEFAULT_PINMUX(KB_ROW15, KBC, NORMAL, NORMAL, INPUT),
238 DEFAULT_PINMUX(KB_COL0, KBC, NORMAL, NORMAL, INPUT),
239 DEFAULT_PINMUX(KB_COL1, KBC, NORMAL, NORMAL, INPUT),
240 DEFAULT_PINMUX(KB_COL2, KBC, NORMAL, NORMAL, INPUT),
241 DEFAULT_PINMUX(KB_COL3, KBC, NORMAL, NORMAL, INPUT),
242 DEFAULT_PINMUX(KB_COL4, KBC, NORMAL, NORMAL, INPUT),
243 DEFAULT_PINMUX(KB_COL5, KBC, NORMAL, NORMAL, INPUT),
244 DEFAULT_PINMUX(KB_COL6, KBC, NORMAL, NORMAL, INPUT),
245 DEFAULT_PINMUX(KB_COL7, KBC, NORMAL, NORMAL, INPUT),
246 DEFAULT_PINMUX(CLK_32K_OUT, BLINK, NORMAL, NORMAL, OUTPUT),
247 DEFAULT_PINMUX(SYS_CLK_REQ, SYSCLK, NORMAL, NORMAL, OUTPUT),
248 DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT),
249#ifdef CONFIG_SND_HDA_TEGRA
250 DEFAULT_PINMUX(DAP1_FS, HDA, NORMAL, NORMAL, INPUT),
251 DEFAULT_PINMUX(DAP1_DIN, HDA, NORMAL, NORMAL, INPUT),
252 DEFAULT_PINMUX(DAP1_DOUT, HDA, NORMAL, NORMAL, INPUT),
253 DEFAULT_PINMUX(DAP1_SCLK, HDA, NORMAL, NORMAL, INPUT),
254 DEFAULT_PINMUX(CLK1_REQ, DAP1, NORMAL, NORMAL, INPUT),
255#else
256 DEFAULT_PINMUX(DAP1_FS, I2S0, NORMAL, NORMAL, INPUT),
257 DEFAULT_PINMUX(DAP1_DIN, I2S0, NORMAL, NORMAL, INPUT),
258 DEFAULT_PINMUX(DAP1_DOUT, I2S0, NORMAL, NORMAL, INPUT),
259 DEFAULT_PINMUX(DAP1_SCLK, I2S0, NORMAL, NORMAL, INPUT),
260 DEFAULT_PINMUX(CLK1_REQ, DAP, NORMAL, NORMAL, INPUT),
261#endif
262 DEFAULT_PINMUX(CLK1_OUT, EXTPERIPH1, NORMAL, NORMAL, INPUT),
263 DEFAULT_PINMUX(SPDIF_IN, SPDIF, NORMAL, NORMAL, INPUT),
264 DEFAULT_PINMUX(SPDIF_OUT, SPDIF, NORMAL, NORMAL, OUTPUT),
265 DEFAULT_PINMUX(DAP2_FS, I2S1, NORMAL, NORMAL, INPUT),
266 DEFAULT_PINMUX(DAP2_DIN, I2S1, NORMAL, NORMAL, INPUT),
267 DEFAULT_PINMUX(DAP2_DOUT, I2S1, NORMAL, NORMAL, INPUT),
268 DEFAULT_PINMUX(DAP2_SCLK, I2S1, NORMAL, NORMAL, INPUT),
269 DEFAULT_PINMUX(SPI2_MOSI, SPI6, NORMAL, NORMAL, INPUT),
270 DEFAULT_PINMUX(SPI2_MISO, SPI6, NORMAL, NORMAL, INPUT),
271 DEFAULT_PINMUX(SPI2_CS0_N, SPI6, NORMAL, NORMAL, INPUT),
272 DEFAULT_PINMUX(SPI2_SCK, SPI6, NORMAL, NORMAL, INPUT),
273 DEFAULT_PINMUX(SPI1_MOSI, SPI1, NORMAL, NORMAL, INPUT),
274 DEFAULT_PINMUX(SPI1_SCK, SPI1, NORMAL, NORMAL, INPUT),
275 DEFAULT_PINMUX(SPI1_CS0_N, SPI1, NORMAL, NORMAL, INPUT),
276 DEFAULT_PINMUX(SPI1_MISO, SPI1, NORMAL, NORMAL, INPUT),
277 DEFAULT_PINMUX(SPI2_CS1_N, SPI3, NORMAL, NORMAL, INPUT),
278 DEFAULT_PINMUX(SPI2_CS2_N, SPI3, NORMAL, NORMAL, INPUT),
279 DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT),
280 DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, NORMAL, NORMAL, INPUT),
281 DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, NORMAL, NORMAL, INPUT),
282 DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, NORMAL, NORMAL, INPUT),
283 DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, NORMAL, NORMAL, INPUT),
284 DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, NORMAL, NORMAL, INPUT),
285 DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, NORMAL, NORMAL, INPUT),
286 DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, NORMAL, NORMAL, INPUT),
287 DEFAULT_PINMUX(SDMMC3_DAT6, SDMMC3, NORMAL, NORMAL, INPUT),
288 DEFAULT_PINMUX(SDMMC3_DAT7, SDMMC3, NORMAL, NORMAL, INPUT),
289 DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
290 DEFAULT_PINMUX(PEX_L0_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
291 DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
292 DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT),
293 DEFAULT_PINMUX(PEX_L1_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
294 DEFAULT_PINMUX(PEX_L1_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
295 DEFAULT_PINMUX(PEX_L1_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
296 DEFAULT_PINMUX(PEX_L2_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
297 DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
298 DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
299 DEFAULT_PINMUX(HDMI_CEC, CEC, NORMAL, NORMAL, INPUT),
300};
301
302void __init aruba_pinmux_init(void)
303{
304 tegra_pinmux_config_table(aruba_pinmux, ARRAY_SIZE(aruba_pinmux));
305 tegra_drive_pinmux_config_table(aruba_drive_pinmux,
306 ARRAY_SIZE(aruba_drive_pinmux));
307}
diff --git a/arch/arm/mach-tegra/board-aruba-power.c b/arch/arm/mach-tegra/board-aruba-power.c
new file mode 100644
index 00000000000..4391f6f19b5
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba-power.c
@@ -0,0 +1,76 @@
1/*
2 * Copyright (C) 2010 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/pda_power.h>
20#include <linux/platform_device.h>
21#include <linux/resource.h>
22#include <linux/io.h>
23
24#include <mach/iomap.h>
25#include <mach/irqs.h>
26
27#include "pm.h"
28#include "board.h"
29#include "wakeups-t3.h"
30
31static int ac_online(void)
32{
33 return 1;
34}
35
36static struct resource aruba_pda_resources[] = {
37 [0] = {
38 .name = "ac",
39 },
40};
41
42static struct pda_power_pdata aruba_pda_data = {
43 .is_ac_online = ac_online,
44};
45
46static struct platform_device aruba_pda_power_device = {
47 .name = "pda-power",
48 .id = -1,
49 .resource = aruba_pda_resources,
50 .num_resources = ARRAY_SIZE(aruba_pda_resources),
51 .dev = {
52 .platform_data = &aruba_pda_data,
53 },
54};
55
56static struct tegra_suspend_platform_data aruba_suspend_data = {
57 .cpu_timer = 2000,
58 .cpu_off_timer = 0,
59 .suspend_mode = TEGRA_SUSPEND_NONE,
60 .core_timer = 0x7e7e,
61 .core_off_timer = 0,
62 .corereq_high = false,
63 .sysclkreq_high = true,
64};
65
66int __init aruba_regulator_init(void)
67{
68 platform_device_register(&aruba_pda_power_device);
69 tegra_init_suspend(&aruba_suspend_data);
70 return 0;
71}
72
73void __init tegra_tsensor_init(void)
74{
75 /* No tsensor on FPGAs */
76}
diff --git a/arch/arm/mach-tegra/board-aruba-sdhci.c b/arch/arm/mach-tegra/board-aruba-sdhci.c
new file mode 100644
index 00000000000..26b04a9021e
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba-sdhci.c
@@ -0,0 +1,248 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-sdhci.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/resource.h>
18#include <linux/platform_device.h>
19#include <linux/wlan_plat.h>
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/mmc/host.h>
25
26#include <asm/mach-types.h>
27#include <mach/irqs.h>
28#include <mach/iomap.h>
29#include <mach/sdhci.h>
30
31#include "gpio-names.h"
32#include "board.h"
33
34#define ARUBA_WIFI 0 /* !!!FIXME!!! NOT SUPPORTED YET */
35
36#if ARUBA_WIFI
37
38#define ARUBA_WLAN_PWR TEGRA_GPIO_PK5
39#define ARUBA_WLAN_RST TEGRA_GPIO_PK6
40
41static void (*wifi_status_cb)(int card_present, void *dev_id);
42static void *wifi_status_cb_devid;
43static int aruba_wifi_status_register(void (*callback)(int , void *), void *);
44static struct clk *wifi_32k_clk;
45
46static int aruba_wifi_reset(int on);
47static int aruba_wifi_power(int on);
48static int aruba_wifi_set_carddetect(int val);
49
50static struct wifi_platform_data aruba_wifi_control = {
51 .set_power = aruba_wifi_power,
52 .set_reset = aruba_wifi_reset,
53 .set_carddetect = aruba_wifi_set_carddetect,
54};
55
56static struct platform_device aruba_wifi_device = {
57 .name = "bcm4329_wlan",
58 .id = 1,
59 .dev = {
60 .platform_data = &aruba_wifi_control,
61 },
62};
63#endif
64
65static struct resource sdhci_resource0[] = {
66 [0] = {
67 .start = INT_SDMMC1,
68 .end = INT_SDMMC1,
69 .flags = IORESOURCE_IRQ,
70 },
71 [1] = {
72 .start = TEGRA_SDMMC1_BASE,
73 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
74 .flags = IORESOURCE_MEM,
75 },
76};
77
78static struct resource sdhci_resource2[] = {
79 [0] = {
80 .start = INT_SDMMC3,
81 .end = INT_SDMMC3,
82 .flags = IORESOURCE_IRQ,
83 },
84 [1] = {
85 .start = TEGRA_SDMMC3_BASE,
86 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
87 .flags = IORESOURCE_MEM,
88 },
89};
90
91static struct resource sdhci_resource3[] = {
92 [0] = {
93 .start = INT_SDMMC4,
94 .end = INT_SDMMC4,
95 .flags = IORESOURCE_IRQ,
96 },
97 [1] = {
98 .start = TEGRA_SDMMC4_BASE,
99 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
100 .flags = IORESOURCE_MEM,
101 },
102};
103
104
105static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
106#if ARUBA_WIFI /* !!!FIXME!!! NOT SUPPORTED YET */
107 .register_status_notify = aruba_wifi_status_register,
108 .cccr = {
109 .sdio_vsn = 2,
110 .multi_block = 1,
111 .low_speed = 0,
112 .wide_bus = 0,
113 .high_power = 1,
114 .high_speed = 1,
115 },
116 .cis = {
117 .vendor = 0x02d0,
118 .device = 0x4329,
119 },
120#endif
121 .cd_gpio = -1,
122 .wp_gpio = -1,
123 .power_gpio = -1,
124/* .max_clk = 12000000, */
125};
126
127static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
128 .cd_gpio = -1,
129 .wp_gpio = -1,
130 .power_gpio = -1,
131/* .max_clk = 12000000, */
132};
133
134static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
135 .cd_gpio = -1,
136 .wp_gpio = -1,
137 .power_gpio = -1,
138/* .max_clk = 12000000, */
139};
140
141static struct platform_device tegra_sdhci_device0 = {
142 .name = "sdhci-tegra",
143 .id = 0,
144 .resource = sdhci_resource0,
145 .num_resources = ARRAY_SIZE(sdhci_resource0),
146 .dev = {
147 .platform_data = &tegra_sdhci_platform_data0,
148 },
149};
150
151static struct platform_device tegra_sdhci_device2 = {
152 .name = "sdhci-tegra",
153 .id = 2,
154 .resource = sdhci_resource2,
155 .num_resources = ARRAY_SIZE(sdhci_resource2),
156 .dev = {
157 .platform_data = &tegra_sdhci_platform_data2,
158 },
159};
160
161static struct platform_device tegra_sdhci_device3 = {
162 .name = "sdhci-tegra",
163 .id = 3,
164 .resource = sdhci_resource3,
165 .num_resources = ARRAY_SIZE(sdhci_resource3),
166 .dev = {
167 .platform_data = &tegra_sdhci_platform_data3,
168 },
169};
170
171#if ARUBA_WIFI /* !!!FIXME!!! NOT SUPPORTED YET */
172static int aruba_wifi_status_register(
173 void (*callback)(int card_present, void *dev_id),
174 void *dev_id)
175{
176 if (wifi_status_cb)
177 return -EAGAIN;
178 wifi_status_cb = callback;
179 wifi_status_cb_devid = dev_id;
180 return 0;
181}
182
183static int aruba_wifi_set_carddetect(int val)
184{
185 pr_debug("%s: %d\n", __func__, val);
186 if (wifi_status_cb)
187 wifi_status_cb(val, wifi_status_cb_devid);
188 else
189 pr_warning("%s: Nobody to notify\n", __func__);
190 return 0;
191}
192
193static int aruba_wifi_power(int on)
194{
195 pr_debug("%s: %d\n", __func__, on);
196
197 gpio_set_value(ARUBA_WLAN_PWR, on);
198 mdelay(100);
199 gpio_set_value(ARUBA_WLAN_RST, on);
200 mdelay(200);
201
202 if (on)
203 clk_enable(wifi_32k_clk);
204 else
205 clk_disable(wifi_32k_clk);
206
207 return 0;
208}
209
210static int aruba_wifi_reset(int on)
211{
212 pr_debug("%s: do nothing\n", __func__);
213 return 0;
214}
215
216static int __init aruba_wifi_init(void)
217{
218 wifi_32k_clk = clk_get_sys(NULL, "blink");
219 if (IS_ERR(wifi_32k_clk)) {
220 pr_err("%s: unable to get blink clock\n", __func__);
221 return PTR_ERR(wifi_32k_clk);
222 }
223
224 gpio_request(ARUBA_WLAN_PWR, "wlan_power");
225 gpio_request(ARUBA_WLAN_RST, "wlan_rst");
226
227 tegra_gpio_enable(ARUBA_WLAN_PWR);
228 tegra_gpio_enable(ARUBA_WLAN_RST);
229
230 gpio_direction_output(ARUBA_WLAN_PWR, 0);
231 gpio_direction_output(ARUBA_WLAN_RST, 0);
232
233 platform_device_register(&aruba_wifi_device);
234 return 0;
235}
236#else
237#define aruba_wifi_init() do {} while (0)
238#endif
239
240int __init aruba_sdhci_init(void)
241{
242 platform_device_register(&tegra_sdhci_device3);
243 platform_device_register(&tegra_sdhci_device2);
244 platform_device_register(&tegra_sdhci_device0);
245
246 aruba_wifi_init();
247 return 0;
248}
diff --git a/arch/arm/mach-tegra/board-aruba-sensors.c b/arch/arm/mach-tegra/board-aruba-sensors.c
new file mode 100644
index 00000000000..f5ba3d76163
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba-sensors.c
@@ -0,0 +1,109 @@
1/*
2 * arch/arm/mach-tegra/board-aruba-sensors.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/i2c.h>
35#include <mach/gpio.h>
36
37#include "gpio-names.h"
38
39#if 0 // !!!FIXME!!! IMPLEMENT ME
40
41#define ISL29018_IRQ_GPIO TEGRA_GPIO_PZ2
42#define AKM8975_IRQ_GPIO TEGRA_GPIO_PN5
43
44static void aruba_isl29018_init(void)
45{
46 tegra_gpio_enable(ISL29018_IRQ_GPIO);
47 gpio_request(ISL29018_IRQ_GPIO, "isl29018");
48 gpio_direction_input(ISL29018_IRQ_GPIO);
49}
50
51static void aruba_akm8975_init(void)
52{
53 tegra_gpio_enable(AKM8975_IRQ_GPIO);
54 gpio_request(AKM8975_IRQ_GPIO, "akm8975");
55 gpio_direction_input(AKM8975_IRQ_GPIO);
56}
57
58struct nct1008_platform_data aruba_nct1008_pdata = {
59 .conv_rate = 5,
60 .config = NCT1008_CONFIG_ALERT_DISABLE,
61 .thermal_threshold = 110,
62};
63
64static const struct i2c_board_info aruba_i2c0_board_info[] = {
65 {
66 I2C_BOARD_INFO("isl29018", 0x44),
67 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PZ2),
68 },
69};
70
71static const struct i2c_board_info aruba_i2c2_board_info[] = {
72 {
73 I2C_BOARD_INFO("bq20z75-battery", 0x0B),
74 },
75};
76
77static struct i2c_board_info aruba_i2c4_board_info[] = {
78 {
79 I2C_BOARD_INFO("nct1008", 0x4C),
80 .platform_data = &aruba_nct1008_pdata,
81 },
82 {
83 I2C_BOARD_INFO("akm8975", 0x0C),
84 .irq = TEGRA_GPIO_TO_IRQ(AKM8975_IRQ_GPIO),
85 }
86};
87
88int __init aruba_sensors_init(void)
89{
90 aruba_isl29018_init();
91 aruba_akm8975_init();
92
93 i2c_register_board_info(0, aruba_i2c0_board_info,
94 ARRAY_SIZE(aruba_i2c0_board_info));
95
96 i2c_register_board_info(2, aruba_i2c2_board_info,
97 ARRAY_SIZE(aruba_i2c2_board_info));
98
99 i2c_register_board_info(4, aruba_i2c4_board_info,
100 ARRAY_SIZE(aruba_i2c4_board_info));
101
102 return 0;
103}
104#else
105int __init aruba_sensors_init(void)
106{
107 return 0;
108}
109#endif
diff --git a/arch/arm/mach-tegra/board-aruba.c b/arch/arm/mach-tegra/board-aruba.c
new file mode 100644
index 00000000000..152f3472048
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba.c
@@ -0,0 +1,544 @@
1/*
2 * arch/arm/mach-tegra/board-aruba.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/serial_8250.h>
28#include <linux/i2c.h>
29#include <linux/i2c/panjit_ts.h>
30#include <linux/dma-mapping.h>
31#include <linux/delay.h>
32#include <linux/i2c-tegra.h>
33#include <linux/gpio.h>
34#include <linux/gpio_keys.h>
35#include <linux/input.h>
36#include <linux/platform_data/tegra_usb.h>
37#include <mach/clk.h>
38#include <mach/iomap.h>
39#include <mach/irqs.h>
40#include <mach/pinmux.h>
41#include <mach/iomap.h>
42#include <mach/io.h>
43#include <mach/i2s.h>
44#include <mach/audio.h>
45#include <mach/tegra_das.h>
46#include <asm/mach-types.h>
47#include <asm/mach/arch.h>
48#include <mach/usb_phy.h>
49#include <mach/nand.h>
50#include "board.h"
51#include "clock.h"
52#include "board-aruba.h"
53#include "devices.h"
54#include "gpio-names.h"
55#include "fuse.h"
56
57#define ENABLE_OTG 0
58
59static struct plat_serial8250_port debug_uart_platform_data[] = {
60 {
61 .membase = IO_ADDRESS(TEGRA_UARTA_BASE),
62 .mapbase = TEGRA_UARTA_BASE,
63 .irq = INT_UARTA,
64 .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
65 .type = PORT_TEGRA,
66 .iotype = UPIO_MEM,
67 .regshift = 2,
68 .uartclk = 13000000,
69 }, {
70 .flags = 0,
71 }
72};
73
74static struct platform_device debug_uart = {
75 .name = "serial8250",
76 .id = PLAT8250_DEV_PLATFORM,
77 .dev = {
78 .platform_data = debug_uart_platform_data,
79 },
80};
81
82/* !!!FIXME!!! THESE ARE VENTANA SETTINGS */
83static struct tegra_utmip_config utmi_phy_config[] = {
84 [0] = {
85 .hssync_start_delay = 0,
86 .idle_wait_delay = 17,
87 .elastic_limit = 16,
88 .term_range_adj = 6,
89 .xcvr_setup = 15,
90 .xcvr_lsfslew = 2,
91 .xcvr_lsrslew = 2,
92 },
93 [1] = {
94 .hssync_start_delay = 0,
95 .idle_wait_delay = 17,
96 .elastic_limit = 16,
97 .term_range_adj = 6,
98 .xcvr_setup = 8,
99 .xcvr_lsfslew = 2,
100 .xcvr_lsrslew = 2,
101 },
102};
103
104/* !!!FIXME!!! THESE ARE VENTANA SETTINGS */
105static struct tegra_ulpi_config ulpi_phy_config = {
106 .clk = "cdev2",
107};
108
109#ifdef CONFIG_BCM4329_RFKILL
110
111static struct resource aruba_bcm4329_rfkill_resources[] = {
112 {
113 .name = "bcm4329_nreset_gpio",
114 .start = TEGRA_GPIO_PU0,
115 .end = TEGRA_GPIO_PU0,
116 .flags = IORESOURCE_IO,
117 },
118 {
119 .name = "bcm4329_nshutdown_gpio",
120 .start = TEGRA_GPIO_PK2,
121 .end = TEGRA_GPIO_PK2,
122 .flags = IORESOURCE_IO,
123 },
124};
125
126static struct platform_device aruba_bcm4329_rfkill_device = {
127 .name = "bcm4329_rfkill",
128 .id = -1,
129 .num_resources = ARRAY_SIZE(aruba_bcm4329_rfkill_resources),
130 .resource = aruba_bcm4329_rfkill_resources,
131};
132
133static noinline void __init aruba_bt_rfkill(void)
134{
135 /*Add Clock Resource*/
136 clk_add_alias("bcm4329_32k_clk", aruba_bcm4329_rfkill_device.name, \
137 "blink", NULL);
138
139 platform_device_register(&aruba_bcm4329_rfkill_device);
140
141 return;
142}
143#else
144static inline void aruba_bt_rfkill(void) { }
145#endif
146
147static __initdata struct tegra_clk_init_table aruba_clk_init_table[] = {
148 /* name parent rate enabled */
149 { "uarta", "clk_m", 13000000, true},
150 { "uartb", "clk_m", 13000000, true},
151 { "uartc", "clk_m", 13000000, true},
152 { "uartd", "clk_m", 13000000, true},
153 { "uarte", "clk_m", 13000000, true},
154 { "pll_m", NULL, 0, true},
155 { "blink", "clk_32k", 32768, false},
156 { "pll_p_out4", "pll_p", 24000000, true },
157 { "pwm", "clk_32k", 32768, false},
158 { "blink", "clk_32k", 32768, false},
159 { "pll_a", NULL, 56448000, true},
160 { "pll_a_out0", NULL, 11289600, true},
161 { "i2s1", "pll_a_out0", 11289600, true},
162 { "i2s2", "pll_a_out0", 11289600, true},
163 { "d_audio", "pll_a_out0", 11289600, false},
164 { "audio_2x", "audio", 22579200, true},
165 { NULL, NULL, 0, 0},
166};
167
168struct tegra_das_platform_data tegra_das_pdata = {
169 .tegra_dap_port_info_table = {
170 /* I2S0 <--> NULL */
171 [0] = {
172 .dac_port = tegra_das_port_none,
173 .codec_type = tegra_audio_codec_type_none,
174 .device_property = {
175 .num_channels = 0,
176 .bits_per_sample = 0,
177 .rate = 0,
178 .master = 0,
179 .lrck_high_left = false,
180 .dac_dap_data_comm_format = 0,
181 },
182 },
183 /* I2S1 <--> Hifi Codec */
184 [1] = {
185 .dac_port = tegra_das_port_i2s1,
186 .codec_type = tegra_audio_codec_type_hifi,
187 .device_property = {
188 .num_channels = 2,
189 .bits_per_sample = 16,
190 .rate = 48000,
191 .master = 0,
192 .lrck_high_left = false,
193 .dac_dap_data_comm_format =
194 dac_dap_data_format_i2s,
195 },
196 },
197 /* I2s2 <--> BB */
198 [2] = {
199 .dac_port = tegra_das_port_i2s2,
200 .codec_type = tegra_audio_codec_type_baseband,
201 .device_property = {
202 .num_channels = 1,
203 .bits_per_sample = 16,
204 .rate = 16000,
205 .master = 0,
206 .lrck_high_left = true,
207 .dac_dap_data_comm_format =
208 dac_dap_data_format_dsp,
209 },
210 },
211 /* I2s3 <--> BT */
212 [3] = {
213 .dac_port = tegra_das_port_i2s3,
214 .codec_type = tegra_audio_codec_type_bluetooth,
215 .device_property = {
216 .num_channels = 1,
217 .bits_per_sample = 16,
218 .rate = 8000,
219 .master = 0,
220 .lrck_high_left = false,
221 .dac_dap_data_comm_format =
222 dac_dap_data_format_dsp,
223 },
224 },
225 [4] = {
226 .dac_port = tegra_das_port_none,
227 .codec_type = tegra_audio_codec_type_none,
228 .device_property = {
229 .num_channels = 0,
230 .bits_per_sample = 0,
231 .rate = 0,
232 .master = 0,
233 .lrck_high_left = false,
234 .dac_dap_data_comm_format = 0,
235 },
236 },
237 },
238};
239
240static struct i2c_board_info __initdata aruba_i2c_bus1_board_info[] = {
241 {
242 I2C_BOARD_INFO("wm8903", 0x1a),
243 },
244};
245
246static struct tegra_i2c_platform_data aruba_i2c1_platform_data = {
247 .adapter_nr = 0,
248 .bus_count = 1,
249 .bus_clk_rate = { 100000, 0 },
250};
251
252#if 0 /* !!!FIXME!!! THESE ARE VENTANA SETTINGS */
253static const struct tegra_pingroup_config i2c2_ddc = {
254 .pingroup = TEGRA_PINGROUP_DDC,
255 .func = TEGRA_MUX_I2C2,
256};
257
258static const struct tegra_pingroup_config i2c2_gen2 = {
259 .pingroup = TEGRA_PINGROUP_PTA,
260 .func = TEGRA_MUX_I2C2,
261};
262#endif
263
264static struct tegra_i2c_platform_data aruba_i2c2_platform_data = {
265 .adapter_nr = 1,
266 .bus_count = 2,
267 .bus_clk_rate = { 100000, 100000 },
268#if 0 /* !!!FIXME!!!! TESE ARE VENTANA SETTINGS */
269 .bus_mux = { &i2c2_ddc, &i2c2_gen2 },
270 .bus_mux_len = { 1, 1 },
271#endif
272};
273
274static struct tegra_i2c_platform_data aruba_i2c3_platform_data = {
275 .adapter_nr = 3,
276 .bus_count = 1,
277 .bus_clk_rate = { 100000, 0 },
278};
279
280static struct tegra_i2c_platform_data aruba_i2c4_platform_data = {
281 .adapter_nr = 4,
282 .bus_count = 1,
283 .bus_clk_rate = { 100000, 0 },
284};
285
286static struct tegra_i2c_platform_data aruba_i2c5_platform_data = {
287 .adapter_nr = 5,
288 .bus_count = 1,
289 .bus_clk_rate = { 100000, 0 },
290};
291
292static void aruba_i2c_init(void)
293{
294 tegra_i2c_device1.dev.platform_data = &aruba_i2c1_platform_data;
295 tegra_i2c_device2.dev.platform_data = &aruba_i2c2_platform_data;
296 tegra_i2c_device3.dev.platform_data = &aruba_i2c3_platform_data;
297 tegra_i2c_device4.dev.platform_data = &aruba_i2c4_platform_data;
298 tegra_i2c_device5.dev.platform_data = &aruba_i2c5_platform_data;
299
300 i2c_register_board_info(0, aruba_i2c_bus1_board_info, 1);
301
302 platform_device_register(&tegra_i2c_device5);
303 platform_device_register(&tegra_i2c_device4);
304 platform_device_register(&tegra_i2c_device3);
305 platform_device_register(&tegra_i2c_device2);
306 platform_device_register(&tegra_i2c_device1);
307}
308
309#define GPIO_KEY(_id, _gpio, _iswake) \
310 { \
311 .code = _id, \
312 .gpio = TEGRA_GPIO_##_gpio, \
313 .active_low = 1, \
314 .desc = #_id, \
315 .type = EV_KEY, \
316 .wakeup = _iswake, \
317 .debounce_interval = 10, \
318 }
319
320// !!!FIXME!!! THESE ARE VENTANA DEFINITIONS
321static struct gpio_keys_button aruba_keys[] = {
322 [0] = GPIO_KEY(KEY_MENU, PQ0, 0),
323 [1] = GPIO_KEY(KEY_HOME, PQ1, 0),
324 [2] = GPIO_KEY(KEY_BACK, PQ2, 0),
325 [3] = GPIO_KEY(KEY_VOLUMEUP, PQ3, 0),
326 [4] = GPIO_KEY(KEY_VOLUMEDOWN, PQ4, 0),
327 [5] = GPIO_KEY(KEY_POWER, PV2, 1),
328};
329
330static struct gpio_keys_platform_data aruba_keys_platform_data = {
331 .buttons = aruba_keys,
332 .nbuttons = ARRAY_SIZE(aruba_keys),
333};
334
335static struct platform_device aruba_keys_device = {
336 .name = "gpio-keys",
337 .id = 0,
338 .dev = {
339 .platform_data = &aruba_keys_platform_data,
340 },
341};
342
343static struct resource tegra_rtc_resources[] = {
344 [0] = {
345 .start = TEGRA_RTC_BASE,
346 .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1,
347 .flags = IORESOURCE_MEM,
348 },
349 [1] = {
350 .start = INT_RTC,
351 .end = INT_RTC,
352 .flags = IORESOURCE_IRQ,
353 },
354};
355
356static struct platform_device tegra_rtc_device = {
357 .name = "tegra_rtc",
358 .id = -1,
359 .resource = tegra_rtc_resources,
360 .num_resources = ARRAY_SIZE(tegra_rtc_resources),
361};
362
363#if defined(CONFIG_MTD_NAND_TEGRA)
364static struct resource nand_resources[] = {
365 [0] = {
366 .start = INT_NANDFLASH,
367 .end = INT_NANDFLASH,
368 .flags = IORESOURCE_IRQ
369 },
370 [1] = {
371 .start = TEGRA_NAND_BASE,
372 .end = TEGRA_NAND_BASE + TEGRA_NAND_SIZE - 1,
373 .flags = IORESOURCE_MEM
374 }
375};
376
377static struct tegra_nand_chip_parms nand_chip_parms[] = {
378 /* Samsung K5E2G1GACM */
379 [0] = {
380 .vendor_id = 0xEC,
381 .device_id = 0xAA,
382 .capacity = 256,
383 .timing = {
384 .trp = 21,
385 .trh = 15,
386 .twp = 21,
387 .twh = 15,
388 .tcs = 31,
389 .twhr = 60,
390 .tcr_tar_trr = 20,
391 .twb = 100,
392 .trp_resp = 30,
393 .tadl = 100,
394 },
395 },
396 /* Hynix H5PS1GB3EFR */
397 [1] = {
398 .vendor_id = 0xAD,
399 .device_id = 0xDC,
400 .capacity = 512,
401 .timing = {
402 .trp = 12,
403 .trh = 10,
404 .twp = 12,
405 .twh = 10,
406 .tcs = 20,
407 .twhr = 80,
408 .tcr_tar_trr = 20,
409 .twb = 100,
410 .trp_resp = 20,
411 .tadl = 70,
412 },
413 },
414};
415
416struct tegra_nand_platform nand_data = {
417 .max_chips = 8,
418 .chip_parms = nand_chip_parms,
419 .nr_chip_parms = ARRAY_SIZE(nand_chip_parms),
420};
421
422struct platform_device tegra_nand_device = {
423 .name = "tegra_nand",
424 .id = -1,
425 .resource = nand_resources,
426 .num_resources = ARRAY_SIZE(nand_resources),
427 .dev = {
428 .platform_data = &nand_data,
429 },
430};
431#endif
432
433static struct platform_device *aruba_devices[] __initdata = {
434#if ENABLE_OTG
435 &tegra_otg_device,
436#endif
437 &debug_uart,
438 &tegra_uartb_device,
439 &tegra_uartc_device,
440 &tegra_uartd_device,
441 &tegra_uarte_device,
442 &tegra_pmu_device,
443 &tegra_rtc_device,
444 &tegra_udc_device,
445#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
446 &tegra_smmu_device,
447#endif
448 &aruba_keys_device,
449 &tegra_wdt_device,
450#if defined(CONFIG_SND_HDA_TEGRA)
451 &tegra_hda_device,
452#endif
453 &tegra_avp_device,
454#if defined(CONFIG_MTD_NAND_TEGRA)
455 &tegra_nand_device,
456#endif
457};
458
459static void aruba_keys_init(void)
460{
461 int i;
462
463 for (i = 0; i < ARRAY_SIZE(aruba_keys); i++)
464 tegra_gpio_enable(aruba_keys[i].gpio);
465}
466
467static int __init aruba_touch_init(void)
468{
469 return 0;
470}
471
472
473static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
474 [0] = {
475 .phy_config = &utmi_phy_config[0],
476 .operating_mode = TEGRA_USB_HOST,
477 .power_down_on_bus_suspend = 0,
478 },
479 [1] = {
480 .phy_config = &ulpi_phy_config,
481 .operating_mode = TEGRA_USB_HOST,
482 .power_down_on_bus_suspend = 1,
483 },
484 [2] = {
485 .phy_config = &utmi_phy_config[1],
486 .operating_mode = TEGRA_USB_HOST,
487 .power_down_on_bus_suspend = 0,
488 },
489};
490
491
492static void aruba_usb_init(void)
493{
494 tegra_ehci2_device.dev.platform_data=&tegra_ehci_pdata[1];
495 platform_device_register(&tegra_ehci2_device);
496}
497
498#ifdef CONFIG_SATA_AHCI_TEGRA
499static void aruba_sata_init(void)
500{
501 platform_device_register(&tegra_sata_device);
502}
503#else
504static void aruba_sata_init(void) { }
505#endif
506
507static void __init tegra_aruba_init(void)
508{
509 tegra_clk_init_from_table(aruba_clk_init_table);
510 aruba_pinmux_init();
511
512 platform_add_devices(aruba_devices, ARRAY_SIZE(aruba_devices));
513
514 aruba_sdhci_init();
515 aruba_i2c_init();
516 aruba_regulator_init();
517 aruba_touch_init();
518 aruba_keys_init();
519 aruba_usb_init();
520 aruba_panel_init();
521 aruba_sensors_init();
522 aruba_bt_rfkill();
523 aruba_sata_init();
524 tegra_release_bootloader_fb();
525}
526
527static void __init tegra_aruba_reserve(void)
528{
529#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM)
530 tegra_reserve(0, SZ_4M, 0);
531#else
532 tegra_reserve(SZ_32M, SZ_4M, 0);
533#endif
534}
535
536MACHINE_START(ARUBA, "aruba")
537 .boot_params = 0x80000100,
538 .map_io = tegra_map_common_io,
539 .reserve = tegra_aruba_reserve,
540 .init_early = tegra_init_early,
541 .init_irq = tegra_init_irq,
542 .timer = &tegra_timer,
543 .init_machine = tegra_aruba_init,
544MACHINE_END
diff --git a/arch/arm/mach-tegra/board-aruba.h b/arch/arm/mach-tegra/board-aruba.h
new file mode 100644
index 00000000000..e00e0b071ff
--- /dev/null
+++ b/arch/arm/mach-tegra/board-aruba.h
@@ -0,0 +1,26 @@
1/*
2 * arch/arm/mach-tegra/board-aruba.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_ARUBA_H
18#define _MACH_TEGRA_BOARD_ARUBA_H
19
20int aruba_regulator_init(void);
21int aruba_sdhci_init(void);
22int aruba_pinmux_init(void);
23int aruba_panel_init(void);
24int aruba_sensors_init(void);
25
26#endif
diff --git a/arch/arm/mach-tegra/board-cardhu-kbc.c b/arch/arm/mach-tegra/board-cardhu-kbc.c
new file mode 100644
index 00000000000..3bf0a3b864f
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-kbc.c
@@ -0,0 +1,299 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-kbc.c
3 * Keys configuration for Nvidia tegra3 cardhu platform.
4 *
5 * Copyright (C) 2011 NVIDIA, Inc.
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
19 * 02111-1307, USA
20 */
21
22#include <linux/kernel.h>
23#include <linux/platform_device.h>
24#include <linux/input.h>
25#include <linux/device.h>
26#include <linux/gpio.h>
27#include <linux/gpio_keys.h>
28#include <linux/mfd/tps6591x.h>
29#include <linux/mfd/max77663-core.h>
30#include <linux/gpio_scrollwheel.h>
31
32#include <mach/irqs.h>
33#include <mach/io.h>
34#include <mach/iomap.h>
35#include <mach/kbc.h>
36#include "board.h"
37#include "board-cardhu.h"
38
39#include "gpio-names.h"
40#include "devices.h"
41
42#define CARDHU_PM269_ROW_COUNT 2
43#define CARDHU_PM269_COL_COUNT 4
44
45static const u32 kbd_keymap[] = {
46 KEY(0, 0, KEY_POWER),
47 KEY(0, 1, KEY_RESERVED),
48 KEY(0, 2, KEY_VOLUMEUP),
49 KEY(0, 3, KEY_VOLUMEDOWN),
50
51 KEY(1, 0, KEY_HOME),
52 KEY(1, 1, KEY_MENU),
53 KEY(1, 2, KEY_BACK),
54 KEY(1, 3, KEY_SEARCH),
55};
56static const struct matrix_keymap_data keymap_data = {
57 .keymap = kbd_keymap,
58 .keymap_size = ARRAY_SIZE(kbd_keymap),
59};
60
61static struct tegra_kbc_wake_key cardhu_wake_cfg[] = {
62 [0] = {
63 .row = 0,
64 .col = 0,
65 },
66};
67
68static struct tegra_kbc_platform_data cardhu_kbc_platform_data = {
69 .debounce_cnt = 20 * 32, /* 20ms debounce time */
70 .repeat_cnt = 1,
71 .scan_count = 30,
72 .wakeup = true,
73 .keymap_data = &keymap_data,
74 .wake_cnt = 1,
75 .wake_cfg = &cardhu_wake_cfg[0],
76#ifdef CONFIG_ANDROID
77 .disable_ev_rep = true,
78#endif
79};
80
81int __init cardhu_kbc_init(void)
82{
83 struct tegra_kbc_platform_data *data = &cardhu_kbc_platform_data;
84 int i;
85 struct board_info board_info;
86
87 tegra_get_board_info(&board_info);
88 if ((board_info.board_id == BOARD_E1198) ||
89 (board_info.board_id == BOARD_E1291))
90 return 0;
91
92 pr_info("Registering tegra-kbc\n");
93 tegra_kbc_device.dev.platform_data = &cardhu_kbc_platform_data;
94
95 for (i = 0; i < CARDHU_PM269_ROW_COUNT; i++) {
96 data->pin_cfg[i].num = i;
97 data->pin_cfg[i].is_row = true;
98 data->pin_cfg[i].en = true;
99 }
100 for (i = 0; i < CARDHU_PM269_COL_COUNT; i++) {
101 data->pin_cfg[i + KBC_PIN_GPIO_16].num = i;
102 data->pin_cfg[i + KBC_PIN_GPIO_16].en = true;
103 }
104
105 platform_device_register(&tegra_kbc_device);
106 return 0;
107}
108
109int __init cardhu_scroll_init(void)
110{
111 return 0;
112}
113
114#define GPIO_KEY(_id, _gpio, _iswake) \
115 { \
116 .code = _id, \
117 .gpio = TEGRA_GPIO_##_gpio, \
118 .active_low = 1, \
119 .desc = #_id, \
120 .type = EV_KEY, \
121 .wakeup = _iswake, \
122 .debounce_interval = 10, \
123 }
124
125#define GPIO_IKEY(_id, _irq, _iswake, _deb) \
126 { \
127 .code = _id, \
128 .gpio = -1, \
129 .irq = _irq, \
130 .desc = #_id, \
131 .type = EV_KEY, \
132 .wakeup = _iswake, \
133 .debounce_interval = _deb, \
134 }
135
136static struct gpio_keys_button cardhu_keys_e1198[] = {
137 [0] = GPIO_KEY(KEY_HOME, PQ0, 0),
138 [1] = GPIO_KEY(KEY_BACK, PQ1, 0),
139 [2] = GPIO_KEY(KEY_MENU, PQ2, 0),
140 [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
141 [4] = GPIO_KEY(KEY_VOLUMEUP, PR0, 0),
142 [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0),
143 [6] = GPIO_KEY(KEY_POWER, PV0, 1),
144 [7] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
145};
146
147static struct gpio_keys_platform_data cardhu_keys_e1198_pdata = {
148 .buttons = cardhu_keys_e1198,
149 .nbuttons = ARRAY_SIZE(cardhu_keys_e1198),
150};
151
152static struct platform_device cardhu_keys_e1198_device = {
153 .name = "gpio-keys",
154 .id = 0,
155 .dev = {
156 .platform_data = &cardhu_keys_e1198_pdata,
157 },
158};
159
160static struct gpio_keys_button cardhu_keys_e1291[] = {
161 [0] = GPIO_KEY(KEY_VOLUMEDOWN, PR0, 0),
162 [1] = GPIO_KEY(KEY_VOLUMEUP, PR1, 0),
163 [2] = GPIO_KEY(KEY_HOME, PR2, 0),
164 [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
165 [4] = GPIO_KEY(KEY_BACK, PQ0, 0),
166 [5] = GPIO_KEY(KEY_MENU, PQ1, 0),
167 [6] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
168};
169
170static struct gpio_keys_button cardhu_keys_e1291_a04[] = {
171 [0] = GPIO_KEY(KEY_VOLUMEDOWN, PR0, 0),
172 [1] = GPIO_KEY(KEY_VOLUMEUP, PR1, 0),
173 [2] = GPIO_KEY(KEY_HOME, PQ2, 0),
174 [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
175 [4] = GPIO_KEY(KEY_BACK, PQ0, 0),
176 [5] = GPIO_KEY(KEY_MENU, PQ1, 0),
177 [6] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
178};
179
180static struct gpio_keys_platform_data cardhu_keys_e1291_pdata = {
181 .buttons = cardhu_keys_e1291,
182 .nbuttons = ARRAY_SIZE(cardhu_keys_e1291),
183};
184
185static struct platform_device cardhu_keys_e1291_device = {
186 .name = "gpio-keys",
187 .id = 0,
188 .dev = {
189 .platform_data = &cardhu_keys_e1291_pdata,
190 },
191};
192
193static struct gpio_keys_button cardhu_int_keys[] = {
194 [0] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
195};
196
197static struct gpio_keys_button cardhu_pm298_int_keys[] = {
198 [0] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_FALLING, 1, 100),
199 [1] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_1SEC, 1, 3000),
200};
201
202static struct gpio_keys_button cardhu_pm299_int_keys[] = {
203 [0] = GPIO_IKEY(KEY_POWER, RICOH583_IRQ_BASE + RICOH583_IRQ_ONKEY, 1, 100),
204};
205
206static struct gpio_keys_platform_data cardhu_int_keys_pdata = {
207 .buttons = cardhu_int_keys,
208 .nbuttons = ARRAY_SIZE(cardhu_int_keys),
209};
210
211static struct platform_device cardhu_int_keys_device = {
212 .name = "gpio-keys",
213 .id = 0,
214 .dev = {
215 .platform_data = &cardhu_int_keys_pdata,
216 },
217};
218
219int __init cardhu_keys_init(void)
220{
221 int i;
222 struct board_info board_info;
223 struct board_info pmu_board_info;
224 int gpio_nr;
225
226 tegra_get_board_info(&board_info);
227 if (!((board_info.board_id == BOARD_E1198) ||
228 (board_info.board_id == BOARD_E1291) ||
229 (board_info.board_id == BOARD_E1186) ||
230 (board_info.board_id == BOARD_E1257) ||
231 (board_info.board_id == BOARD_PM305) ||
232 (board_info.board_id == BOARD_PM311) ||
233 (board_info.board_id == BOARD_PM269)))
234 return 0;
235
236 pr_info("Registering gpio keys\n");
237
238 if (board_info.board_id == BOARD_E1291) {
239 if (board_info.fab >= BOARD_FAB_A04) {
240 cardhu_keys_e1291_pdata.buttons =
241 cardhu_keys_e1291_a04;
242 cardhu_keys_e1291_pdata.nbuttons =
243 ARRAY_SIZE(cardhu_keys_e1291_a04);
244 }
245
246 /* Enable gpio mode for other pins */
247 for (i = 0; i < cardhu_keys_e1291_pdata.nbuttons; i++) {
248 gpio_nr = cardhu_keys_e1291_pdata.buttons[i].gpio;
249 if (gpio_nr < 0) {
250 if (get_tegra_image_type() == rck_image)
251 cardhu_keys_e1291_pdata.buttons[i].code
252 = KEY_ENTER;
253 } else {
254 tegra_gpio_enable(gpio_nr);
255 }
256 }
257
258 platform_device_register(&cardhu_keys_e1291_device);
259 } else if (board_info.board_id == BOARD_E1198) {
260 /* For E1198 */
261 for (i = 0; i < ARRAY_SIZE(cardhu_keys_e1198); i++) {
262 gpio_nr = cardhu_keys_e1198[i].gpio;
263 if (gpio_nr < 0) {
264 if (get_tegra_image_type() == rck_image)
265 cardhu_keys_e1198[i].code = KEY_ENTER;
266 } else {
267 tegra_gpio_enable(gpio_nr);
268 }
269 }
270
271 platform_device_register(&cardhu_keys_e1198_device);
272 }
273
274 /* Register on-key through pmu interrupt */
275 tegra_get_pmu_board_info(&pmu_board_info);
276
277 if (pmu_board_info.board_id == BOARD_PMU_PM298) {
278 cardhu_int_keys_pdata.buttons = cardhu_pm298_int_keys;
279 cardhu_int_keys_pdata.nbuttons =
280 ARRAY_SIZE(cardhu_pm298_int_keys);
281 }
282
283 if (pmu_board_info.board_id == BOARD_PMU_PM299) {
284 cardhu_int_keys_pdata.buttons = cardhu_pm299_int_keys;
285 cardhu_int_keys_pdata.nbuttons =
286 ARRAY_SIZE(cardhu_pm299_int_keys);
287 }
288
289 if ((board_info.board_id == BOARD_E1257) ||
290 (board_info.board_id == BOARD_E1186) ||
291 (board_info.board_id == BOARD_PM305) ||
292 (board_info.board_id == BOARD_PM311) ||
293 (board_info.board_id == BOARD_PM269)) {
294 if (get_tegra_image_type() == rck_image)
295 cardhu_int_keys[0].code = KEY_ENTER;
296 platform_device_register(&cardhu_int_keys_device);
297 }
298 return 0;
299}
diff --git a/arch/arm/mach-tegra/board-cardhu-memory.c b/arch/arm/mach-tegra/board-cardhu-memory.c
new file mode 100644
index 00000000000..21c98216ce7
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-memory.c
@@ -0,0 +1,5518 @@
1/*
2 * Copyright (C) 2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22#include "board.h"
23#include "board-cardhu.h"
24#include "tegra3_emc.h"
25#include "fuse.h"
26
27
28static const struct tegra_emc_table cardhu_emc_tables_h5tc2g[] = {
29 {
30 0x30, /* Rev 3.0 */
31 27000, /* SDRAM frquency */
32 {
33 0x00000001, /* EMC_RC */
34 0x00000004, /* EMC_RFC */
35 0x00000000, /* EMC_RAS */
36 0x00000000, /* EMC_RP */
37 0x00000002, /* EMC_R2W */
38 0x0000000a, /* EMC_W2R */
39 0x00000003, /* EMC_R2P */
40 0x0000000b, /* EMC_W2P */
41 0x00000000, /* EMC_RD_RCD */
42 0x00000000, /* EMC_WR_RCD */
43 0x00000003, /* EMC_RRD */
44 0x00000001, /* EMC_REXT */
45 0x00000000, /* EMC_WEXT */
46 0x00000005, /* EMC_WDV */
47 0x00000005, /* EMC_QUSE */
48 0x00000004, /* EMC_QRST */
49 0x00000007, /* EMC_QSAFE */
50 0x0000000d, /* EMC_RDV */
51 0x000000cb, /* EMC_REFRESH */
52 0x00000000, /* EMC_BURST_REFRESH_NUM */
53 0x00000032, /* EMC_PRE_REFRESH_REQ_CNT */
54 0x00000002, /* EMC_PDEX2WR */
55 0x00000002, /* EMC_PDEX2RD */
56 0x00000001, /* EMC_PCHG2PDEN */
57 0x00000000, /* EMC_ACT2PDEN */
58 0x00000007, /* EMC_AR2PDEN */
59 0x0000000f, /* EMC_RW2PDEN */
60 0x00000005, /* EMC_TXSR */
61 0x00000005, /* EMC_TXSRDLL */
62 0x00000004, /* EMC_TCKE */
63 0x00000001, /* EMC_TFAW */
64 0x00000000, /* EMC_TRPAB */
65 0x00000004, /* EMC_TCLKSTABLE */
66 0x00000005, /* EMC_TCLKSTOP */
67 0x000000d3, /* EMC_TREFBW */
68 0x00000000, /* EMC_QUSE_EXTRA */
69 0x00000004, /* EMC_FBIO_CFG6 */
70 0x00000000, /* EMC_ODT_WRITE */
71 0x00000000, /* EMC_ODT_READ */
72 0x00006288, /* EMC_FBIO_CFG5 */
73 0xd0780421, /* EMC_CFG_DIG_DLL */
74 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
75 0x00080000, /* EMC_DLL_XFORM_DQS0 */
76 0x00080000, /* EMC_DLL_XFORM_DQS1 */
77 0x00080000, /* EMC_DLL_XFORM_DQS2 */
78 0x00080000, /* EMC_DLL_XFORM_DQS3 */
79 0x00080000, /* EMC_DLL_XFORM_DQS4 */
80 0x00080000, /* EMC_DLL_XFORM_DQS5 */
81 0x00080000, /* EMC_DLL_XFORM_DQS6 */
82 0x00080000, /* EMC_DLL_XFORM_DQS7 */
83 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
84 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
85 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
86 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
87 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
88 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
89 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
90 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
91 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
92 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
93 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
94 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
95 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
96 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
97 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
98 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
99 0x00080000, /* EMC_DLL_XFORM_DQ0 */
100 0x00080000, /* EMC_DLL_XFORM_DQ1 */
101 0x00080000, /* EMC_DLL_XFORM_DQ2 */
102 0x00080000, /* EMC_DLL_XFORM_DQ3 */
103 0x000003e0, /* EMC_XM2CMDPADCTRL */
104 0x0800211d, /* EMC_XM2DQSPADCTRL2 */
105 0x00000000, /* EMC_XM2DQPADCTRL2 */
106 0x77ffc084, /* EMC_XM2CLKPADCTRL */
107 0x01f1f108, /* EMC_XM2COMPPADCTRL */
108 0x07075504, /* EMC_XM2VTTGENPADCTRL */
109 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
110 0x0800012d, /* EMC_XM2QUSEPADCTRL */
111 0x08000000, /* EMC_XM2DQSPADCTRL3 */
112 0x00000802, /* EMC_CTT_TERM_CTRL */
113 0x00000000, /* EMC_ZCAL_INTERVAL */
114 0x00000040, /* EMC_ZCAL_WAIT_CNT */
115 0x000c000c, /* EMC_MRS_WAIT_CNT */
116 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
117 0x00000000, /* EMC_CTT */
118 0x00000000, /* EMC_CTT_DURATION */
119 0x8000029e, /* EMC_DYN_SELF_REF_CONTROL */
120 0x00000001, /* MC_EMEM_ARB_CFG */
121 0x8000000d, /* MC_EMEM_ARB_OUTSTANDING_REQ */
122 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
123 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
124 0x00000005, /* MC_EMEM_ARB_TIMING_RC */
125 0x00000001, /* MC_EMEM_ARB_TIMING_RAS */
126 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
127 0x00000003, /* MC_EMEM_ARB_TIMING_RRD */
128 0x00000004, /* MC_EMEM_ARB_TIMING_RAP2PRE */
129 0x0000000f, /* MC_EMEM_ARB_TIMING_WAP2PRE */
130 0x00000006, /* MC_EMEM_ARB_TIMING_R2R */
131 0x00000005, /* MC_EMEM_ARB_TIMING_W2W */
132 0x00000007, /* MC_EMEM_ARB_TIMING_R2W */
133 0x0000000f, /* MC_EMEM_ARB_TIMING_W2R */
134 0x0f070506, /* MC_EMEM_ARB_DA_TURNS */
135 0x00140905, /* MC_EMEM_ARB_DA_COVERS */
136 0x78430306, /* MC_EMEM_ARB_MISC0 */
137 0x001f0001, /* MC_EMEM_ARB_RING1_THROTTLE */
138 },
139 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
140 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
141 0x00000000, /* EMC_CFG.PERIODIC_QRST */
142 0x00001221, /* Mode Register 0 */
143 0x00100003, /* Mode Register 1 */
144 0x00200008, /* Mode Register 2 */
145 },
146 {
147 0x30, /* Rev 3.0 */
148 54000, /* SDRAM frquency */
149 {
150 0x00000002, /* EMC_RC */
151 0x00000008, /* EMC_RFC */
152 0x00000001, /* EMC_RAS */
153 0x00000000, /* EMC_RP */
154 0x00000002, /* EMC_R2W */
155 0x0000000a, /* EMC_W2R */
156 0x00000003, /* EMC_R2P */
157 0x0000000b, /* EMC_W2P */
158 0x00000000, /* EMC_RD_RCD */
159 0x00000000, /* EMC_WR_RCD */
160 0x00000003, /* EMC_RRD */
161 0x00000001, /* EMC_REXT */
162 0x00000000, /* EMC_WEXT */
163 0x00000005, /* EMC_WDV */
164 0x00000005, /* EMC_QUSE */
165 0x00000004, /* EMC_QRST */
166 0x00000007, /* EMC_QSAFE */
167 0x0000000d, /* EMC_RDV */
168 0x00000198, /* EMC_REFRESH */
169 0x00000000, /* EMC_BURST_REFRESH_NUM */
170 0x00000066, /* EMC_PRE_REFRESH_REQ_CNT */
171 0x00000002, /* EMC_PDEX2WR */
172 0x00000002, /* EMC_PDEX2RD */
173 0x00000001, /* EMC_PCHG2PDEN */
174 0x00000000, /* EMC_ACT2PDEN */
175 0x00000007, /* EMC_AR2PDEN */
176 0x0000000f, /* EMC_RW2PDEN */
177 0x0000000a, /* EMC_TXSR */
178 0x0000000a, /* EMC_TXSRDLL */
179 0x00000004, /* EMC_TCKE */
180 0x00000002, /* EMC_TFAW */
181 0x00000000, /* EMC_TRPAB */
182 0x00000004, /* EMC_TCLKSTABLE */
183 0x00000005, /* EMC_TCLKSTOP */
184 0x000001a6, /* EMC_TREFBW */
185 0x00000000, /* EMC_QUSE_EXTRA */
186 0x00000004, /* EMC_FBIO_CFG6 */
187 0x00000000, /* EMC_ODT_WRITE */
188 0x00000000, /* EMC_ODT_READ */
189 0x00006288, /* EMC_FBIO_CFG5 */
190 0xd0780421, /* EMC_CFG_DIG_DLL */
191 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
192 0x00080000, /* EMC_DLL_XFORM_DQS0 */
193 0x00080000, /* EMC_DLL_XFORM_DQS1 */
194 0x00080000, /* EMC_DLL_XFORM_DQS2 */
195 0x00080000, /* EMC_DLL_XFORM_DQS3 */
196 0x00080000, /* EMC_DLL_XFORM_DQS4 */
197 0x00080000, /* EMC_DLL_XFORM_DQS5 */
198 0x00080000, /* EMC_DLL_XFORM_DQS6 */
199 0x00080000, /* EMC_DLL_XFORM_DQS7 */
200 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
201 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
202 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
203 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
204 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
205 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
206 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
207 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
208 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
209 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
210 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
211 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
212 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
213 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
214 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
215 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
216 0x00080000, /* EMC_DLL_XFORM_DQ0 */
217 0x00080000, /* EMC_DLL_XFORM_DQ1 */
218 0x00080000, /* EMC_DLL_XFORM_DQ2 */
219 0x00080000, /* EMC_DLL_XFORM_DQ3 */
220 0x000003e0, /* EMC_XM2CMDPADCTRL */
221 0x0800211d, /* EMC_XM2DQSPADCTRL2 */
222 0x00000000, /* EMC_XM2DQPADCTRL2 */
223 0x77ffc084, /* EMC_XM2CLKPADCTRL */
224 0x01f1f108, /* EMC_XM2COMPPADCTRL */
225 0x07075504, /* EMC_XM2VTTGENPADCTRL */
226 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
227 0x0800012d, /* EMC_XM2QUSEPADCTRL */
228 0x08000000, /* EMC_XM2DQSPADCTRL3 */
229 0x00000802, /* EMC_CTT_TERM_CTRL */
230 0x00000000, /* EMC_ZCAL_INTERVAL */
231 0x00000040, /* EMC_ZCAL_WAIT_CNT */
232 0x000c000c, /* EMC_MRS_WAIT_CNT */
233 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
234 0x00000000, /* EMC_CTT */
235 0x00000000, /* EMC_CTT_DURATION */
236 0x80000439, /* EMC_DYN_SELF_REF_CONTROL */
237 0x00000001, /* MC_EMEM_ARB_CFG */
238 0x80000014, /* MC_EMEM_ARB_OUTSTANDING_REQ */
239 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
240 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
241 0x00000005, /* MC_EMEM_ARB_TIMING_RC */
242 0x00000001, /* MC_EMEM_ARB_TIMING_RAS */
243 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
244 0x00000003, /* MC_EMEM_ARB_TIMING_RRD */
245 0x00000004, /* MC_EMEM_ARB_TIMING_RAP2PRE */
246 0x0000000f, /* MC_EMEM_ARB_TIMING_WAP2PRE */
247 0x00000006, /* MC_EMEM_ARB_TIMING_R2R */
248 0x00000005, /* MC_EMEM_ARB_TIMING_W2W */
249 0x00000007, /* MC_EMEM_ARB_TIMING_R2W */
250 0x0000000f, /* MC_EMEM_ARB_TIMING_W2R */
251 0x0f070506, /* MC_EMEM_ARB_DA_TURNS */
252 0x00140905, /* MC_EMEM_ARB_DA_COVERS */
253 0x78430506, /* MC_EMEM_ARB_MISC0 */
254 0x001f0001, /* MC_EMEM_ARB_RING1_THROTTLE */
255 },
256 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
257 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
258 0x00000000, /* EMC_CFG.PERIODIC_QRST */
259 0x00001221, /* Mode Register 0 */
260 0x00100003, /* Mode Register 1 */
261 0x00200008, /* Mode Register 2 */
262 },
263 {
264 0x30, /* Rev 3.0 */
265 108000, /* SDRAM frquency */
266 {
267 0x00000005, /* EMC_RC */
268 0x00000011, /* EMC_RFC */
269 0x00000003, /* EMC_RAS */
270 0x00000001, /* EMC_RP */
271 0x00000002, /* EMC_R2W */
272 0x0000000a, /* EMC_W2R */
273 0x00000003, /* EMC_R2P */
274 0x0000000b, /* EMC_W2P */
275 0x00000001, /* EMC_RD_RCD */
276 0x00000001, /* EMC_WR_RCD */
277 0x00000003, /* EMC_RRD */
278 0x00000001, /* EMC_REXT */
279 0x00000000, /* EMC_WEXT */
280 0x00000005, /* EMC_WDV */
281 0x00000005, /* EMC_QUSE */
282 0x00000004, /* EMC_QRST */
283 0x00000007, /* EMC_QSAFE */
284 0x0000000d, /* EMC_RDV */
285 0x00000330, /* EMC_REFRESH */
286 0x00000000, /* EMC_BURST_REFRESH_NUM */
287 0x000000cc, /* EMC_PRE_REFRESH_REQ_CNT */
288 0x00000002, /* EMC_PDEX2WR */
289 0x00000002, /* EMC_PDEX2RD */
290 0x00000001, /* EMC_PCHG2PDEN */
291 0x00000000, /* EMC_ACT2PDEN */
292 0x00000007, /* EMC_AR2PDEN */
293 0x0000000f, /* EMC_RW2PDEN */
294 0x00000013, /* EMC_TXSR */
295 0x00000013, /* EMC_TXSRDLL */
296 0x00000004, /* EMC_TCKE */
297 0x00000004, /* EMC_TFAW */
298 0x00000000, /* EMC_TRPAB */
299 0x00000004, /* EMC_TCLKSTABLE */
300 0x00000005, /* EMC_TCLKSTOP */
301 0x0000034b, /* EMC_TREFBW */
302 0x00000000, /* EMC_QUSE_EXTRA */
303 0x00000004, /* EMC_FBIO_CFG6 */
304 0x00000000, /* EMC_ODT_WRITE */
305 0x00000000, /* EMC_ODT_READ */
306 0x00006288, /* EMC_FBIO_CFG5 */
307 0xd0780421, /* EMC_CFG_DIG_DLL */
308 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
309 0x00080000, /* EMC_DLL_XFORM_DQS0 */
310 0x00080000, /* EMC_DLL_XFORM_DQS1 */
311 0x00080000, /* EMC_DLL_XFORM_DQS2 */
312 0x00080000, /* EMC_DLL_XFORM_DQS3 */
313 0x00080000, /* EMC_DLL_XFORM_DQS4 */
314 0x00080000, /* EMC_DLL_XFORM_DQS5 */
315 0x00080000, /* EMC_DLL_XFORM_DQS6 */
316 0x00080000, /* EMC_DLL_XFORM_DQS7 */
317 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
318 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
319 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
320 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
321 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
322 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
323 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
324 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
325 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
326 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
327 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
328 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
329 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
330 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
331 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
332 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
333 0x00080000, /* EMC_DLL_XFORM_DQ0 */
334 0x00080000, /* EMC_DLL_XFORM_DQ1 */
335 0x00080000, /* EMC_DLL_XFORM_DQ2 */
336 0x00080000, /* EMC_DLL_XFORM_DQ3 */
337 0x000003e0, /* EMC_XM2CMDPADCTRL */
338 0x0800211d, /* EMC_XM2DQSPADCTRL2 */
339 0x00000000, /* EMC_XM2DQPADCTRL2 */
340 0x77ffc084, /* EMC_XM2CLKPADCTRL */
341 0x01f1f108, /* EMC_XM2COMPPADCTRL */
342 0x07075504, /* EMC_XM2VTTGENPADCTRL */
343 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
344 0x0800012d, /* EMC_XM2QUSEPADCTRL */
345 0x08000000, /* EMC_XM2DQSPADCTRL3 */
346 0x00000802, /* EMC_CTT_TERM_CTRL */
347 0x00000000, /* EMC_ZCAL_INTERVAL */
348 0x00000040, /* EMC_ZCAL_WAIT_CNT */
349 0x000c000c, /* EMC_MRS_WAIT_CNT */
350 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
351 0x00000000, /* EMC_CTT */
352 0x00000000, /* EMC_CTT_DURATION */
353 0x8000076e, /* EMC_DYN_SELF_REF_CONTROL */
354 0x00000003, /* MC_EMEM_ARB_CFG */
355 0x80000027, /* MC_EMEM_ARB_OUTSTANDING_REQ */
356 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
357 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
358 0x00000006, /* MC_EMEM_ARB_TIMING_RC */
359 0x00000002, /* MC_EMEM_ARB_TIMING_RAS */
360 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
361 0x00000003, /* MC_EMEM_ARB_TIMING_RRD */
362 0x00000004, /* MC_EMEM_ARB_TIMING_RAP2PRE */
363 0x0000000f, /* MC_EMEM_ARB_TIMING_WAP2PRE */
364 0x00000006, /* MC_EMEM_ARB_TIMING_R2R */
365 0x00000005, /* MC_EMEM_ARB_TIMING_W2W */
366 0x00000007, /* MC_EMEM_ARB_TIMING_R2W */
367 0x0000000f, /* MC_EMEM_ARB_TIMING_W2R */
368 0x0f070506, /* MC_EMEM_ARB_DA_TURNS */
369 0x00140906, /* MC_EMEM_ARB_DA_COVERS */
370 0x78440a07, /* MC_EMEM_ARB_MISC0 */
371 0x001f0001, /* MC_EMEM_ARB_RING1_THROTTLE */
372 },
373 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
374 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
375 0x00000000, /* EMC_CFG.PERIODIC_QRST */
376 0x00001221, /* Mode Register 0 */
377 0x00100003, /* Mode Register 1 */
378 0x00200008, /* Mode Register 2 */
379 },
380 {
381 0x30, /* Rev 3.0 */
382 416000, /* SDRAM frequency */
383 {
384 0x00000013, /* EMC_RC */
385 0x00000041, /* EMC_RFC */
386 0x0000000d, /* EMC_RAS */
387 0x00000004, /* EMC_RP */
388 0x00000002, /* EMC_R2W */
389 0x00000009, /* EMC_W2R */
390 0x00000002, /* EMC_R2P */
391 0x0000000c, /* EMC_W2P */
392 0x00000004, /* EMC_RD_RCD */
393 0x00000004, /* EMC_WR_RCD */
394 0x00000002, /* EMC_RRD */
395 0x00000001, /* EMC_REXT */
396 0x00000000, /* EMC_WEXT */
397 0x00000005, /* EMC_WDV */
398 0x00000008, /* EMC_QUSE */
399 0x00000006, /* EMC_QRST */
400 0x00000008, /* EMC_QSAFE */
401 0x00000010, /* EMC_RDV */
402 0x00000c6c, /* EMC_REFRESH */
403 0x00000000, /* EMC_BURST_REFRESH_NUM */
404 0x0000031b, /* EMC_PRE_REFRESH_REQ_CNT */
405 0x00000001, /* EMC_PDEX2WR */
406 0x00000001, /* EMC_PDEX2RD */
407 0x00000001, /* EMC_PCHG2PDEN */
408 0x00000000, /* EMC_ACT2PDEN */
409 0x00000008, /* EMC_AR2PDEN */
410 0x00000011, /* EMC_RW2PDEN */
411 0x00000047, /* EMC_TXSR */
412 0x00000200, /* EMC_TXSRDLL */
413 0x00000004, /* EMC_TCKE */
414 0x0000000d, /* EMC_TFAW */
415 0x00000000, /* EMC_TRPAB */
416 0x00000004, /* EMC_TCLKSTABLE */
417 0x00000005, /* EMC_TCLKSTOP */
418 0x00000cad, /* EMC_TREFBW */
419 0x00000000, /* EMC_QUSE_EXTRA */
420 0x00000006, /* EMC_FBIO_CFG6 */
421 0x00000000, /* EMC_ODT_WRITE */
422 0x00000000, /* EMC_ODT_READ */
423 0x00007088, /* EMC_FBIO_CFG5 */
424 0xf0120441, /* EMC_CFG_DIG_DLL */
425 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
426 0x00010000, /* EMC_DLL_XFORM_DQS0 */
427 0x00010000, /* EMC_DLL_XFORM_DQS1 */
428 0x00010000, /* EMC_DLL_XFORM_DQS2 */
429 0x00010000, /* EMC_DLL_XFORM_DQS3 */
430 0x00010000, /* EMC_DLL_XFORM_DQS4 */
431 0x00010000, /* EMC_DLL_XFORM_DQS5 */
432 0x00010000, /* EMC_DLL_XFORM_DQS6 */
433 0x00010000, /* EMC_DLL_XFORM_DQS7 */
434 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
435 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
436 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
437 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
438 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
439 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
440 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
441 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
442 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
443 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
444 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
445 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
446 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
447 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
448 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
449 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
450 0x00020000, /* EMC_DLL_XFORM_DQ0 */
451 0x00020000, /* EMC_DLL_XFORM_DQ1 */
452 0x00020000, /* EMC_DLL_XFORM_DQ2 */
453 0x00020000, /* EMC_DLL_XFORM_DQ3 */
454 0x000006a0, /* EMC_XM2CMDPADCTRL */
455 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
456 0x00000000, /* EMC_XM2DQPADCTRL2 */
457 0x77ffc084, /* EMC_XM2CLKPADCTRL */
458 0x01f1f50f, /* EMC_XM2COMPPADCTRL */
459 0x07077404, /* EMC_XM2VTTGENPADCTRL */
460 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
461 0x0800011d, /* EMC_XM2QUSEPADCTRL */
462 0x08000021, /* EMC_XM2DQSPADCTRL3 */
463 0x00000802, /* EMC_CTT_TERM_CTRL */
464 0x00000000, /* EMC_ZCAL_INTERVAL */
465 0x00000040, /* EMC_ZCAL_WAIT_CNT */
466 0x01be000c, /* EMC_MRS_WAIT_CNT */
467 0xa0f10404, /* EMC_AUTO_CAL_CONFIG */
468 0x00000000, /* EMC_CTT */
469 0x00000000, /* EMC_CTT_DURATION */
470 0x000020ae, /* EMC_DYN_SELF_REF_CONTROL */
471 0x00000006, /* MC_EMEM_ARB_CFG */
472 0x8000004b, /* MC_EMEM_ARB_OUTSTANDING_REQ */
473 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
474 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
475 0x0000000a, /* MC_EMEM_ARB_TIMING_RC */
476 0x00000006, /* MC_EMEM_ARB_TIMING_RAS */
477 0x00000006, /* MC_EMEM_ARB_TIMING_FAW */
478 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
479 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
480 0x00000009, /* MC_EMEM_ARB_TIMING_WAP2PRE */
481 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
482 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
483 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
484 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
485 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
486 0x000e070a, /* MC_EMEM_ARB_DA_COVERS */
487 0x7027130b, /* MC_EMEM_ARB_MISC0 */
488 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
489 },
490 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
491 0x00000010, /* EMC_AUTO_CAL_INTERVAL */
492 0x00000000, /* EMC_CFG.PERIODIC_QRST */
493 0x00001941, /* Mode Register 0 */
494 0x00100002, /* Mode Register 1 */
495 0x00200008, /* Mode Register 2 */
496 },
497 {
498 0x30, /* Rev 3.0 */
499 533000, /* SDRAM frquency */
500 {
501 0x00000018, /* EMC_RC */
502 0x00000054, /* EMC_RFC */
503 0x00000011, /* EMC_RAS */
504 0x00000006, /* EMC_RP */
505 0x00000003, /* EMC_R2W */
506 0x00000009, /* EMC_W2R */
507 0x00000002, /* EMC_R2P */
508 0x0000000d, /* EMC_W2P */
509 0x00000006, /* EMC_RD_RCD */
510 0x00000006, /* EMC_WR_RCD */
511 0x00000002, /* EMC_RRD */
512 0x00000001, /* EMC_REXT */
513 0x00000000, /* EMC_WEXT */
514 0x00000005, /* EMC_WDV */
515 0x00000008, /* EMC_QUSE */
516 0x00000006, /* EMC_QRST */
517 0x00000008, /* EMC_QSAFE */
518 0x00000010, /* EMC_RDV */
519 0x00000ffd, /* EMC_REFRESH */
520 0x00000000, /* EMC_BURST_REFRESH_NUM */
521 0x000003ff, /* EMC_PRE_REFRESH_REQ_CNT */
522 0x00000002, /* EMC_PDEX2WR */
523 0x00000002, /* EMC_PDEX2RD */
524 0x00000001, /* EMC_PCHG2PDEN */
525 0x00000000, /* EMC_ACT2PDEN */
526 0x0000000a, /* EMC_AR2PDEN */
527 0x00000012, /* EMC_RW2PDEN */
528 0x0000005b, /* EMC_TXSR */
529 0x00000200, /* EMC_TXSRDLL */
530 0x00000004, /* EMC_TCKE */
531 0x00000010, /* EMC_TFAW */
532 0x00000000, /* EMC_TRPAB */
533 0x00000005, /* EMC_TCLKSTABLE */
534 0x00000006, /* EMC_TCLKSTOP */
535 0x0000103e, /* EMC_TREFBW */
536 0x00000000, /* EMC_QUSE_EXTRA */
537 0x00000006, /* EMC_FBIO_CFG6 */
538 0x00000000, /* EMC_ODT_WRITE */
539 0x00000000, /* EMC_ODT_READ */
540 0x00007088, /* EMC_FBIO_CFG5 */
541 0xf0120441, /* EMC_CFG_DIG_DLL */
542 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
543 0x00010000, /* EMC_DLL_XFORM_DQS0 */
544 0x00010000, /* EMC_DLL_XFORM_DQS1 */
545 0x00010000, /* EMC_DLL_XFORM_DQS2 */
546 0x00010000, /* EMC_DLL_XFORM_DQS3 */
547 0x00010000, /* EMC_DLL_XFORM_DQS4 */
548 0x00010000, /* EMC_DLL_XFORM_DQS5 */
549 0x00010000, /* EMC_DLL_XFORM_DQS6 */
550 0x00010000, /* EMC_DLL_XFORM_DQS7 */
551 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
552 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
553 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
554 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
555 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
556 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
557 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
558 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
559 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
560 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
561 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
562 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
563 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
564 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
565 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
566 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
567 0x00020000, /* EMC_DLL_XFORM_DQ0 */
568 0x00020000, /* EMC_DLL_XFORM_DQ1 */
569 0x00020000, /* EMC_DLL_XFORM_DQ2 */
570 0x00020000, /* EMC_DLL_XFORM_DQ3 */
571 0x000006a0, /* EMC_XM2CMDPADCTRL */
572 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
573 0x00000000, /* EMC_XM2DQPADCTRL2 */
574 0x77ffc084, /* EMC_XM2CLKPADCTRL */
575 0x01f1f50f, /* EMC_XM2COMPPADCTRL */
576 0x07077404, /* EMC_XM2VTTGENPADCTRL */
577 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
578 0x0800011d, /* EMC_XM2QUSEPADCTRL */
579 0x08000021, /* EMC_XM2DQSPADCTRL3 */
580 0x00000802, /* EMC_CTT_TERM_CTRL */
581 0x00000000, /* EMC_ZCAL_INTERVAL */
582 0x00000040, /* EMC_ZCAL_WAIT_CNT */
583 0x01ab000c, /* EMC_MRS_WAIT_CNT */
584 0xa0f10404, /* EMC_AUTO_CAL_CONFIG */
585 0x00000000, /* EMC_CTT */
586 0x00000000, /* EMC_CTT_DURATION */
587 0x000020ae, /* EMC_DYN_SELF_REF_CONTROL */
588 0x00000008, /* MC_EMEM_ARB_CFG */
589 0x80000060, /* MC_EMEM_ARB_OUTSTANDING_REQ */
590 0x00000002, /* MC_EMEM_ARB_TIMING_RCD */
591 0x00000003, /* MC_EMEM_ARB_TIMING_RP */
592 0x0000000d, /* MC_EMEM_ARB_TIMING_RC */
593 0x00000008, /* MC_EMEM_ARB_TIMING_RAS */
594 0x00000007, /* MC_EMEM_ARB_TIMING_FAW */
595 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
596 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
597 0x00000009, /* MC_EMEM_ARB_TIMING_WAP2PRE */
598 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
599 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
600 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
601 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
602 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
603 0x0010090d, /* MC_EMEM_ARB_DA_COVERS */
604 0x7028180e, /* MC_EMEM_ARB_MISC0 */
605 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
606 },
607 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
608 0x00000010, /* EMC_AUTO_CAL_INTERVAL */
609 0x00000000, /* EMC_CFG.PERIODIC_QRST */
610 0x00001941, /* Mode Register 0 */
611 0x00100002, /* Mode Register 1 */
612 0x00200008, /* Mode Register 2 */
613 },
614};
615
616static const struct tegra_emc_table cardhu_emc_tables_h5tc2g_a2[] = {
617 {
618 0x32, /* Rev 3.2 */
619 25500, /* SDRAM frequency */
620 {
621 0x00000001, /* EMC_RC */
622 0x00000003, /* EMC_RFC */
623 0x00000000, /* EMC_RAS */
624 0x00000000, /* EMC_RP */
625 0x00000002, /* EMC_R2W */
626 0x0000000a, /* EMC_W2R */
627 0x00000003, /* EMC_R2P */
628 0x0000000b, /* EMC_W2P */
629 0x00000000, /* EMC_RD_RCD */
630 0x00000000, /* EMC_WR_RCD */
631 0x00000003, /* EMC_RRD */
632 0x00000001, /* EMC_REXT */
633 0x00000000, /* EMC_WEXT */
634 0x00000005, /* EMC_WDV */
635 0x00000005, /* EMC_QUSE */
636 0x00000004, /* EMC_QRST */
637 0x00000007, /* EMC_QSAFE */
638 0x0000000c, /* EMC_RDV */
639 0x000000bd, /* EMC_REFRESH */
640 0x00000000, /* EMC_BURST_REFRESH_NUM */
641 0x0000002f, /* EMC_PRE_REFRESH_REQ_CNT */
642 0x00000002, /* EMC_PDEX2WR */
643 0x00000002, /* EMC_PDEX2RD */
644 0x00000001, /* EMC_PCHG2PDEN */
645 0x00000000, /* EMC_ACT2PDEN */
646 0x00000007, /* EMC_AR2PDEN */
647 0x0000000f, /* EMC_RW2PDEN */
648 0x00000005, /* EMC_TXSR */
649 0x00000005, /* EMC_TXSRDLL */
650 0x00000004, /* EMC_TCKE */
651 0x00000001, /* EMC_TFAW */
652 0x00000000, /* EMC_TRPAB */
653 0x00000004, /* EMC_TCLKSTABLE */
654 0x00000005, /* EMC_TCLKSTOP */
655 0x000000c3, /* EMC_TREFBW */
656 0x00000000, /* EMC_QUSE_EXTRA */
657 0x00000004, /* EMC_FBIO_CFG6 */
658 0x00000000, /* EMC_ODT_WRITE */
659 0x00000000, /* EMC_ODT_READ */
660 0x00006288, /* EMC_FBIO_CFG5 */
661 0x007800a4, /* EMC_CFG_DIG_DLL */
662 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
663 0x00080000, /* EMC_DLL_XFORM_DQS0 */
664 0x00080000, /* EMC_DLL_XFORM_DQS1 */
665 0x00080000, /* EMC_DLL_XFORM_DQS2 */
666 0x00080000, /* EMC_DLL_XFORM_DQS3 */
667 0x00080000, /* EMC_DLL_XFORM_DQS4 */
668 0x00080000, /* EMC_DLL_XFORM_DQS5 */
669 0x00080000, /* EMC_DLL_XFORM_DQS6 */
670 0x00080000, /* EMC_DLL_XFORM_DQS7 */
671 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
672 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
673 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
674 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
675 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
676 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
677 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
678 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
679 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
680 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
681 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
682 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
683 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
684 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
685 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
686 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
687 0x00080000, /* EMC_DLL_XFORM_DQ0 */
688 0x00080000, /* EMC_DLL_XFORM_DQ1 */
689 0x00080000, /* EMC_DLL_XFORM_DQ2 */
690 0x00080000, /* EMC_DLL_XFORM_DQ3 */
691 0x000002a0, /* EMC_XM2CMDPADCTRL */
692 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
693 0x00000000, /* EMC_XM2DQPADCTRL2 */
694 0x77ffc084, /* EMC_XM2CLKPADCTRL */
695 0x01f1f108, /* EMC_XM2COMPPADCTRL */
696 0x05057404, /* EMC_XM2VTTGENPADCTRL */
697 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
698 0x08000168, /* EMC_XM2QUSEPADCTRL */
699 0x08000000, /* EMC_XM2DQSPADCTRL3 */
700 0x00000802, /* EMC_CTT_TERM_CTRL */
701 0x00000000, /* EMC_ZCAL_INTERVAL */
702 0x00000040, /* EMC_ZCAL_WAIT_CNT */
703 0x000c000c, /* EMC_MRS_WAIT_CNT */
704 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
705 0x00000000, /* EMC_CTT */
706 0x00000000, /* EMC_CTT_DURATION */
707 0x80000280, /* EMC_DYN_SELF_REF_CONTROL */
708 0x00020001, /* MC_EMEM_ARB_CFG */
709 0xc0000010, /* MC_EMEM_ARB_OUTSTANDING_REQ */
710 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
711 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
712 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
713 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
714 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
715 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
716 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
717 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
718 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
719 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
720 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
721 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
722 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
723 0x000a0402, /* MC_EMEM_ARB_DA_COVERS */
724 0x74430303, /* MC_EMEM_ARB_MISC0 */
725 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
726 0xd8000000, /* EMC_FBIO_SPARE */
727 0xff00ff00, /* EMC_CFG_RSV */
728 },
729 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
730 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
731 0x00000000, /* EMC_CFG.PERIODIC_QRST */
732 0x80001221, /* Mode Register 0 */
733 0x80100003, /* Mode Register 1 */
734 0x80200008, /* Mode Register 2 */
735 0x00000001, /* EMC_CFG.DYN_SELF_REF */
736 },
737 {
738 0x32, /* Rev 3.2 */
739 51000, /* SDRAM frequency */
740 {
741 0x00000002, /* EMC_RC */
742 0x00000008, /* EMC_RFC */
743 0x00000001, /* EMC_RAS */
744 0x00000000, /* EMC_RP */
745 0x00000002, /* EMC_R2W */
746 0x0000000a, /* EMC_W2R */
747 0x00000003, /* EMC_R2P */
748 0x0000000b, /* EMC_W2P */
749 0x00000000, /* EMC_RD_RCD */
750 0x00000000, /* EMC_WR_RCD */
751 0x00000003, /* EMC_RRD */
752 0x00000001, /* EMC_REXT */
753 0x00000000, /* EMC_WEXT */
754 0x00000005, /* EMC_WDV */
755 0x00000005, /* EMC_QUSE */
756 0x00000004, /* EMC_QRST */
757 0x00000007, /* EMC_QSAFE */
758 0x0000000c, /* EMC_RDV */
759 0x00000181, /* EMC_REFRESH */
760 0x00000000, /* EMC_BURST_REFRESH_NUM */
761 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
762 0x00000002, /* EMC_PDEX2WR */
763 0x00000002, /* EMC_PDEX2RD */
764 0x00000001, /* EMC_PCHG2PDEN */
765 0x00000000, /* EMC_ACT2PDEN */
766 0x00000007, /* EMC_AR2PDEN */
767 0x0000000f, /* EMC_RW2PDEN */
768 0x00000009, /* EMC_TXSR */
769 0x00000009, /* EMC_TXSRDLL */
770 0x00000004, /* EMC_TCKE */
771 0x00000002, /* EMC_TFAW */
772 0x00000000, /* EMC_TRPAB */
773 0x00000004, /* EMC_TCLKSTABLE */
774 0x00000005, /* EMC_TCLKSTOP */
775 0x0000018e, /* EMC_TREFBW */
776 0x00000000, /* EMC_QUSE_EXTRA */
777 0x00000004, /* EMC_FBIO_CFG6 */
778 0x00000000, /* EMC_ODT_WRITE */
779 0x00000000, /* EMC_ODT_READ */
780 0x00006288, /* EMC_FBIO_CFG5 */
781 0x007800a4, /* EMC_CFG_DIG_DLL */
782 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
783 0x00080000, /* EMC_DLL_XFORM_DQS0 */
784 0x00080000, /* EMC_DLL_XFORM_DQS1 */
785 0x00080000, /* EMC_DLL_XFORM_DQS2 */
786 0x00080000, /* EMC_DLL_XFORM_DQS3 */
787 0x00080000, /* EMC_DLL_XFORM_DQS4 */
788 0x00080000, /* EMC_DLL_XFORM_DQS5 */
789 0x00080000, /* EMC_DLL_XFORM_DQS6 */
790 0x00080000, /* EMC_DLL_XFORM_DQS7 */
791 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
792 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
793 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
794 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
795 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
796 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
797 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
798 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
799 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
800 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
801 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
802 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
803 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
804 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
805 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
806 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
807 0x00080000, /* EMC_DLL_XFORM_DQ0 */
808 0x00080000, /* EMC_DLL_XFORM_DQ1 */
809 0x00080000, /* EMC_DLL_XFORM_DQ2 */
810 0x00080000, /* EMC_DLL_XFORM_DQ3 */
811 0x000002a0, /* EMC_XM2CMDPADCTRL */
812 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
813 0x00000000, /* EMC_XM2DQPADCTRL2 */
814 0x77ffc084, /* EMC_XM2CLKPADCTRL */
815 0x01f1f108, /* EMC_XM2COMPPADCTRL */
816 0x05057404, /* EMC_XM2VTTGENPADCTRL */
817 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
818 0x08000168, /* EMC_XM2QUSEPADCTRL */
819 0x08000000, /* EMC_XM2DQSPADCTRL3 */
820 0x00000802, /* EMC_CTT_TERM_CTRL */
821 0x00000000, /* EMC_ZCAL_INTERVAL */
822 0x00000040, /* EMC_ZCAL_WAIT_CNT */
823 0x000c000c, /* EMC_MRS_WAIT_CNT */
824 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
825 0x00000000, /* EMC_CTT */
826 0x00000000, /* EMC_CTT_DURATION */
827 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
828 0x00000001, /* MC_EMEM_ARB_CFG */
829 0xc0000010, /* MC_EMEM_ARB_OUTSTANDING_REQ */
830 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
831 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
832 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
833 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
834 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
835 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
836 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
837 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
838 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
839 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
840 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
841 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
842 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
843 0x000a0402, /* MC_EMEM_ARB_DA_COVERS */
844 0x73430303, /* MC_EMEM_ARB_MISC0 */
845 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
846 0xd8000000, /* EMC_FBIO_SPARE */
847 0xff00ff00, /* EMC_CFG_RSV */
848 },
849 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
850 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
851 0x00000000, /* EMC_CFG.PERIODIC_QRST */
852 0x80001221, /* Mode Register 0 */
853 0x80100003, /* Mode Register 1 */
854 0x80200008, /* Mode Register 2 */
855 0x00000001, /* EMC_CFG.DYN_SELF_REF */
856 },
857 {
858 0x32, /* Rev 3.2 */
859 102000, /* SDRAM frequency */
860 {
861 0x00000004, /* EMC_RC */
862 0x00000010, /* EMC_RFC */
863 0x00000003, /* EMC_RAS */
864 0x00000001, /* EMC_RP */
865 0x00000002, /* EMC_R2W */
866 0x0000000a, /* EMC_W2R */
867 0x00000003, /* EMC_R2P */
868 0x0000000b, /* EMC_W2P */
869 0x00000001, /* EMC_RD_RCD */
870 0x00000001, /* EMC_WR_RCD */
871 0x00000003, /* EMC_RRD */
872 0x00000001, /* EMC_REXT */
873 0x00000000, /* EMC_WEXT */
874 0x00000005, /* EMC_WDV */
875 0x00000005, /* EMC_QUSE */
876 0x00000004, /* EMC_QRST */
877 0x00000007, /* EMC_QSAFE */
878 0x0000000c, /* EMC_RDV */
879 0x00000303, /* EMC_REFRESH */
880 0x00000000, /* EMC_BURST_REFRESH_NUM */
881 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
882 0x00000002, /* EMC_PDEX2WR */
883 0x00000002, /* EMC_PDEX2RD */
884 0x00000001, /* EMC_PCHG2PDEN */
885 0x00000000, /* EMC_ACT2PDEN */
886 0x00000007, /* EMC_AR2PDEN */
887 0x0000000f, /* EMC_RW2PDEN */
888 0x00000012, /* EMC_TXSR */
889 0x00000012, /* EMC_TXSRDLL */
890 0x00000004, /* EMC_TCKE */
891 0x00000004, /* EMC_TFAW */
892 0x00000000, /* EMC_TRPAB */
893 0x00000004, /* EMC_TCLKSTABLE */
894 0x00000005, /* EMC_TCLKSTOP */
895 0x0000031c, /* EMC_TREFBW */
896 0x00000000, /* EMC_QUSE_EXTRA */
897 0x00000004, /* EMC_FBIO_CFG6 */
898 0x00000000, /* EMC_ODT_WRITE */
899 0x00000000, /* EMC_ODT_READ */
900 0x00006288, /* EMC_FBIO_CFG5 */
901 0x007800a4, /* EMC_CFG_DIG_DLL */
902 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
903 0x00080000, /* EMC_DLL_XFORM_DQS0 */
904 0x00080000, /* EMC_DLL_XFORM_DQS1 */
905 0x00080000, /* EMC_DLL_XFORM_DQS2 */
906 0x00080000, /* EMC_DLL_XFORM_DQS3 */
907 0x00080000, /* EMC_DLL_XFORM_DQS4 */
908 0x00080000, /* EMC_DLL_XFORM_DQS5 */
909 0x00080000, /* EMC_DLL_XFORM_DQS6 */
910 0x00080000, /* EMC_DLL_XFORM_DQS7 */
911 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
912 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
913 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
914 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
915 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
916 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
917 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
918 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
919 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
920 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
921 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
922 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
923 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
924 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
925 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
926 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
927 0x00080000, /* EMC_DLL_XFORM_DQ0 */
928 0x00080000, /* EMC_DLL_XFORM_DQ1 */
929 0x00080000, /* EMC_DLL_XFORM_DQ2 */
930 0x00080000, /* EMC_DLL_XFORM_DQ3 */
931 0x000002a0, /* EMC_XM2CMDPADCTRL */
932 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
933 0x00000000, /* EMC_XM2DQPADCTRL2 */
934 0x77ffc084, /* EMC_XM2CLKPADCTRL */
935 0x01f1f108, /* EMC_XM2COMPPADCTRL */
936 0x05057404, /* EMC_XM2VTTGENPADCTRL */
937 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
938 0x08000168, /* EMC_XM2QUSEPADCTRL */
939 0x08000000, /* EMC_XM2DQSPADCTRL3 */
940 0x00000802, /* EMC_CTT_TERM_CTRL */
941 0x00000000, /* EMC_ZCAL_INTERVAL */
942 0x00000040, /* EMC_ZCAL_WAIT_CNT */
943 0x000c000c, /* EMC_MRS_WAIT_CNT */
944 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
945 0x00000000, /* EMC_CTT */
946 0x00000000, /* EMC_CTT_DURATION */
947 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
948 0x00000001, /* MC_EMEM_ARB_CFG */
949 0xc0000018, /* MC_EMEM_ARB_OUTSTANDING_REQ */
950 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
951 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
952 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
953 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
954 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
955 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
956 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
957 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
958 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
959 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
960 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
961 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
962 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
963 0x000a0403, /* MC_EMEM_ARB_DA_COVERS */
964 0x72830504, /* MC_EMEM_ARB_MISC0 */
965 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
966 0xd8000000, /* EMC_FBIO_SPARE */
967 0xff00ff00, /* EMC_CFG_RSV */
968 },
969 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
970 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
971 0x00000000, /* EMC_CFG.PERIODIC_QRST */
972 0x80001221, /* Mode Register 0 */
973 0x80100003, /* Mode Register 1 */
974 0x80200008, /* Mode Register 2 */
975 0x00000001, /* EMC_CFG.DYN_SELF_REF */
976 },
977 {
978 0x32, /* Rev 3.2 */
979 375000, /* SDRAM frequency */
980 {
981 0x00000011, /* EMC_RC */
982 0x0000003a, /* EMC_RFC */
983 0x0000000c, /* EMC_RAS */
984 0x00000004, /* EMC_RP */
985 0x00000003, /* EMC_R2W */
986 0x00000008, /* EMC_W2R */
987 0x00000002, /* EMC_R2P */
988 0x0000000a, /* EMC_W2P */
989 0x00000004, /* EMC_RD_RCD */
990 0x00000004, /* EMC_WR_RCD */
991 0x00000002, /* EMC_RRD */
992 0x00000001, /* EMC_REXT */
993 0x00000000, /* EMC_WEXT */
994 0x00000004, /* EMC_WDV */
995 0x00000006, /* EMC_QUSE */
996 0x00000004, /* EMC_QRST */
997 0x00000008, /* EMC_QSAFE */
998 0x0000000d, /* EMC_RDV */
999 0x00000b2d, /* EMC_REFRESH */
1000 0x00000000, /* EMC_BURST_REFRESH_NUM */
1001 0x000002cb, /* EMC_PRE_REFRESH_REQ_CNT */
1002 0x00000008, /* EMC_PDEX2WR */
1003 0x00000008, /* EMC_PDEX2RD */
1004 0x00000001, /* EMC_PCHG2PDEN */
1005 0x00000000, /* EMC_ACT2PDEN */
1006 0x00000007, /* EMC_AR2PDEN */
1007 0x0000000f, /* EMC_RW2PDEN */
1008 0x00000040, /* EMC_TXSR */
1009 0x00000200, /* EMC_TXSRDLL */
1010 0x00000009, /* EMC_TCKE */
1011 0x0000000c, /* EMC_TFAW */
1012 0x00000000, /* EMC_TRPAB */
1013 0x00000004, /* EMC_TCLKSTABLE */
1014 0x00000005, /* EMC_TCLKSTOP */
1015 0x00000b6d, /* EMC_TREFBW */
1016 0x00000000, /* EMC_QUSE_EXTRA */
1017 0x00000006, /* EMC_FBIO_CFG6 */
1018 0x00000000, /* EMC_ODT_WRITE */
1019 0x00000000, /* EMC_ODT_READ */
1020 0x00007088, /* EMC_FBIO_CFG5 */
1021 0x00200084, /* EMC_CFG_DIG_DLL */
1022 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1023 0x0003c000, /* EMC_DLL_XFORM_DQS0 */
1024 0x0003c000, /* EMC_DLL_XFORM_DQS1 */
1025 0x0003c000, /* EMC_DLL_XFORM_DQS2 */
1026 0x0003c000, /* EMC_DLL_XFORM_DQS3 */
1027 0x0003c000, /* EMC_DLL_XFORM_DQS4 */
1028 0x0003c000, /* EMC_DLL_XFORM_DQS5 */
1029 0x0003c000, /* EMC_DLL_XFORM_DQS6 */
1030 0x0003c000, /* EMC_DLL_XFORM_DQS7 */
1031 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1032 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1033 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1034 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1035 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1036 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1037 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1038 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1039 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1040 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1041 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1042 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1043 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1044 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1045 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1046 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1047 0x00040000, /* EMC_DLL_XFORM_DQ0 */
1048 0x00040000, /* EMC_DLL_XFORM_DQ1 */
1049 0x00040000, /* EMC_DLL_XFORM_DQ2 */
1050 0x00040000, /* EMC_DLL_XFORM_DQ3 */
1051 0x000002a0, /* EMC_XM2CMDPADCTRL */
1052 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
1053 0x00000000, /* EMC_XM2DQPADCTRL2 */
1054 0x77fff884, /* EMC_XM2CLKPADCTRL */
1055 0x01f1f508, /* EMC_XM2COMPPADCTRL */
1056 0x05057404, /* EMC_XM2VTTGENPADCTRL */
1057 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
1058 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1059 0x08000021, /* EMC_XM2DQSPADCTRL3 */
1060 0x00000802, /* EMC_CTT_TERM_CTRL */
1061 0x00020000, /* EMC_ZCAL_INTERVAL */
1062 0x00000100, /* EMC_ZCAL_WAIT_CNT */
1063 0x0184000c, /* EMC_MRS_WAIT_CNT */
1064 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1065 0x00000000, /* EMC_CTT */
1066 0x00000000, /* EMC_CTT_DURATION */
1067 0x8000174b, /* EMC_DYN_SELF_REF_CONTROL */
1068 0x00000005, /* MC_EMEM_ARB_CFG */
1069 0x80000044, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1070 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
1071 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
1072 0x00000009, /* MC_EMEM_ARB_TIMING_RC */
1073 0x00000005, /* MC_EMEM_ARB_TIMING_RAS */
1074 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
1075 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
1076 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1077 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1078 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1079 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1080 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
1081 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
1082 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
1083 0x000d0709, /* MC_EMEM_ARB_DA_COVERS */
1084 0x75c6110a, /* MC_EMEM_ARB_MISC0 */
1085 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1086 0x58000000, /* EMC_FBIO_SPARE */
1087 0xff00ff88, /* EMC_CFG_RSV */
1088 },
1089 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1090 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1091 0x00000000, /* EMC_CFG.PERIODIC_QRST */
1092 0x80000521, /* Mode Register 0 */
1093 0x80100002, /* Mode Register 1 */
1094 0x80200000, /* Mode Register 2 */
1095 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1096 },
1097 {
1098 0x32, /* Rev 3.2 */
1099 400000, /* SDRAM frequency */
1100 {
1101 0x00000012, /* EMC_RC */
1102 0x00000040, /* EMC_RFC */
1103 0x0000000d, /* EMC_RAS */
1104 0x00000004, /* EMC_RP */
1105 0x00000002, /* EMC_R2W */
1106 0x00000009, /* EMC_W2R */
1107 0x00000002, /* EMC_R2P */
1108 0x0000000c, /* EMC_W2P */
1109 0x00000004, /* EMC_RD_RCD */
1110 0x00000004, /* EMC_WR_RCD */
1111 0x00000002, /* EMC_RRD */
1112 0x00000001, /* EMC_REXT */
1113 0x00000000, /* EMC_WEXT */
1114 0x00000005, /* EMC_WDV */
1115 0x00000007, /* EMC_QUSE */
1116 0x00000005, /* EMC_QRST */
1117 0x00000008, /* EMC_QSAFE */
1118 0x0000000e, /* EMC_RDV */
1119 0x00000c2e, /* EMC_REFRESH */
1120 0x00000000, /* EMC_BURST_REFRESH_NUM */
1121 0x0000030b, /* EMC_PRE_REFRESH_REQ_CNT */
1122 0x00000008, /* EMC_PDEX2WR */
1123 0x00000008, /* EMC_PDEX2RD */
1124 0x00000001, /* EMC_PCHG2PDEN */
1125 0x00000000, /* EMC_ACT2PDEN */
1126 0x00000008, /* EMC_AR2PDEN */
1127 0x00000011, /* EMC_RW2PDEN */
1128 0x00000046, /* EMC_TXSR */
1129 0x00000200, /* EMC_TXSRDLL */
1130 0x0000000a, /* EMC_TCKE */
1131 0x0000000d, /* EMC_TFAW */
1132 0x00000000, /* EMC_TRPAB */
1133 0x00000004, /* EMC_TCLKSTABLE */
1134 0x00000005, /* EMC_TCLKSTOP */
1135 0x00000c6f, /* EMC_TREFBW */
1136 0x00000000, /* EMC_QUSE_EXTRA */
1137 0x00000006, /* EMC_FBIO_CFG6 */
1138 0x00000000, /* EMC_ODT_WRITE */
1139 0x00000000, /* EMC_ODT_READ */
1140 0x00007088, /* EMC_FBIO_CFG5 */
1141 0x001c0084, /* EMC_CFG_DIG_DLL */
1142 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1143 0x00034000, /* EMC_DLL_XFORM_DQS0 */
1144 0x00034000, /* EMC_DLL_XFORM_DQS1 */
1145 0x00034000, /* EMC_DLL_XFORM_DQS2 */
1146 0x00034000, /* EMC_DLL_XFORM_DQS3 */
1147 0x00034000, /* EMC_DLL_XFORM_DQS4 */
1148 0x00034000, /* EMC_DLL_XFORM_DQS5 */
1149 0x00034000, /* EMC_DLL_XFORM_DQS6 */
1150 0x00034000, /* EMC_DLL_XFORM_DQS7 */
1151 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1152 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1153 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1154 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1155 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1156 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1157 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1158 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1159 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1160 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1161 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1162 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1163 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1164 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1165 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1166 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1167 0x00040000, /* EMC_DLL_XFORM_DQ0 */
1168 0x00040000, /* EMC_DLL_XFORM_DQ1 */
1169 0x00040000, /* EMC_DLL_XFORM_DQ2 */
1170 0x00040000, /* EMC_DLL_XFORM_DQ3 */
1171 0x000002a0, /* EMC_XM2CMDPADCTRL */
1172 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
1173 0x00000000, /* EMC_XM2DQPADCTRL2 */
1174 0x77fff884, /* EMC_XM2CLKPADCTRL */
1175 0x01f1f508, /* EMC_XM2COMPPADCTRL */
1176 0x05057404, /* EMC_XM2VTTGENPADCTRL */
1177 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
1178 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1179 0x08000021, /* EMC_XM2DQSPADCTRL3 */
1180 0x00000802, /* EMC_CTT_TERM_CTRL */
1181 0x00020000, /* EMC_ZCAL_INTERVAL */
1182 0x00000100, /* EMC_ZCAL_WAIT_CNT */
1183 0x017f000c, /* EMC_MRS_WAIT_CNT */
1184 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1185 0x00000000, /* EMC_CTT */
1186 0x00000000, /* EMC_CTT_DURATION */
1187 0x80001941, /* EMC_DYN_SELF_REF_CONTROL */
1188 0x00000006, /* MC_EMEM_ARB_CFG */
1189 0x8000004a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1190 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
1191 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
1192 0x0000000a, /* MC_EMEM_ARB_TIMING_RC */
1193 0x00000006, /* MC_EMEM_ARB_TIMING_RAS */
1194 0x00000006, /* MC_EMEM_ARB_TIMING_FAW */
1195 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
1196 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1197 0x00000009, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1198 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1199 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1200 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
1201 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
1202 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
1203 0x000e070a, /* MC_EMEM_ARB_DA_COVERS */
1204 0x7547130b, /* MC_EMEM_ARB_MISC0 */
1205 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1206 0x58000000, /* EMC_FBIO_SPARE */
1207 0xff00ff88, /* EMC_CFG_RSV */
1208 },
1209 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1210 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1211 0x00000000, /* EMC_CFG.PERIODIC_QRST */
1212 0x80000731, /* Mode Register 0 */
1213 0x80100002, /* Mode Register 1 */
1214 0x80200008, /* Mode Register 2 */
1215 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1216 },
1217 {
1218 0x32, /* Rev 3.2 */
1219 425000, /* SDRAM frequency */
1220 {
1221 0x00000012, /* EMC_RC */
1222 0x00000040, /* EMC_RFC */
1223 0x0000000d, /* EMC_RAS */
1224 0x00000004, /* EMC_RP */
1225 0x00000002, /* EMC_R2W */
1226 0x00000009, /* EMC_W2R */
1227 0x00000002, /* EMC_R2P */
1228 0x0000000c, /* EMC_W2P */
1229 0x00000004, /* EMC_RD_RCD */
1230 0x00000004, /* EMC_WR_RCD */
1231 0x00000002, /* EMC_RRD */
1232 0x00000001, /* EMC_REXT */
1233 0x00000000, /* EMC_WEXT */
1234 0x00000005, /* EMC_WDV */
1235 0x00000007, /* EMC_QUSE */
1236 0x00000005, /* EMC_QRST */
1237 0x00000008, /* EMC_QSAFE */
1238 0x0000000e, /* EMC_RDV */
1239 0x00000c2e, /* EMC_REFRESH */
1240 0x00000000, /* EMC_BURST_REFRESH_NUM */
1241 0x0000030b, /* EMC_PRE_REFRESH_REQ_CNT */
1242 0x00000008, /* EMC_PDEX2WR */
1243 0x00000008, /* EMC_PDEX2RD */
1244 0x00000001, /* EMC_PCHG2PDEN */
1245 0x00000000, /* EMC_ACT2PDEN */
1246 0x00000008, /* EMC_AR2PDEN */
1247 0x00000011, /* EMC_RW2PDEN */
1248 0x00000046, /* EMC_TXSR */
1249 0x00000200, /* EMC_TXSRDLL */
1250 0x0000000a, /* EMC_TCKE */
1251 0x0000000d, /* EMC_TFAW */
1252 0x00000000, /* EMC_TRPAB */
1253 0x00000004, /* EMC_TCLKSTABLE */
1254 0x00000005, /* EMC_TCLKSTOP */
1255 0x00000c6f, /* EMC_TREFBW */
1256 0x00000000, /* EMC_QUSE_EXTRA */
1257 0x00000006, /* EMC_FBIO_CFG6 */
1258 0x00000000, /* EMC_ODT_WRITE */
1259 0x00000000, /* EMC_ODT_READ */
1260 0x00007088, /* EMC_FBIO_CFG5 */
1261 0x001c0084, /* EMC_CFG_DIG_DLL */
1262 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1263 0x00034000, /* EMC_DLL_XFORM_DQS0 */
1264 0x00034000, /* EMC_DLL_XFORM_DQS1 */
1265 0x00034000, /* EMC_DLL_XFORM_DQS2 */
1266 0x00034000, /* EMC_DLL_XFORM_DQS3 */
1267 0x00034000, /* EMC_DLL_XFORM_DQS4 */
1268 0x00034000, /* EMC_DLL_XFORM_DQS5 */
1269 0x00034000, /* EMC_DLL_XFORM_DQS6 */
1270 0x00034000, /* EMC_DLL_XFORM_DQS7 */
1271 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1272 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1273 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1274 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1275 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1276 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1277 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1278 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1279 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1280 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1281 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1282 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1283 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1284 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1285 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1286 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1287 0x00040000, /* EMC_DLL_XFORM_DQ0 */
1288 0x00040000, /* EMC_DLL_XFORM_DQ1 */
1289 0x00040000, /* EMC_DLL_XFORM_DQ2 */
1290 0x00040000, /* EMC_DLL_XFORM_DQ3 */
1291 0x000002a0, /* EMC_XM2CMDPADCTRL */
1292 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
1293 0x00000000, /* EMC_XM2DQPADCTRL2 */
1294 0x77fff884, /* EMC_XM2CLKPADCTRL */
1295 0x01f1f508, /* EMC_XM2COMPPADCTRL */
1296 0x05057404, /* EMC_XM2VTTGENPADCTRL */
1297 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
1298 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1299 0x08000021, /* EMC_XM2DQSPADCTRL3 */
1300 0x00000802, /* EMC_CTT_TERM_CTRL */
1301 0x00020000, /* EMC_ZCAL_INTERVAL */
1302 0x00000100, /* EMC_ZCAL_WAIT_CNT */
1303 0x017f000c, /* EMC_MRS_WAIT_CNT */
1304 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1305 0x00000000, /* EMC_CTT */
1306 0x00000000, /* EMC_CTT_DURATION */
1307 0x80001941, /* EMC_DYN_SELF_REF_CONTROL */
1308 0x00000006, /* MC_EMEM_ARB_CFG */
1309 0x8000004a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1310 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
1311 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
1312 0x0000000a, /* MC_EMEM_ARB_TIMING_RC */
1313 0x00000006, /* MC_EMEM_ARB_TIMING_RAS */
1314 0x00000006, /* MC_EMEM_ARB_TIMING_FAW */
1315 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
1316 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1317 0x00000009, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1318 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1319 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1320 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
1321 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
1322 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
1323 0x000e070a, /* MC_EMEM_ARB_DA_COVERS */
1324 0x7547130b, /* MC_EMEM_ARB_MISC0 */
1325 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1326 0x58000000, /* EMC_FBIO_SPARE */
1327 0xff00ff88, /* EMC_CFG_RSV */
1328 },
1329 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1330 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1331 0x00000000, /* EMC_CFG.PERIODIC_QRST */
1332 0x80000731, /* Mode Register 0 */
1333 0x80100002, /* Mode Register 1 */
1334 0x80200008, /* Mode Register 2 */
1335 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1336 },
1337 {
1338 0x32, /* Rev 3.2 */
1339 450000, /* SDRAM frequency */
1340 {
1341 0x00000014, /* EMC_RC */
1342 0x00000046, /* EMC_RFC */
1343 0x0000000e, /* EMC_RAS */
1344 0x00000005, /* EMC_RP */
1345 0x00000003, /* EMC_R2W */
1346 0x00000009, /* EMC_W2R */
1347 0x00000002, /* EMC_R2P */
1348 0x0000000c, /* EMC_W2P */
1349 0x00000005, /* EMC_RD_RCD */
1350 0x00000005, /* EMC_WR_RCD */
1351 0x00000002, /* EMC_RRD */
1352 0x00000001, /* EMC_REXT */
1353 0x00000000, /* EMC_WEXT */
1354 0x00000005, /* EMC_WDV */
1355 0x00000007, /* EMC_QUSE */
1356 0x00000005, /* EMC_QRST */
1357 0x0000000a, /* EMC_QSAFE */
1358 0x0000000e, /* EMC_RDV */
1359 0x00000d76, /* EMC_REFRESH */
1360 0x00000000, /* EMC_BURST_REFRESH_NUM */
1361 0x0000035d, /* EMC_PRE_REFRESH_REQ_CNT */
1362 0x00000001, /* EMC_PDEX2WR */
1363 0x00000009, /* EMC_PDEX2RD */
1364 0x00000001, /* EMC_PCHG2PDEN */
1365 0x00000000, /* EMC_ACT2PDEN */
1366 0x00000009, /* EMC_AR2PDEN */
1367 0x00000011, /* EMC_RW2PDEN */
1368 0x0000004d, /* EMC_TXSR */
1369 0x00000200, /* EMC_TXSRDLL */
1370 0x00000004, /* EMC_TCKE */
1371 0x0000000e, /* EMC_TFAW */
1372 0x00000000, /* EMC_TRPAB */
1373 0x00000004, /* EMC_TCLKSTABLE */
1374 0x00000005, /* EMC_TCLKSTOP */
1375 0x00000db6, /* EMC_TREFBW */
1376 0x00000000, /* EMC_QUSE_EXTRA */
1377 0x00000006, /* EMC_FBIO_CFG6 */
1378 0x00000000, /* EMC_ODT_WRITE */
1379 0x00000000, /* EMC_ODT_READ */
1380 0x00007088, /* EMC_FBIO_CFG5 */
1381 0x00180084, /* EMC_CFG_DIG_DLL */
1382 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1383 0x00022000, /* EMC_DLL_XFORM_DQS0 */
1384 0x00022000, /* EMC_DLL_XFORM_DQS1 */
1385 0x00022000, /* EMC_DLL_XFORM_DQS2 */
1386 0x00022000, /* EMC_DLL_XFORM_DQS3 */
1387 0x00022000, /* EMC_DLL_XFORM_DQS4 */
1388 0x00022000, /* EMC_DLL_XFORM_DQS5 */
1389 0x00022000, /* EMC_DLL_XFORM_DQS6 */
1390 0x00022000, /* EMC_DLL_XFORM_DQS7 */
1391 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1392 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1393 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1394 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1395 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1396 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1397 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1398 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1399 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1400 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1401 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1402 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1403 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1404 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1405 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1406 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1407 0x00030000, /* EMC_DLL_XFORM_DQ0 */
1408 0x00030000, /* EMC_DLL_XFORM_DQ1 */
1409 0x00030000, /* EMC_DLL_XFORM_DQ2 */
1410 0x00030000, /* EMC_DLL_XFORM_DQ3 */
1411 0x000002a0, /* EMC_XM2CMDPADCTRL */
1412 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
1413 0x00000000, /* EMC_XM2DQPADCTRL2 */
1414 0x77fff884, /* EMC_XM2CLKPADCTRL */
1415 0x01f1f508, /* EMC_XM2COMPPADCTRL */
1416 0x05057404, /* EMC_XM2VTTGENPADCTRL */
1417 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
1418 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1419 0x08000021, /* EMC_XM2DQSPADCTRL3 */
1420 0x00000802, /* EMC_CTT_TERM_CTRL */
1421 0x00020000, /* EMC_ZCAL_INTERVAL */
1422 0x00000100, /* EMC_ZCAL_WAIT_CNT */
1423 0x0178000c, /* EMC_MRS_WAIT_CNT */
1424 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1425 0x00000000, /* EMC_CTT */
1426 0x00000000, /* EMC_CTT_DURATION */
1427 0x80001bc0, /* EMC_DYN_SELF_REF_CONTROL */
1428 0x00000006, /* MC_EMEM_ARB_CFG */
1429 0x80000051, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1430 0x00000002, /* MC_EMEM_ARB_TIMING_RCD */
1431 0x00000003, /* MC_EMEM_ARB_TIMING_RP */
1432 0x0000000b, /* MC_EMEM_ARB_TIMING_RC */
1433 0x00000006, /* MC_EMEM_ARB_TIMING_RAS */
1434 0x00000006, /* MC_EMEM_ARB_TIMING_FAW */
1435 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
1436 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1437 0x00000009, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1438 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1439 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1440 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
1441 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
1442 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
1443 0x000f080b, /* MC_EMEM_ARB_DA_COVERS */
1444 0x70a7150c, /* MC_EMEM_ARB_MISC0 */
1445 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1446 0xe8000000, /* EMC_FBIO_SPARE */
1447 0xff00ff8b, /* EMC_CFG_RSV */
1448 },
1449 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1450 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1451 0x00000000, /* EMC_CFG.PERIODIC_QRST */
1452 0x80000731, /* Mode Register 0 */
1453 0x80100002, /* Mode Register 1 */
1454 0x80200008, /* Mode Register 2 */
1455 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1456 },
1457 {
1458 0x32, /* Rev 3.2 */
1459 533000, /* SDRAM frequency */
1460 {
1461 0x00000018, /* EMC_RC */
1462 0x00000054, /* EMC_RFC */
1463 0x00000011, /* EMC_RAS */
1464 0x00000006, /* EMC_RP */
1465 0x00000003, /* EMC_R2W */
1466 0x00000009, /* EMC_W2R */
1467 0x00000002, /* EMC_R2P */
1468 0x0000000d, /* EMC_W2P */
1469 0x00000006, /* EMC_RD_RCD */
1470 0x00000006, /* EMC_WR_RCD */
1471 0x00000002, /* EMC_RRD */
1472 0x00000001, /* EMC_REXT */
1473 0x00000000, /* EMC_WEXT */
1474 0x00000005, /* EMC_WDV */
1475 0x00000008, /* EMC_QUSE */
1476 0x00000006, /* EMC_QRST */
1477 0x00000008, /* EMC_QSAFE */
1478 0x00000010, /* EMC_RDV */
1479 0x00000ffd, /* EMC_REFRESH */
1480 0x00000000, /* EMC_BURST_REFRESH_NUM */
1481 0x000003ff, /* EMC_PRE_REFRESH_REQ_CNT */
1482 0x0000000b, /* EMC_PDEX2WR */
1483 0x0000000b, /* EMC_PDEX2RD */
1484 0x00000001, /* EMC_PCHG2PDEN */
1485 0x00000000, /* EMC_ACT2PDEN */
1486 0x0000000a, /* EMC_AR2PDEN */
1487 0x00000012, /* EMC_RW2PDEN */
1488 0x0000005b, /* EMC_TXSR */
1489 0x00000200, /* EMC_TXSRDLL */
1490 0x0000000d, /* EMC_TCKE */
1491 0x00000010, /* EMC_TFAW */
1492 0x00000000, /* EMC_TRPAB */
1493 0x00000005, /* EMC_TCLKSTABLE */
1494 0x00000006, /* EMC_TCLKSTOP */
1495 0x0000103e, /* EMC_TREFBW */
1496 0x00000000, /* EMC_QUSE_EXTRA */
1497 0x00000006, /* EMC_FBIO_CFG6 */
1498 0x00000000, /* EMC_ODT_WRITE */
1499 0x00000000, /* EMC_ODT_READ */
1500 0x00007088, /* EMC_FBIO_CFG5 */
1501 0x00120084, /* EMC_CFG_DIG_DLL */
1502 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1503 0x00010000, /* EMC_DLL_XFORM_DQS0 */
1504 0x00010000, /* EMC_DLL_XFORM_DQS1 */
1505 0x00010000, /* EMC_DLL_XFORM_DQS2 */
1506 0x00010000, /* EMC_DLL_XFORM_DQS3 */
1507 0x00010000, /* EMC_DLL_XFORM_DQS4 */
1508 0x00010000, /* EMC_DLL_XFORM_DQS5 */
1509 0x00010000, /* EMC_DLL_XFORM_DQS6 */
1510 0x00010000, /* EMC_DLL_XFORM_DQS7 */
1511 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1512 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1513 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1514 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1515 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1516 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1517 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1518 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1519 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1520 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1521 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1522 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1523 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1524 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1525 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1526 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1527 0x00020000, /* EMC_DLL_XFORM_DQ0 */
1528 0x00020000, /* EMC_DLL_XFORM_DQ1 */
1529 0x00020000, /* EMC_DLL_XFORM_DQ2 */
1530 0x00020000, /* EMC_DLL_XFORM_DQ3 */
1531 0x000006a0, /* EMC_XM2CMDPADCTRL */
1532 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
1533 0x00000000, /* EMC_XM2DQPADCTRL2 */
1534 0x77ffc084, /* EMC_XM2CLKPADCTRL */
1535 0x01f1f508, /* EMC_XM2COMPPADCTRL */
1536 0x05057404, /* EMC_XM2VTTGENPADCTRL */
1537 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
1538 0x08000168, /* EMC_XM2QUSEPADCTRL */
1539 0x08000021, /* EMC_XM2DQSPADCTRL3 */
1540 0x00000802, /* EMC_CTT_TERM_CTRL */
1541 0x00000000, /* EMC_ZCAL_INTERVAL */
1542 0x00000040, /* EMC_ZCAL_WAIT_CNT */
1543 0x01ab000c, /* EMC_MRS_WAIT_CNT */
1544 0xa0f10404, /* EMC_AUTO_CAL_CONFIG */
1545 0x00000000, /* EMC_CTT */
1546 0x00000000, /* EMC_CTT_DURATION */
1547 0x800020ae, /* EMC_DYN_SELF_REF_CONTROL */
1548 0x00000008, /* MC_EMEM_ARB_CFG */
1549 0x80000060, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1550 0x00000002, /* MC_EMEM_ARB_TIMING_RCD */
1551 0x00000003, /* MC_EMEM_ARB_TIMING_RP */
1552 0x0000000d, /* MC_EMEM_ARB_TIMING_RC */
1553 0x00000008, /* MC_EMEM_ARB_TIMING_RAS */
1554 0x00000007, /* MC_EMEM_ARB_TIMING_FAW */
1555 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
1556 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1557 0x00000009, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1558 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1559 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1560 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
1561 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
1562 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
1563 0x0010090d, /* MC_EMEM_ARB_DA_COVERS */
1564 0x7028180e, /* MC_EMEM_ARB_MISC0 */
1565 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1566 0x00000000, /* EMC_FBIO_SPARE */
1567 0xff00ff00, /* EMC_CFG_RSV */
1568 },
1569 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1570 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1571 0x00000000, /* EMC_CFG.PERIODIC_QRST */
1572 0x80000941, /* Mode Register 0 */
1573 0x80100002, /* Mode Register 1 */
1574 0x80200008, /* Mode Register 2 */
1575 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1576 },
1577 {
1578 0x32, /* Rev 3.2 */
1579 750000, /* SDRAM frequency */
1580 {
1581 0x00000025, /* EMC_RC */
1582 0x0000007e, /* EMC_RFC */
1583 0x0000001a, /* EMC_RAS */
1584 0x00000009, /* EMC_RP */
1585 0x00000004, /* EMC_R2W */
1586 0x0000000d, /* EMC_W2R */
1587 0x00000004, /* EMC_R2P */
1588 0x00000013, /* EMC_W2P */
1589 0x00000009, /* EMC_RD_RCD */
1590 0x00000009, /* EMC_WR_RCD */
1591 0x00000003, /* EMC_RRD */
1592 0x00000001, /* EMC_REXT */
1593 0x00000000, /* EMC_WEXT */
1594 0x00000007, /* EMC_WDV */
1595 0x0000000b, /* EMC_QUSE */
1596 0x00000009, /* EMC_QRST */
1597 0x0000000c, /* EMC_QSAFE */
1598 0x00000011, /* EMC_RDV */
1599 0x0000169a, /* EMC_REFRESH */
1600 0x00000000, /* EMC_BURST_REFRESH_NUM */
1601 0x00000608, /* EMC_PRE_REFRESH_REQ_CNT */
1602 0x00000012, /* EMC_PDEX2WR */
1603 0x00000012, /* EMC_PDEX2RD */
1604 0x00000001, /* EMC_PCHG2PDEN */
1605 0x00000000, /* EMC_ACT2PDEN */
1606 0x0000000f, /* EMC_AR2PDEN */
1607 0x00000018, /* EMC_RW2PDEN */
1608 0x00000088, /* EMC_TXSR */
1609 0x00000200, /* EMC_TXSRDLL */
1610 0x00000014, /* EMC_TCKE */
1611 0x00000018, /* EMC_TFAW */
1612 0x00000000, /* EMC_TRPAB */
1613 0x00000007, /* EMC_TCLKSTABLE */
1614 0x00000008, /* EMC_TCLKSTOP */
1615 0x00001860, /* EMC_TREFBW */
1616 0x0000000c, /* EMC_QUSE_EXTRA */
1617 0x00000004, /* EMC_FBIO_CFG6 */
1618 0x00000000, /* EMC_ODT_WRITE */
1619 0x00000000, /* EMC_ODT_READ */
1620 0x00005088, /* EMC_FBIO_CFG5 */
1621 0xf0080191, /* EMC_CFG_DIG_DLL */
1622 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1623 0x00000008, /* EMC_DLL_XFORM_DQS0 */
1624 0x00000008, /* EMC_DLL_XFORM_DQS1 */
1625 0x00000008, /* EMC_DLL_XFORM_DQS2 */
1626 0x00000008, /* EMC_DLL_XFORM_DQS3 */
1627 0x00000008, /* EMC_DLL_XFORM_DQS4 */
1628 0x00000008, /* EMC_DLL_XFORM_DQS5 */
1629 0x00000008, /* EMC_DLL_XFORM_DQS6 */
1630 0x00000008, /* EMC_DLL_XFORM_DQS7 */
1631 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1632 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1633 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1634 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1635 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1636 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1637 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1638 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1639 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1640 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1641 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1642 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1643 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1644 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1645 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1646 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1647 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
1648 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
1649 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
1650 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
1651 0x000002a0, /* EMC_XM2CMDPADCTRL */
1652 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
1653 0x22220000, /* EMC_XM2DQPADCTRL2 */
1654 0x77fff884, /* EMC_XM2CLKPADCTRL */
1655 0x01f1f501, /* EMC_XM2COMPPADCTRL */
1656 0x07077404, /* EMC_XM2VTTGENPADCTRL */
1657 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
1658 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1659 0x07000021, /* EMC_XM2DQSPADCTRL3 */
1660 0x00000802, /* EMC_CTT_TERM_CTRL */
1661 0x00020000, /* EMC_ZCAL_INTERVAL */
1662 0x00000100, /* EMC_ZCAL_WAIT_CNT */
1663 0x0180000c, /* EMC_MRS_WAIT_CNT */
1664 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1665 0x00000000, /* EMC_CTT */
1666 0x00000000, /* EMC_CTT_DURATION */
1667 0x8000308c, /* EMC_DYN_SELF_REF_CONTROL */
1668 0x0000000c, /* MC_EMEM_ARB_CFG */
1669 0x80000090, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1670 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
1671 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
1672 0x00000013, /* MC_EMEM_ARB_TIMING_RC */
1673 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
1674 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
1675 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
1676 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1677 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1678 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1679 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1680 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
1681 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
1682 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
1683 0x00160d13, /* MC_EMEM_ARB_DA_COVERS */
1684 0x72ac2414, /* MC_EMEM_ARB_MISC0 */
1685 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1686 0xf8000000, /* EMC_FBIO_SPARE */
1687 0xff00ff49, /* EMC_CFG_RSV */
1688 },
1689 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1690 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1691 0x00000001, /* EMC_CFG.PERIODIC_QRST */
1692 0x80000d71, /* Mode Register 0 */
1693 0x80100002, /* Mode Register 1 */
1694 0x80200018, /* Mode Register 2 */
1695 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1696 },
1697 {
1698 0x32, /* Rev 3.2 */
1699 800000, /* SDRAM frequency */
1700 {
1701 0x00000025, /* EMC_RC */
1702 0x0000007e, /* EMC_RFC */
1703 0x0000001a, /* EMC_RAS */
1704 0x00000009, /* EMC_RP */
1705 0x00000004, /* EMC_R2W */
1706 0x0000000d, /* EMC_W2R */
1707 0x00000004, /* EMC_R2P */
1708 0x00000013, /* EMC_W2P */
1709 0x00000009, /* EMC_RD_RCD */
1710 0x00000009, /* EMC_WR_RCD */
1711 0x00000003, /* EMC_RRD */
1712 0x00000001, /* EMC_REXT */
1713 0x00000000, /* EMC_WEXT */
1714 0x00000007, /* EMC_WDV */
1715 0x0000000b, /* EMC_QUSE */
1716 0x00000009, /* EMC_QRST */
1717 0x0000000c, /* EMC_QSAFE */
1718 0x00000011, /* EMC_RDV */
1719 0x00001820, /* EMC_REFRESH */
1720 0x00000000, /* EMC_BURST_REFRESH_NUM */
1721 0x00000608, /* EMC_PRE_REFRESH_REQ_CNT */
1722 0x00000012, /* EMC_PDEX2WR */
1723 0x00000012, /* EMC_PDEX2RD */
1724 0x00000001, /* EMC_PCHG2PDEN */
1725 0x00000000, /* EMC_ACT2PDEN */
1726 0x0000000f, /* EMC_AR2PDEN */
1727 0x00000018, /* EMC_RW2PDEN */
1728 0x00000088, /* EMC_TXSR */
1729 0x00000200, /* EMC_TXSRDLL */
1730 0x00000014, /* EMC_TCKE */
1731 0x00000018, /* EMC_TFAW */
1732 0x00000000, /* EMC_TRPAB */
1733 0x00000007, /* EMC_TCLKSTABLE */
1734 0x00000008, /* EMC_TCLKSTOP */
1735 0x00001860, /* EMC_TREFBW */
1736 0x0000000c, /* EMC_QUSE_EXTRA */
1737 0x00000004, /* EMC_FBIO_CFG6 */
1738 0x00000000, /* EMC_ODT_WRITE */
1739 0x00000000, /* EMC_ODT_READ */
1740 0x00005088, /* EMC_FBIO_CFG5 */
1741 0xf0070191, /* EMC_CFG_DIG_DLL */
1742 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1743 0x0000000a, /* EMC_DLL_XFORM_DQS0 */
1744 0x0000000a, /* EMC_DLL_XFORM_DQS1 */
1745 0x0000000a, /* EMC_DLL_XFORM_DQS2 */
1746 0x0000000a, /* EMC_DLL_XFORM_DQS3 */
1747 0x0000000a, /* EMC_DLL_XFORM_DQS4 */
1748 0x0000000a, /* EMC_DLL_XFORM_DQS5 */
1749 0x0000000a, /* EMC_DLL_XFORM_DQS6 */
1750 0x0000000a, /* EMC_DLL_XFORM_DQS7 */
1751 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
1752 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
1753 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
1754 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
1755 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
1756 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
1757 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
1758 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
1759 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1760 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1761 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1762 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1763 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1764 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1765 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1766 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1767 0x0000000a, /* EMC_DLL_XFORM_DQ0 */
1768 0x0000000a, /* EMC_DLL_XFORM_DQ1 */
1769 0x0000000a, /* EMC_DLL_XFORM_DQ2 */
1770 0x0000000a, /* EMC_DLL_XFORM_DQ3 */
1771 0x000002a0, /* EMC_XM2CMDPADCTRL */
1772 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
1773 0x22220000, /* EMC_XM2DQPADCTRL2 */
1774 0x77fff884, /* EMC_XM2CLKPADCTRL */
1775 0x01f1f501, /* EMC_XM2COMPPADCTRL */
1776 0x07077404, /* EMC_XM2VTTGENPADCTRL */
1777 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
1778 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1779 0x07000021, /* EMC_XM2DQSPADCTRL3 */
1780 0x00000802, /* EMC_CTT_TERM_CTRL */
1781 0x00020000, /* EMC_ZCAL_INTERVAL */
1782 0x00000100, /* EMC_ZCAL_WAIT_CNT */
1783 0x0180000c, /* EMC_MRS_WAIT_CNT */
1784 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1785 0x00000000, /* EMC_CTT */
1786 0x00000000, /* EMC_CTT_DURATION */
1787 0x8000308c, /* EMC_DYN_SELF_REF_CONTROL */
1788 0x0000000c, /* MC_EMEM_ARB_CFG */
1789 0x80000090, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1790 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
1791 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
1792 0x00000013, /* MC_EMEM_ARB_TIMING_RC */
1793 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
1794 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
1795 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
1796 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1797 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1798 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1799 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1800 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
1801 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
1802 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
1803 0x00160d13, /* MC_EMEM_ARB_DA_COVERS */
1804 0x72ac2414, /* MC_EMEM_ARB_MISC0 */
1805 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1806 0xf8000000, /* EMC_FBIO_SPARE */
1807 0xff00ff49, /* EMC_CFG_RSV */
1808 },
1809 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
1810 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1811 0x00000001, /* EMC_CFG.PERIODIC_QRST */
1812 0x80000d71, /* Mode Register 0 */
1813 0x80100002, /* Mode Register 1 */
1814 0x80200018, /* Mode Register 2 */
1815 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1816 },
1817 {
1818 0x32, /* Rev 3.2 */
1819 850000, /* SDRAM frequency */
1820 {
1821 0x00000028, /* EMC_RC */
1822 0x00000086, /* EMC_RFC */
1823 0x0000001c, /* EMC_RAS */
1824 0x0000000a, /* EMC_RP */
1825 0x00000006, /* EMC_R2W */
1826 0x0000000f, /* EMC_W2R */
1827 0x00000005, /* EMC_R2P */
1828 0x00000016, /* EMC_W2P */
1829 0x0000000a, /* EMC_RD_RCD */
1830 0x0000000a, /* EMC_WR_RCD */
1831 0x00000004, /* EMC_RRD */
1832 0x00000001, /* EMC_REXT */
1833 0x00000000, /* EMC_WEXT */
1834 0x00000008, /* EMC_WDV */
1835 0x0000000d, /* EMC_QUSE */
1836 0x0000000b, /* EMC_QRST */
1837 0x0000000b, /* EMC_QSAFE */
1838 0x00000014, /* EMC_RDV */
1839 0x000019a6, /* EMC_REFRESH */
1840 0x00000000, /* EMC_BURST_REFRESH_NUM */
1841 0x00000669, /* EMC_PRE_REFRESH_REQ_CNT */
1842 0x00000004, /* EMC_PDEX2WR */
1843 0x00000013, /* EMC_PDEX2RD */
1844 0x00000001, /* EMC_PCHG2PDEN */
1845 0x00000000, /* EMC_ACT2PDEN */
1846 0x00000010, /* EMC_AR2PDEN */
1847 0x0000001b, /* EMC_RW2PDEN */
1848 0x00000091, /* EMC_TXSR */
1849 0x00000200, /* EMC_TXSRDLL */
1850 0x00000006, /* EMC_TCKE */
1851 0x0000001a, /* EMC_TFAW */
1852 0x00000000, /* EMC_TRPAB */
1853 0x00000008, /* EMC_TCLKSTABLE */
1854 0x00000009, /* EMC_TCLKSTOP */
1855 0x000019e6, /* EMC_TREFBW */
1856 0x0000000e, /* EMC_QUSE_EXTRA */
1857 0x00000004, /* EMC_FBIO_CFG6 */
1858 0x00000000, /* EMC_ODT_WRITE */
1859 0x00000000, /* EMC_ODT_READ */
1860 0x00005088, /* EMC_FBIO_CFG5 */
1861 0xf0050191, /* EMC_CFG_DIG_DLL */
1862 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1863 0x0000c00a, /* EMC_DLL_XFORM_DQS0 */
1864 0x0000000a, /* EMC_DLL_XFORM_DQS1 */
1865 0x007fc008, /* EMC_DLL_XFORM_DQS2 */
1866 0x007fc008, /* EMC_DLL_XFORM_DQS3 */
1867 0x0000000a, /* EMC_DLL_XFORM_DQS4 */
1868 0x0000000a, /* EMC_DLL_XFORM_DQS5 */
1869 0x0000000a, /* EMC_DLL_XFORM_DQS6 */
1870 0x0000000a, /* EMC_DLL_XFORM_DQS7 */
1871 0x0000c000, /* EMC_DLL_XFORM_QUSE0 */
1872 0x0000c000, /* EMC_DLL_XFORM_QUSE1 */
1873 0x0000c000, /* EMC_DLL_XFORM_QUSE2 */
1874 0x0000c000, /* EMC_DLL_XFORM_QUSE3 */
1875 0x0000c000, /* EMC_DLL_XFORM_QUSE4 */
1876 0x0000c000, /* EMC_DLL_XFORM_QUSE5 */
1877 0x0000c000, /* EMC_DLL_XFORM_QUSE6 */
1878 0x0000c000, /* EMC_DLL_XFORM_QUSE7 */
1879 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
1880 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
1881 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
1882 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
1883 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
1884 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
1885 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
1886 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
1887 0x007fc00a, /* EMC_DLL_XFORM_DQ0 */
1888 0x0000000a, /* EMC_DLL_XFORM_DQ1 */
1889 0x0000000a, /* EMC_DLL_XFORM_DQ2 */
1890 0x0000000a, /* EMC_DLL_XFORM_DQ3 */
1891 0x000002a0, /* EMC_XM2CMDPADCTRL */
1892 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
1893 0x22220000, /* EMC_XM2DQPADCTRL2 */
1894 0x77fff884, /* EMC_XM2CLKPADCTRL */
1895 0x01f1f501, /* EMC_XM2COMPPADCTRL */
1896 0x07077404, /* EMC_XM2VTTGENPADCTRL */
1897 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
1898 0x080001e8, /* EMC_XM2QUSEPADCTRL */
1899 0x07000021, /* EMC_XM2DQSPADCTRL3 */
1900 0x00000802, /* EMC_CTT_TERM_CTRL */
1901 0x00020000, /* EMC_ZCAL_INTERVAL */
1902 0x00000110, /* EMC_ZCAL_WAIT_CNT */
1903 0x0134000c, /* EMC_MRS_WAIT_CNT */
1904 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
1905 0x00000000, /* EMC_CTT */
1906 0x00000000, /* EMC_CTT_DURATION */
1907 0x80003384, /* EMC_DYN_SELF_REF_CONTROL */
1908 0x0000000c, /* MC_EMEM_ARB_CFG */
1909 0x80000099, /* MC_EMEM_ARB_OUTSTANDING_REQ */
1910 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
1911 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
1912 0x00000014, /* MC_EMEM_ARB_TIMING_RC */
1913 0x0000000d, /* MC_EMEM_ARB_TIMING_RAS */
1914 0x0000000c, /* MC_EMEM_ARB_TIMING_FAW */
1915 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
1916 0x00000004, /* MC_EMEM_ARB_TIMING_RAP2PRE */
1917 0x0000000e, /* MC_EMEM_ARB_TIMING_WAP2PRE */
1918 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
1919 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
1920 0x00000005, /* MC_EMEM_ARB_TIMING_R2W */
1921 0x00000009, /* MC_EMEM_ARB_TIMING_W2R */
1922 0x09050202, /* MC_EMEM_ARB_DA_TURNS */
1923 0x00190f14, /* MC_EMEM_ARB_DA_COVERS */
1924 0x714d2715, /* MC_EMEM_ARB_MISC0 */
1925 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
1926 0xe8000000, /* EMC_FBIO_SPARE */
1927 0xff00ff49, /* EMC_CFG_RSV */
1928 },
1929 0x00000044, /* EMC_ZCAL_WAIT_CNT after clock change */
1930 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
1931 0x00000001, /* EMC_CFG.PERIODIC_QRST */
1932 0x80000f15, /* Mode Register 0 */
1933 0x80100002, /* Mode Register 1 */
1934 0x80200020, /* Mode Register 2 */
1935 0x00000000, /* EMC_CFG.DYN_SELF_REF */
1936 },
1937 {
1938 0x32, /* Rev 3.2 */
1939 900000, /* SDRAM frequency */
1940 {
1941 0x0000002a, /* EMC_RC */
1942 0x0000008e, /* EMC_RFC */
1943 0x0000001e, /* EMC_RAS */
1944 0x0000000b, /* EMC_RP */
1945 0x00000006, /* EMC_R2W */
1946 0x0000000f, /* EMC_W2R */
1947 0x00000005, /* EMC_R2P */
1948 0x00000016, /* EMC_W2P */
1949 0x0000000b, /* EMC_RD_RCD */
1950 0x0000000b, /* EMC_WR_RCD */
1951 0x00000004, /* EMC_RRD */
1952 0x00000001, /* EMC_REXT */
1953 0x00000000, /* EMC_WEXT */
1954 0x00000008, /* EMC_WDV */
1955 0x0000000d, /* EMC_QUSE */
1956 0x0000000b, /* EMC_QRST */
1957 0x0000000b, /* EMC_QSAFE */
1958 0x00000014, /* EMC_RDV */
1959 0x00001b2c, /* EMC_REFRESH */
1960 0x00000000, /* EMC_BURST_REFRESH_NUM */
1961 0x000006cb, /* EMC_PRE_REFRESH_REQ_CNT */
1962 0x00000004, /* EMC_PDEX2WR */
1963 0x00000014, /* EMC_PDEX2RD */
1964 0x00000001, /* EMC_PCHG2PDEN */
1965 0x00000000, /* EMC_ACT2PDEN */
1966 0x00000011, /* EMC_AR2PDEN */
1967 0x0000001b, /* EMC_RW2PDEN */
1968 0x00000099, /* EMC_TXSR */
1969 0x00000200, /* EMC_TXSRDLL */
1970 0x00000006, /* EMC_TCKE */
1971 0x0000001b, /* EMC_TFAW */
1972 0x00000000, /* EMC_TRPAB */
1973 0x00000008, /* EMC_TCLKSTABLE */
1974 0x00000009, /* EMC_TCLKSTOP */
1975 0x00001b6c, /* EMC_TREFBW */
1976 0x0000000e, /* EMC_QUSE_EXTRA */
1977 0x00000004, /* EMC_FBIO_CFG6 */
1978 0x00000000, /* EMC_ODT_WRITE */
1979 0x00000000, /* EMC_ODT_READ */
1980 0x00005088, /* EMC_FBIO_CFG5 */
1981 0xf0040191, /* EMC_CFG_DIG_DLL */
1982 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
1983 0x0000800a, /* EMC_DLL_XFORM_DQS0 */
1984 0x0000000a, /* EMC_DLL_XFORM_DQS1 */
1985 0x007fc00a, /* EMC_DLL_XFORM_DQS2 */
1986 0x0000000a, /* EMC_DLL_XFORM_DQS3 */
1987 0x0000000a, /* EMC_DLL_XFORM_DQS4 */
1988 0x0000000a, /* EMC_DLL_XFORM_DQS5 */
1989 0x0000000a, /* EMC_DLL_XFORM_DQS6 */
1990 0x0000000a, /* EMC_DLL_XFORM_DQS7 */
1991 0x0001c000, /* EMC_DLL_XFORM_QUSE0 */
1992 0x0001c000, /* EMC_DLL_XFORM_QUSE1 */
1993 0x0001c000, /* EMC_DLL_XFORM_QUSE2 */
1994 0x0001c000, /* EMC_DLL_XFORM_QUSE3 */
1995 0x0001c000, /* EMC_DLL_XFORM_QUSE4 */
1996 0x0001c000, /* EMC_DLL_XFORM_QUSE5 */
1997 0x0001c000, /* EMC_DLL_XFORM_QUSE6 */
1998 0x0001c000, /* EMC_DLL_XFORM_QUSE7 */
1999 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2000 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2001 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2002 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2003 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2004 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2005 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2006 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2007 0x007fc00a, /* EMC_DLL_XFORM_DQ0 */
2008 0x0000000a, /* EMC_DLL_XFORM_DQ1 */
2009 0x0000000a, /* EMC_DLL_XFORM_DQ2 */
2010 0x0000000a, /* EMC_DLL_XFORM_DQ3 */
2011 0x000002a0, /* EMC_XM2CMDPADCTRL */
2012 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
2013 0x22220000, /* EMC_XM2DQPADCTRL2 */
2014 0x77fff884, /* EMC_XM2CLKPADCTRL */
2015 0x01f1f501, /* EMC_XM2COMPPADCTRL */
2016 0x07077404, /* EMC_XM2VTTGENPADCTRL */
2017 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
2018 0x080001e8, /* EMC_XM2QUSEPADCTRL */
2019 0x07000021, /* EMC_XM2DQSPADCTRL3 */
2020 0x00000802, /* EMC_CTT_TERM_CTRL */
2021 0x00020000, /* EMC_ZCAL_INTERVAL */
2022 0x00000120, /* EMC_ZCAL_WAIT_CNT */
2023 0x0128000c, /* EMC_MRS_WAIT_CNT */
2024 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2025 0x00000000, /* EMC_CTT */
2026 0x00000000, /* EMC_CTT_DURATION */
2027 0x8000367d, /* EMC_DYN_SELF_REF_CONTROL */
2028 0x0000000d, /* MC_EMEM_ARB_CFG */
2029 0x800000a2, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2030 0x00000005, /* MC_EMEM_ARB_TIMING_RCD */
2031 0x00000006, /* MC_EMEM_ARB_TIMING_RP */
2032 0x00000016, /* MC_EMEM_ARB_TIMING_RC */
2033 0x0000000e, /* MC_EMEM_ARB_TIMING_RAS */
2034 0x0000000d, /* MC_EMEM_ARB_TIMING_FAW */
2035 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
2036 0x00000004, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2037 0x0000000e, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2038 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2039 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
2040 0x00000005, /* MC_EMEM_ARB_TIMING_R2W */
2041 0x00000009, /* MC_EMEM_ARB_TIMING_W2R */
2042 0x09050202, /* MC_EMEM_ARB_DA_TURNS */
2043 0x001a1016, /* MC_EMEM_ARB_DA_COVERS */
2044 0x714e2917, /* MC_EMEM_ARB_MISC0 */
2045 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2046 0xe8000000, /* EMC_FBIO_SPARE */
2047 0xff00ff4b, /* EMC_CFG_RSV */
2048 },
2049 0x00000048, /* EMC_ZCAL_WAIT_CNT after clock change */
2050 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2051 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2052 0x80000f15, /* Mode Register 0 */
2053 0x80100002, /* Mode Register 1 */
2054 0x80200020, /* Mode Register 2 */
2055 0x00000000, /* EMC_CFG.DYN_SELF_REF */
2056 },
2057};
2058
2059static const struct tegra_emc_table cardhu_emc_tables_h5tc2g_a2_2GB1R[] = {
2060 {
2061 0x32, /* Rev 3.2 */
2062 51000, /* SDRAM frequency */
2063 {
2064 0x00000002, /* EMC_RC */
2065 0x0000000d, /* EMC_RFC */
2066 0x00000001, /* EMC_RAS */
2067 0x00000000, /* EMC_RP */
2068 0x00000002, /* EMC_R2W */
2069 0x0000000a, /* EMC_W2R */
2070 0x00000003, /* EMC_R2P */
2071 0x0000000b, /* EMC_W2P */
2072 0x00000000, /* EMC_RD_RCD */
2073 0x00000000, /* EMC_WR_RCD */
2074 0x00000003, /* EMC_RRD */
2075 0x00000001, /* EMC_REXT */
2076 0x00000000, /* EMC_WEXT */
2077 0x00000005, /* EMC_WDV */
2078 0x00000005, /* EMC_QUSE */
2079 0x00000004, /* EMC_QRST */
2080 0x00000009, /* EMC_QSAFE */
2081 0x0000000b, /* EMC_RDV */
2082 0x00000181, /* EMC_REFRESH */
2083 0x00000000, /* EMC_BURST_REFRESH_NUM */
2084 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
2085 0x00000002, /* EMC_PDEX2WR */
2086 0x00000002, /* EMC_PDEX2RD */
2087 0x00000001, /* EMC_PCHG2PDEN */
2088 0x00000000, /* EMC_ACT2PDEN */
2089 0x00000007, /* EMC_AR2PDEN */
2090 0x0000000f, /* EMC_RW2PDEN */
2091 0x0000000e, /* EMC_TXSR */
2092 0x0000000e, /* EMC_TXSRDLL */
2093 0x00000004, /* EMC_TCKE */
2094 0x00000002, /* EMC_TFAW */
2095 0x00000000, /* EMC_TRPAB */
2096 0x00000004, /* EMC_TCLKSTABLE */
2097 0x00000005, /* EMC_TCLKSTOP */
2098 0x0000018e, /* EMC_TREFBW */
2099 0x00000006, /* EMC_QUSE_EXTRA */
2100 0x00000004, /* EMC_FBIO_CFG6 */
2101 0x00000000, /* EMC_ODT_WRITE */
2102 0x00000000, /* EMC_ODT_READ */
2103 0x00004288, /* EMC_FBIO_CFG5 */
2104 0x007800a4, /* EMC_CFG_DIG_DLL */
2105 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2106 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
2107 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
2108 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
2109 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
2110 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
2111 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
2112 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
2113 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
2114 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2115 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2116 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2117 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2118 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2119 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2120 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2121 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2122 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2123 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2124 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2125 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2126 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2127 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2128 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2129 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2130 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
2131 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
2132 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
2133 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
2134 0x000002a0, /* EMC_XM2CMDPADCTRL */
2135 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
2136 0x00000000, /* EMC_XM2DQPADCTRL2 */
2137 0x77fff884, /* EMC_XM2CLKPADCTRL */
2138 0x01f1f108, /* EMC_XM2COMPPADCTRL */
2139 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2140 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2141 0x08000168, /* EMC_XM2QUSEPADCTRL */
2142 0x08000000, /* EMC_XM2DQSPADCTRL3 */
2143 0x00000802, /* EMC_CTT_TERM_CTRL */
2144 0x00000000, /* EMC_ZCAL_INTERVAL */
2145 0x00000040, /* EMC_ZCAL_WAIT_CNT */
2146 0x000c000c, /* EMC_MRS_WAIT_CNT */
2147 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2148 0x00000000, /* EMC_CTT */
2149 0x00000000, /* EMC_CTT_DURATION */
2150 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
2151 0x00010001, /* MC_EMEM_ARB_CFG */
2152 0xc0000010, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2153 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2154 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
2155 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
2156 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
2157 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
2158 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
2159 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2160 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2161 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2162 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
2163 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
2164 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
2165 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
2166 0x000a0402, /* MC_EMEM_ARB_DA_COVERS */
2167 0x74630303, /* MC_EMEM_ARB_MISC0 */
2168 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2169 0xe8000000, /* EMC_FBIO_SPARE */
2170 0xff00ff00, /* EMC_CFG_RSV */
2171 },
2172 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2173 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2174 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2175 0x80001221, /* Mode Register 0 */
2176 0x80100003, /* Mode Register 1 */
2177 0x80200008, /* Mode Register 2 */
2178 0x00000001, /* EMC_CFG.DYN_SELF_REF */
2179 },
2180 {
2181 0x32, /* Rev 3.2 */
2182 102000, /* SDRAM frequency */
2183 {
2184 0x00000004, /* EMC_RC */
2185 0x0000001a, /* EMC_RFC */
2186 0x00000003, /* EMC_RAS */
2187 0x00000001, /* EMC_RP */
2188 0x00000002, /* EMC_R2W */
2189 0x0000000a, /* EMC_W2R */
2190 0x00000003, /* EMC_R2P */
2191 0x0000000b, /* EMC_W2P */
2192 0x00000001, /* EMC_RD_RCD */
2193 0x00000001, /* EMC_WR_RCD */
2194 0x00000003, /* EMC_RRD */
2195 0x00000001, /* EMC_REXT */
2196 0x00000000, /* EMC_WEXT */
2197 0x00000005, /* EMC_WDV */
2198 0x00000005, /* EMC_QUSE */
2199 0x00000004, /* EMC_QRST */
2200 0x00000009, /* EMC_QSAFE */
2201 0x0000000b, /* EMC_RDV */
2202 0x00000303, /* EMC_REFRESH */
2203 0x00000000, /* EMC_BURST_REFRESH_NUM */
2204 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
2205 0x00000002, /* EMC_PDEX2WR */
2206 0x00000002, /* EMC_PDEX2RD */
2207 0x00000001, /* EMC_PCHG2PDEN */
2208 0x00000000, /* EMC_ACT2PDEN */
2209 0x00000007, /* EMC_AR2PDEN */
2210 0x0000000f, /* EMC_RW2PDEN */
2211 0x0000001c, /* EMC_TXSR */
2212 0x0000001c, /* EMC_TXSRDLL */
2213 0x00000004, /* EMC_TCKE */
2214 0x00000004, /* EMC_TFAW */
2215 0x00000000, /* EMC_TRPAB */
2216 0x00000004, /* EMC_TCLKSTABLE */
2217 0x00000005, /* EMC_TCLKSTOP */
2218 0x0000031c, /* EMC_TREFBW */
2219 0x00000006, /* EMC_QUSE_EXTRA */
2220 0x00000004, /* EMC_FBIO_CFG6 */
2221 0x00000000, /* EMC_ODT_WRITE */
2222 0x00000000, /* EMC_ODT_READ */
2223 0x00004288, /* EMC_FBIO_CFG5 */
2224 0x007800a4, /* EMC_CFG_DIG_DLL */
2225 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2226 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
2227 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
2228 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
2229 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
2230 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
2231 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
2232 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
2233 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
2234 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2235 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2236 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2237 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2238 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2239 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2240 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2241 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2242 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2243 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2244 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2245 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2246 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2247 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2248 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2249 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2250 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
2251 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
2252 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
2253 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
2254 0x000002a0, /* EMC_XM2CMDPADCTRL */
2255 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
2256 0x00000000, /* EMC_XM2DQPADCTRL2 */
2257 0x77fff884, /* EMC_XM2CLKPADCTRL */
2258 0x01f1f108, /* EMC_XM2COMPPADCTRL */
2259 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2260 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2261 0x08000168, /* EMC_XM2QUSEPADCTRL */
2262 0x08000000, /* EMC_XM2DQSPADCTRL3 */
2263 0x00000802, /* EMC_CTT_TERM_CTRL */
2264 0x00000000, /* EMC_ZCAL_INTERVAL */
2265 0x00000040, /* EMC_ZCAL_WAIT_CNT */
2266 0x000c000c, /* EMC_MRS_WAIT_CNT */
2267 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2268 0x00000000, /* EMC_CTT */
2269 0x00000000, /* EMC_CTT_DURATION */
2270 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
2271 0x00000001, /* MC_EMEM_ARB_CFG */
2272 0xc0000018, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2273 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2274 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
2275 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
2276 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
2277 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
2278 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
2279 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2280 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2281 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2282 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
2283 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
2284 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
2285 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
2286 0x000a0403, /* MC_EMEM_ARB_DA_COVERS */
2287 0x73c30504, /* MC_EMEM_ARB_MISC0 */
2288 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2289 0xe8000000, /* EMC_FBIO_SPARE */
2290 0xff00ff00, /* EMC_CFG_RSV */
2291 },
2292 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2293 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2294 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2295 0x80001221, /* Mode Register 0 */
2296 0x80100003, /* Mode Register 1 */
2297 0x80200008, /* Mode Register 2 */
2298 0x00000001, /* EMC_CFG.DYN_SELF_REF */
2299 },
2300 {
2301 0x32, /* Rev 3.2 */
2302 204000, /* SDRAM frequency */
2303 {
2304 0x00000009, /* EMC_RC */
2305 0x00000035, /* EMC_RFC */
2306 0x00000007, /* EMC_RAS */
2307 0x00000002, /* EMC_RP */
2308 0x00000002, /* EMC_R2W */
2309 0x0000000a, /* EMC_W2R */
2310 0x00000003, /* EMC_R2P */
2311 0x0000000b, /* EMC_W2P */
2312 0x00000002, /* EMC_RD_RCD */
2313 0x00000002, /* EMC_WR_RCD */
2314 0x00000003, /* EMC_RRD */
2315 0x00000001, /* EMC_REXT */
2316 0x00000000, /* EMC_WEXT */
2317 0x00000005, /* EMC_WDV */
2318 0x00000005, /* EMC_QUSE */
2319 0x00000004, /* EMC_QRST */
2320 0x00000009, /* EMC_QSAFE */
2321 0x0000000b, /* EMC_RDV */
2322 0x00000607, /* EMC_REFRESH */
2323 0x00000000, /* EMC_BURST_REFRESH_NUM */
2324 0x00000181, /* EMC_PRE_REFRESH_REQ_CNT */
2325 0x00000002, /* EMC_PDEX2WR */
2326 0x00000002, /* EMC_PDEX2RD */
2327 0x00000001, /* EMC_PCHG2PDEN */
2328 0x00000000, /* EMC_ACT2PDEN */
2329 0x00000007, /* EMC_AR2PDEN */
2330 0x0000000f, /* EMC_RW2PDEN */
2331 0x00000038, /* EMC_TXSR */
2332 0x00000038, /* EMC_TXSRDLL */
2333 0x00000004, /* EMC_TCKE */
2334 0x00000007, /* EMC_TFAW */
2335 0x00000000, /* EMC_TRPAB */
2336 0x00000004, /* EMC_TCLKSTABLE */
2337 0x00000005, /* EMC_TCLKSTOP */
2338 0x00000638, /* EMC_TREFBW */
2339 0x00000006, /* EMC_QUSE_EXTRA */
2340 0x00000004, /* EMC_FBIO_CFG6 */
2341 0x00000000, /* EMC_ODT_WRITE */
2342 0x00000000, /* EMC_ODT_READ */
2343 0x00004288, /* EMC_FBIO_CFG5 */
2344 0x004400a4, /* EMC_CFG_DIG_DLL */
2345 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2346 0x00080000, /* EMC_DLL_XFORM_DQS0 */
2347 0x00080000, /* EMC_DLL_XFORM_DQS1 */
2348 0x00080000, /* EMC_DLL_XFORM_DQS2 */
2349 0x00080000, /* EMC_DLL_XFORM_DQS3 */
2350 0x00080000, /* EMC_DLL_XFORM_DQS4 */
2351 0x00080000, /* EMC_DLL_XFORM_DQS5 */
2352 0x00080000, /* EMC_DLL_XFORM_DQS6 */
2353 0x00080000, /* EMC_DLL_XFORM_DQS7 */
2354 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2355 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2356 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2357 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2358 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2359 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2360 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2361 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2362 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2363 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2364 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2365 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2366 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2367 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2368 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2369 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2370 0x00080000, /* EMC_DLL_XFORM_DQ0 */
2371 0x00080000, /* EMC_DLL_XFORM_DQ1 */
2372 0x00080000, /* EMC_DLL_XFORM_DQ2 */
2373 0x00080000, /* EMC_DLL_XFORM_DQ3 */
2374 0x000002a0, /* EMC_XM2CMDPADCTRL */
2375 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
2376 0x00000000, /* EMC_XM2DQPADCTRL2 */
2377 0x77fff884, /* EMC_XM2CLKPADCTRL */
2378 0x01f1f108, /* EMC_XM2COMPPADCTRL */
2379 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2380 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2381 0x08000168, /* EMC_XM2QUSEPADCTRL */
2382 0x08000000, /* EMC_XM2DQSPADCTRL3 */
2383 0x00000802, /* EMC_CTT_TERM_CTRL */
2384 0x00020000, /* EMC_ZCAL_INTERVAL */
2385 0x00000100, /* EMC_ZCAL_WAIT_CNT */
2386 0x000c000c, /* EMC_MRS_WAIT_CNT */
2387 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2388 0x00000000, /* EMC_CTT */
2389 0x00000000, /* EMC_CTT_DURATION */
2390 0x80000d22, /* EMC_DYN_SELF_REF_CONTROL */
2391 0x00000003, /* MC_EMEM_ARB_CFG */
2392 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2393 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2394 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
2395 0x00000005, /* MC_EMEM_ARB_TIMING_RC */
2396 0x00000002, /* MC_EMEM_ARB_TIMING_RAS */
2397 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
2398 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
2399 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2400 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2401 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2402 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
2403 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
2404 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
2405 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
2406 0x000a0405, /* MC_EMEM_ARB_DA_COVERS */
2407 0x73840a06, /* MC_EMEM_ARB_MISC0 */
2408 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2409 0xe8000000, /* EMC_FBIO_SPARE */
2410 0xff00ff00, /* EMC_CFG_RSV */
2411 },
2412 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2413 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2414 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2415 0x80001221, /* Mode Register 0 */
2416 0x80100003, /* Mode Register 1 */
2417 0x80200008, /* Mode Register 2 */
2418 0x00000001, /* EMC_CFG.DYN_SELF_REF */
2419 },
2420 {
2421 0x32, /* Rev 3.2 */
2422 375000, /* SDRAM frequency */
2423 {
2424 0x00000011, /* EMC_RC */
2425 0x0000006f, /* EMC_RFC */
2426 0x0000000c, /* EMC_RAS */
2427 0x00000004, /* EMC_RP */
2428 0x00000003, /* EMC_R2W */
2429 0x00000008, /* EMC_W2R */
2430 0x00000002, /* EMC_R2P */
2431 0x0000000a, /* EMC_W2P */
2432 0x00000004, /* EMC_RD_RCD */
2433 0x00000004, /* EMC_WR_RCD */
2434 0x00000002, /* EMC_RRD */
2435 0x00000001, /* EMC_REXT */
2436 0x00000000, /* EMC_WEXT */
2437 0x00000004, /* EMC_WDV */
2438 0x00000006, /* EMC_QUSE */
2439 0x00000004, /* EMC_QRST */
2440 0x0000000a, /* EMC_QSAFE */
2441 0x0000000d, /* EMC_RDV */
2442 0x00000b2d, /* EMC_REFRESH */
2443 0x00000000, /* EMC_BURST_REFRESH_NUM */
2444 0x000002cb, /* EMC_PRE_REFRESH_REQ_CNT */
2445 0x00000001, /* EMC_PDEX2WR */
2446 0x00000008, /* EMC_PDEX2RD */
2447 0x00000001, /* EMC_PCHG2PDEN */
2448 0x00000000, /* EMC_ACT2PDEN */
2449 0x00000007, /* EMC_AR2PDEN */
2450 0x0000000f, /* EMC_RW2PDEN */
2451 0x00000075, /* EMC_TXSR */
2452 0x00000200, /* EMC_TXSRDLL */
2453 0x00000004, /* EMC_TCKE */
2454 0x0000000c, /* EMC_TFAW */
2455 0x00000000, /* EMC_TRPAB */
2456 0x00000004, /* EMC_TCLKSTABLE */
2457 0x00000005, /* EMC_TCLKSTOP */
2458 0x00000b6d, /* EMC_TREFBW */
2459 0x00000000, /* EMC_QUSE_EXTRA */
2460 0x00000006, /* EMC_FBIO_CFG6 */
2461 0x00000000, /* EMC_ODT_WRITE */
2462 0x00000000, /* EMC_ODT_READ */
2463 0x00007088, /* EMC_FBIO_CFG5 */
2464 0x00200084, /* EMC_CFG_DIG_DLL */
2465 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2466 0x0003c000, /* EMC_DLL_XFORM_DQS0 */
2467 0x0003c000, /* EMC_DLL_XFORM_DQS1 */
2468 0x0003c000, /* EMC_DLL_XFORM_DQS2 */
2469 0x0003c000, /* EMC_DLL_XFORM_DQS3 */
2470 0x0003c000, /* EMC_DLL_XFORM_DQS4 */
2471 0x0003c000, /* EMC_DLL_XFORM_DQS5 */
2472 0x0003c000, /* EMC_DLL_XFORM_DQS6 */
2473 0x0003c000, /* EMC_DLL_XFORM_DQS7 */
2474 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2475 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2476 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2477 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2478 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2479 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2480 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2481 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2482 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2483 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2484 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2485 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2486 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2487 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2488 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2489 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2490 0x00040000, /* EMC_DLL_XFORM_DQ0 */
2491 0x00040000, /* EMC_DLL_XFORM_DQ1 */
2492 0x00040000, /* EMC_DLL_XFORM_DQ2 */
2493 0x00040000, /* EMC_DLL_XFORM_DQ3 */
2494 0x000002a0, /* EMC_XM2CMDPADCTRL */
2495 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
2496 0x00000000, /* EMC_XM2DQPADCTRL2 */
2497 0x77fff884, /* EMC_XM2CLKPADCTRL */
2498 0x01f1f508, /* EMC_XM2COMPPADCTRL */
2499 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2500 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2501 0x080001e8, /* EMC_XM2QUSEPADCTRL */
2502 0x08000021, /* EMC_XM2DQSPADCTRL3 */
2503 0x00000802, /* EMC_CTT_TERM_CTRL */
2504 0x00020000, /* EMC_ZCAL_INTERVAL */
2505 0x00000100, /* EMC_ZCAL_WAIT_CNT */
2506 0x0150000c, /* EMC_MRS_WAIT_CNT */
2507 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2508 0x00000000, /* EMC_CTT */
2509 0x00000000, /* EMC_CTT_DURATION */
2510 0x8000174b, /* EMC_DYN_SELF_REF_CONTROL */
2511 0x00000005, /* MC_EMEM_ARB_CFG */
2512 0x80000044, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2513 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2514 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
2515 0x00000009, /* MC_EMEM_ARB_TIMING_RC */
2516 0x00000005, /* MC_EMEM_ARB_TIMING_RAS */
2517 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
2518 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
2519 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2520 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2521 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2522 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
2523 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
2524 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
2525 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
2526 0x000d0709, /* MC_EMEM_ARB_DA_COVERS */
2527 0x75c6110a, /* MC_EMEM_ARB_MISC0 */
2528 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2529 0x58000000, /* EMC_FBIO_SPARE */
2530 0xff00ff88, /* EMC_CFG_RSV */
2531 },
2532 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2533 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2534 0x00000000, /* EMC_CFG.PERIODIC_QRST */
2535 0x80000521, /* Mode Register 0 */
2536 0x80100002, /* Mode Register 1 */
2537 0x80200000, /* Mode Register 2 */
2538 0x00000000, /* EMC_CFG.DYN_SELF_REF */
2539 },
2540 {
2541 0x32, /* Rev 3.2 */
2542 750000, /* SDRAM frequency */
2543 {
2544 0x00000023, /* EMC_RC */
2545 0x000000df, /* EMC_RFC */
2546 0x00000019, /* EMC_RAS */
2547 0x00000009, /* EMC_RP */
2548 0x00000005, /* EMC_R2W */
2549 0x0000000d, /* EMC_W2R */
2550 0x00000004, /* EMC_R2P */
2551 0x00000013, /* EMC_W2P */
2552 0x00000009, /* EMC_RD_RCD */
2553 0x00000009, /* EMC_WR_RCD */
2554 0x00000003, /* EMC_RRD */
2555 0x00000001, /* EMC_REXT */
2556 0x00000000, /* EMC_WEXT */
2557 0x00000007, /* EMC_WDV */
2558 0x0000000b, /* EMC_QUSE */
2559 0x00000009, /* EMC_QRST */
2560 0x0000000c, /* EMC_QSAFE */
2561 0x00000011, /* EMC_RDV */
2562 0x0000169a, /* EMC_REFRESH */
2563 0x00000000, /* EMC_BURST_REFRESH_NUM */
2564 0x000005a6, /* EMC_PRE_REFRESH_REQ_CNT */
2565 0x00000003, /* EMC_PDEX2WR */
2566 0x00000010, /* EMC_PDEX2RD */
2567 0x00000001, /* EMC_PCHG2PDEN */
2568 0x00000000, /* EMC_ACT2PDEN */
2569 0x0000000e, /* EMC_AR2PDEN */
2570 0x00000018, /* EMC_RW2PDEN */
2571 0x000000e9, /* EMC_TXSR */
2572 0x00000200, /* EMC_TXSRDLL */
2573 0x00000005, /* EMC_TCKE */
2574 0x00000017, /* EMC_TFAW */
2575 0x00000000, /* EMC_TRPAB */
2576 0x00000007, /* EMC_TCLKSTABLE */
2577 0x00000008, /* EMC_TCLKSTOP */
2578 0x000016da, /* EMC_TREFBW */
2579 0x0000000c, /* EMC_QUSE_EXTRA */
2580 0x00000004, /* EMC_FBIO_CFG6 */
2581 0x00000000, /* EMC_ODT_WRITE */
2582 0x00000000, /* EMC_ODT_READ */
2583 0x00005088, /* EMC_FBIO_CFG5 */
2584 0xf0080191, /* EMC_CFG_DIG_DLL */
2585 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2586 0x00000008, /* EMC_DLL_XFORM_DQS0 */
2587 0x00000008, /* EMC_DLL_XFORM_DQS1 */
2588 0x00000008, /* EMC_DLL_XFORM_DQS2 */
2589 0x00000008, /* EMC_DLL_XFORM_DQS3 */
2590 0x00000008, /* EMC_DLL_XFORM_DQS4 */
2591 0x00000008, /* EMC_DLL_XFORM_DQS5 */
2592 0x00000008, /* EMC_DLL_XFORM_DQS6 */
2593 0x00000008, /* EMC_DLL_XFORM_DQS7 */
2594 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2595 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2596 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2597 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2598 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2599 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2600 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2601 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2602 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2603 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2604 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2605 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2606 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2607 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2608 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2609 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2610 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
2611 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
2612 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
2613 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
2614 0x000002a0, /* EMC_XM2CMDPADCTRL */
2615 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
2616 0x22220000, /* EMC_XM2DQPADCTRL2 */
2617 0x77fff884, /* EMC_XM2CLKPADCTRL */
2618 0x01f1f501, /* EMC_XM2COMPPADCTRL */
2619 0x07077404, /* EMC_XM2VTTGENPADCTRL */
2620 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
2621 0x080001e8, /* EMC_XM2QUSEPADCTRL */
2622 0x07000021, /* EMC_XM2DQSPADCTRL3 */
2623 0x00000802, /* EMC_CTT_TERM_CTRL */
2624 0x00020000, /* EMC_ZCAL_INTERVAL */
2625 0x00000100, /* EMC_ZCAL_WAIT_CNT */
2626 0x00df000c, /* EMC_MRS_WAIT_CNT */
2627 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2628 0x00000000, /* EMC_CTT */
2629 0x00000000, /* EMC_CTT_DURATION */
2630 0x80002d93, /* EMC_DYN_SELF_REF_CONTROL */
2631 0x0000000b, /* MC_EMEM_ARB_CFG */
2632 0x80000087, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2633 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
2634 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
2635 0x00000012, /* MC_EMEM_ARB_TIMING_RC */
2636 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
2637 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
2638 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
2639 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2640 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2641 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2642 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
2643 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
2644 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
2645 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
2646 0x00160d12, /* MC_EMEM_ARB_DA_COVERS */
2647 0x73cc2213, /* MC_EMEM_ARB_MISC0 */
2648 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2649 0xf8000000, /* EMC_FBIO_SPARE */
2650 0xff00ff49, /* EMC_CFG_RSV */
2651 },
2652 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2653 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2654 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2655 0x80000d71, /* Mode Register 0 */
2656 0x80100002, /* Mode Register 1 */
2657 0x80200018, /* Mode Register 2 */
2658 0x00000000, /* EMC_CFG.DYN_SELF_REF */
2659 },
2660};
2661
2662static const struct tegra_emc_table cardhu_emc_tables_k4b4g0846b_hyk0[] = {
2663 {
2664 0x32, /* Rev 3.2 */
2665 25500, /* SDRAM frequency */
2666 {
2667 0x00000001, /* EMC_RC */
2668 0x00000006, /* EMC_RFC */
2669 0x00000000, /* EMC_RAS */
2670 0x00000000, /* EMC_RP */
2671 0x00000002, /* EMC_R2W */
2672 0x0000000a, /* EMC_W2R */
2673 0x00000005, /* EMC_R2P */
2674 0x0000000b, /* EMC_W2P */
2675 0x00000000, /* EMC_RD_RCD */
2676 0x00000000, /* EMC_WR_RCD */
2677 0x00000003, /* EMC_RRD */
2678 0x00000001, /* EMC_REXT */
2679 0x00000000, /* EMC_WEXT */
2680 0x00000005, /* EMC_WDV */
2681 0x00000005, /* EMC_QUSE */
2682 0x00000004, /* EMC_QRST */
2683 0x00000009, /* EMC_QSAFE */
2684 0x0000000b, /* EMC_RDV */
2685 0x000000c0, /* EMC_REFRESH */
2686 0x00000000, /* EMC_BURST_REFRESH_NUM */
2687 0x00000030, /* EMC_PRE_REFRESH_REQ_CNT */
2688 0x00000002, /* EMC_PDEX2WR */
2689 0x00000002, /* EMC_PDEX2RD */
2690 0x00000001, /* EMC_PCHG2PDEN */
2691 0x00000000, /* EMC_ACT2PDEN */
2692 0x00000007, /* EMC_AR2PDEN */
2693 0x0000000f, /* EMC_RW2PDEN */
2694 0x00000007, /* EMC_TXSR */
2695 0x00000007, /* EMC_TXSRDLL */
2696 0x00000004, /* EMC_TCKE */
2697 0x00000001, /* EMC_TFAW */
2698 0x00000000, /* EMC_TRPAB */
2699 0x00000004, /* EMC_TCLKSTABLE */
2700 0x00000005, /* EMC_TCLKSTOP */
2701 0x000000c7, /* EMC_TREFBW */
2702 0x00000006, /* EMC_QUSE_EXTRA */
2703 0x00000004, /* EMC_FBIO_CFG6 */
2704 0x00000000, /* EMC_ODT_WRITE */
2705 0x00000000, /* EMC_ODT_READ */
2706 0x00004288, /* EMC_FBIO_CFG5 */
2707 0x007800a4, /* EMC_CFG_DIG_DLL */
2708 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2709 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
2710 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
2711 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
2712 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
2713 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
2714 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
2715 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
2716 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
2717 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2718 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2719 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2720 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2721 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2722 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2723 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2724 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2725 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2726 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2727 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2728 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2729 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2730 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2731 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2732 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2733 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
2734 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
2735 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
2736 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
2737 0x000002a0, /* EMC_XM2CMDPADCTRL */
2738 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
2739 0x00000000, /* EMC_XM2DQPADCTRL2 */
2740 0x77fff884, /* EMC_XM2CLKPADCTRL */
2741 0x01f1f108, /* EMC_XM2COMPPADCTRL */
2742 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2743 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2744 0x08000168, /* EMC_XM2QUSEPADCTRL */
2745 0x08000000, /* EMC_XM2DQSPADCTRL3 */
2746 0x00000802, /* EMC_CTT_TERM_CTRL */
2747 0x00000000, /* EMC_ZCAL_INTERVAL */
2748 0x00000040, /* EMC_ZCAL_WAIT_CNT */
2749 0x000c000c, /* EMC_MRS_WAIT_CNT */
2750 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2751 0x00000000, /* EMC_CTT */
2752 0x00000000, /* EMC_CTT_DURATION */
2753 0x80000287, /* EMC_DYN_SELF_REF_CONTROL */
2754 0x00020001, /* MC_EMEM_ARB_CFG */
2755 0xc0000010, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2756 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2757 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
2758 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
2759 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
2760 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
2761 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
2762 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2763 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2764 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2765 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
2766 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
2767 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
2768 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
2769 0x000a0402, /* MC_EMEM_ARB_DA_COVERS */
2770 0x75830303, /* MC_EMEM_ARB_MISC0 */
2771 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2772 0xe8000000, /* EMC_FBIO_SPARE */
2773 0xff00ff00, /* EMC_CFG_RSV */
2774 },
2775 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2776 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2777 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2778 0x80001221, /* Mode Register 0 */
2779 0x80100003, /* Mode Register 1 */
2780 0x80200008, /* Mode Register 2 */
2781 0x00000001, /* EMC_CFG.DYN_SELF_REF */
2782 },
2783 {
2784 0x32, /* Rev 3.2 */
2785 51000, /* SDRAM frequency */
2786 {
2787 0x00000002, /* EMC_RC */
2788 0x0000000d, /* EMC_RFC */
2789 0x00000001, /* EMC_RAS */
2790 0x00000000, /* EMC_RP */
2791 0x00000002, /* EMC_R2W */
2792 0x0000000a, /* EMC_W2R */
2793 0x00000005, /* EMC_R2P */
2794 0x0000000b, /* EMC_W2P */
2795 0x00000000, /* EMC_RD_RCD */
2796 0x00000000, /* EMC_WR_RCD */
2797 0x00000003, /* EMC_RRD */
2798 0x00000001, /* EMC_REXT */
2799 0x00000000, /* EMC_WEXT */
2800 0x00000005, /* EMC_WDV */
2801 0x00000005, /* EMC_QUSE */
2802 0x00000004, /* EMC_QRST */
2803 0x00000009, /* EMC_QSAFE */
2804 0x0000000b, /* EMC_RDV */
2805 0x00000181, /* EMC_REFRESH */
2806 0x00000000, /* EMC_BURST_REFRESH_NUM */
2807 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
2808 0x00000002, /* EMC_PDEX2WR */
2809 0x00000002, /* EMC_PDEX2RD */
2810 0x00000001, /* EMC_PCHG2PDEN */
2811 0x00000000, /* EMC_ACT2PDEN */
2812 0x00000007, /* EMC_AR2PDEN */
2813 0x0000000f, /* EMC_RW2PDEN */
2814 0x0000000e, /* EMC_TXSR */
2815 0x0000000e, /* EMC_TXSRDLL */
2816 0x00000004, /* EMC_TCKE */
2817 0x00000002, /* EMC_TFAW */
2818 0x00000000, /* EMC_TRPAB */
2819 0x00000004, /* EMC_TCLKSTABLE */
2820 0x00000005, /* EMC_TCLKSTOP */
2821 0x0000018e, /* EMC_TREFBW */
2822 0x00000006, /* EMC_QUSE_EXTRA */
2823 0x00000004, /* EMC_FBIO_CFG6 */
2824 0x00000000, /* EMC_ODT_WRITE */
2825 0x00000000, /* EMC_ODT_READ */
2826 0x00004288, /* EMC_FBIO_CFG5 */
2827 0x007800a4, /* EMC_CFG_DIG_DLL */
2828 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2829 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
2830 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
2831 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
2832 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
2833 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
2834 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
2835 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
2836 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
2837 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2838 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2839 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2840 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2841 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2842 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2843 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2844 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2845 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2846 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2847 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2848 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2849 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2850 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2851 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2852 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2853 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
2854 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
2855 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
2856 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
2857 0x000002a0, /* EMC_XM2CMDPADCTRL */
2858 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
2859 0x00000000, /* EMC_XM2DQPADCTRL2 */
2860 0x77fff884, /* EMC_XM2CLKPADCTRL */
2861 0x01f1f108, /* EMC_XM2COMPPADCTRL */
2862 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2863 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2864 0x08000168, /* EMC_XM2QUSEPADCTRL */
2865 0x08000000, /* EMC_XM2DQSPADCTRL3 */
2866 0x00000802, /* EMC_CTT_TERM_CTRL */
2867 0x00000000, /* EMC_ZCAL_INTERVAL */
2868 0x00000040, /* EMC_ZCAL_WAIT_CNT */
2869 0x000c000c, /* EMC_MRS_WAIT_CNT */
2870 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2871 0x00000000, /* EMC_CTT */
2872 0x00000000, /* EMC_CTT_DURATION */
2873 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
2874 0x00010001, /* MC_EMEM_ARB_CFG */
2875 0xc0000010, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2876 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2877 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
2878 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
2879 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
2880 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
2881 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
2882 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
2883 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
2884 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
2885 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
2886 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
2887 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
2888 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
2889 0x000a0402, /* MC_EMEM_ARB_DA_COVERS */
2890 0x74630303, /* MC_EMEM_ARB_MISC0 */
2891 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
2892 0xe8000000, /* EMC_FBIO_SPARE */
2893 0xff00ff00, /* EMC_CFG_RSV */
2894 },
2895 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
2896 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
2897 0x00000001, /* EMC_CFG.PERIODIC_QRST */
2898 0x80001221, /* Mode Register 0 */
2899 0x80100003, /* Mode Register 1 */
2900 0x80200008, /* Mode Register 2 */
2901 0x00000001, /* EMC_CFG.DYN_SELF_REF */
2902 },
2903 {
2904 0x32, /* Rev 3.2 */
2905 102000, /* SDRAM frequency */
2906 {
2907 0x00000004, /* EMC_RC */
2908 0x0000001a, /* EMC_RFC */
2909 0x00000003, /* EMC_RAS */
2910 0x00000001, /* EMC_RP */
2911 0x00000002, /* EMC_R2W */
2912 0x0000000a, /* EMC_W2R */
2913 0x00000005, /* EMC_R2P */
2914 0x0000000b, /* EMC_W2P */
2915 0x00000001, /* EMC_RD_RCD */
2916 0x00000001, /* EMC_WR_RCD */
2917 0x00000003, /* EMC_RRD */
2918 0x00000001, /* EMC_REXT */
2919 0x00000000, /* EMC_WEXT */
2920 0x00000005, /* EMC_WDV */
2921 0x00000005, /* EMC_QUSE */
2922 0x00000004, /* EMC_QRST */
2923 0x00000009, /* EMC_QSAFE */
2924 0x0000000b, /* EMC_RDV */
2925 0x00000303, /* EMC_REFRESH */
2926 0x00000000, /* EMC_BURST_REFRESH_NUM */
2927 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
2928 0x00000002, /* EMC_PDEX2WR */
2929 0x00000002, /* EMC_PDEX2RD */
2930 0x00000001, /* EMC_PCHG2PDEN */
2931 0x00000000, /* EMC_ACT2PDEN */
2932 0x00000007, /* EMC_AR2PDEN */
2933 0x0000000f, /* EMC_RW2PDEN */
2934 0x0000001c, /* EMC_TXSR */
2935 0x0000001c, /* EMC_TXSRDLL */
2936 0x00000004, /* EMC_TCKE */
2937 0x00000004, /* EMC_TFAW */
2938 0x00000000, /* EMC_TRPAB */
2939 0x00000004, /* EMC_TCLKSTABLE */
2940 0x00000005, /* EMC_TCLKSTOP */
2941 0x0000031c, /* EMC_TREFBW */
2942 0x00000006, /* EMC_QUSE_EXTRA */
2943 0x00000004, /* EMC_FBIO_CFG6 */
2944 0x00000000, /* EMC_ODT_WRITE */
2945 0x00000000, /* EMC_ODT_READ */
2946 0x00004288, /* EMC_FBIO_CFG5 */
2947 0x007800a4, /* EMC_CFG_DIG_DLL */
2948 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
2949 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
2950 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
2951 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
2952 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
2953 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
2954 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
2955 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
2956 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
2957 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
2958 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
2959 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
2960 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
2961 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
2962 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
2963 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
2964 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
2965 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
2966 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
2967 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
2968 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
2969 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
2970 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
2971 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
2972 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
2973 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
2974 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
2975 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
2976 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
2977 0x000002a0, /* EMC_XM2CMDPADCTRL */
2978 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
2979 0x00000000, /* EMC_XM2DQPADCTRL2 */
2980 0x77fff884, /* EMC_XM2CLKPADCTRL */
2981 0x01f1f108, /* EMC_XM2COMPPADCTRL */
2982 0x05057404, /* EMC_XM2VTTGENPADCTRL */
2983 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
2984 0x08000168, /* EMC_XM2QUSEPADCTRL */
2985 0x08000000, /* EMC_XM2DQSPADCTRL3 */
2986 0x00000802, /* EMC_CTT_TERM_CTRL */
2987 0x00000000, /* EMC_ZCAL_INTERVAL */
2988 0x00000040, /* EMC_ZCAL_WAIT_CNT */
2989 0x000c000c, /* EMC_MRS_WAIT_CNT */
2990 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
2991 0x00000000, /* EMC_CTT */
2992 0x00000000, /* EMC_CTT_DURATION */
2993 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
2994 0x00000001, /* MC_EMEM_ARB_CFG */
2995 0xc0000018, /* MC_EMEM_ARB_OUTSTANDING_REQ */
2996 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
2997 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
2998 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
2999 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
3000 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
3001 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3002 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3003 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3004 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
3005 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
3006 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
3007 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
3008 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
3009 0x000a0403, /* MC_EMEM_ARB_DA_COVERS */
3010 0x73c30504, /* MC_EMEM_ARB_MISC0 */
3011 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3012 0xe8000000, /* EMC_FBIO_SPARE */
3013 0xff00ff00, /* EMC_CFG_RSV */
3014 },
3015 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
3016 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3017 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3018 0x80001221, /* Mode Register 0 */
3019 0x80100003, /* Mode Register 1 */
3020 0x80200008, /* Mode Register 2 */
3021 0x00000001, /* EMC_CFG.DYN_SELF_REF */
3022 },
3023 {
3024 0x32, /* Rev 3.2 */
3025 204000, /* SDRAM frequency */
3026 {
3027 0x00000009, /* EMC_RC */
3028 0x00000035, /* EMC_RFC */
3029 0x00000007, /* EMC_RAS */
3030 0x00000002, /* EMC_RP */
3031 0x00000002, /* EMC_R2W */
3032 0x0000000a, /* EMC_W2R */
3033 0x00000005, /* EMC_R2P */
3034 0x0000000b, /* EMC_W2P */
3035 0x00000002, /* EMC_RD_RCD */
3036 0x00000002, /* EMC_WR_RCD */
3037 0x00000003, /* EMC_RRD */
3038 0x00000001, /* EMC_REXT */
3039 0x00000000, /* EMC_WEXT */
3040 0x00000005, /* EMC_WDV */
3041 0x00000005, /* EMC_QUSE */
3042 0x00000004, /* EMC_QRST */
3043 0x00000009, /* EMC_QSAFE */
3044 0x0000000b, /* EMC_RDV */
3045 0x00000607, /* EMC_REFRESH */
3046 0x00000000, /* EMC_BURST_REFRESH_NUM */
3047 0x00000181, /* EMC_PRE_REFRESH_REQ_CNT */
3048 0x00000002, /* EMC_PDEX2WR */
3049 0x00000002, /* EMC_PDEX2RD */
3050 0x00000001, /* EMC_PCHG2PDEN */
3051 0x00000000, /* EMC_ACT2PDEN */
3052 0x00000007, /* EMC_AR2PDEN */
3053 0x0000000f, /* EMC_RW2PDEN */
3054 0x00000038, /* EMC_TXSR */
3055 0x00000038, /* EMC_TXSRDLL */
3056 0x00000004, /* EMC_TCKE */
3057 0x00000007, /* EMC_TFAW */
3058 0x00000000, /* EMC_TRPAB */
3059 0x00000004, /* EMC_TCLKSTABLE */
3060 0x00000005, /* EMC_TCLKSTOP */
3061 0x00000638, /* EMC_TREFBW */
3062 0x00000006, /* EMC_QUSE_EXTRA */
3063 0x00000004, /* EMC_FBIO_CFG6 */
3064 0x00000000, /* EMC_ODT_WRITE */
3065 0x00000000, /* EMC_ODT_READ */
3066 0x00004288, /* EMC_FBIO_CFG5 */
3067 0x004400a4, /* EMC_CFG_DIG_DLL */
3068 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3069 0x00080000, /* EMC_DLL_XFORM_DQS0 */
3070 0x00080000, /* EMC_DLL_XFORM_DQS1 */
3071 0x00080000, /* EMC_DLL_XFORM_DQS2 */
3072 0x00080000, /* EMC_DLL_XFORM_DQS3 */
3073 0x00080000, /* EMC_DLL_XFORM_DQS4 */
3074 0x00080000, /* EMC_DLL_XFORM_DQS5 */
3075 0x00080000, /* EMC_DLL_XFORM_DQS6 */
3076 0x00080000, /* EMC_DLL_XFORM_DQS7 */
3077 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3078 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3079 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3080 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3081 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
3082 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
3083 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
3084 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
3085 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3086 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3087 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3088 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3089 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3090 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3091 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3092 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3093 0x00080000, /* EMC_DLL_XFORM_DQ0 */
3094 0x00080000, /* EMC_DLL_XFORM_DQ1 */
3095 0x00080000, /* EMC_DLL_XFORM_DQ2 */
3096 0x00080000, /* EMC_DLL_XFORM_DQ3 */
3097 0x000002a0, /* EMC_XM2CMDPADCTRL */
3098 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
3099 0x00000000, /* EMC_XM2DQPADCTRL2 */
3100 0x77fff884, /* EMC_XM2CLKPADCTRL */
3101 0x01f1f108, /* EMC_XM2COMPPADCTRL */
3102 0x05057404, /* EMC_XM2VTTGENPADCTRL */
3103 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
3104 0x08000168, /* EMC_XM2QUSEPADCTRL */
3105 0x08000000, /* EMC_XM2DQSPADCTRL3 */
3106 0x00000802, /* EMC_CTT_TERM_CTRL */
3107 0x00020000, /* EMC_ZCAL_INTERVAL */
3108 0x00000100, /* EMC_ZCAL_WAIT_CNT */
3109 0x000c000c, /* EMC_MRS_WAIT_CNT */
3110 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3111 0x00000000, /* EMC_CTT */
3112 0x00000000, /* EMC_CTT_DURATION */
3113 0x80000d22, /* EMC_DYN_SELF_REF_CONTROL */
3114 0x00000003, /* MC_EMEM_ARB_CFG */
3115 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3116 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
3117 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
3118 0x00000005, /* MC_EMEM_ARB_TIMING_RC */
3119 0x00000002, /* MC_EMEM_ARB_TIMING_RAS */
3120 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
3121 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3122 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3123 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3124 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
3125 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
3126 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
3127 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
3128 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
3129 0x000a0405, /* MC_EMEM_ARB_DA_COVERS */
3130 0x73840a06, /* MC_EMEM_ARB_MISC0 */
3131 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3132 0xe8000000, /* EMC_FBIO_SPARE */
3133 0xff00ff00, /* EMC_CFG_RSV */
3134 },
3135 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
3136 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3137 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3138 0x80001221, /* Mode Register 0 */
3139 0x80100003, /* Mode Register 1 */
3140 0x80200008, /* Mode Register 2 */
3141 0x00000001, /* EMC_CFG.DYN_SELF_REF */
3142 },
3143 {
3144 0x32, /* Rev 3.2 */
3145 375000, /* SDRAM frequency */
3146 {
3147 0x00000011, /* EMC_RC */
3148 0x00000060, /* EMC_RFC */
3149 0x0000000c, /* EMC_RAS */
3150 0x00000004, /* EMC_RP */
3151 0x00000003, /* EMC_R2W */
3152 0x00000008, /* EMC_W2R */
3153 0x00000002, /* EMC_R2P */
3154 0x0000000a, /* EMC_W2P */
3155 0x00000004, /* EMC_RD_RCD */
3156 0x00000004, /* EMC_WR_RCD */
3157 0x00000002, /* EMC_RRD */
3158 0x00000001, /* EMC_REXT */
3159 0x00000000, /* EMC_WEXT */
3160 0x00000004, /* EMC_WDV */
3161 0x00000006, /* EMC_QUSE */
3162 0x00000004, /* EMC_QRST */
3163 0x0000000a, /* EMC_QSAFE */
3164 0x0000000d, /* EMC_RDV */
3165 0x00000b2d, /* EMC_REFRESH */
3166 0x00000000, /* EMC_BURST_REFRESH_NUM */
3167 0x000002cb, /* EMC_PRE_REFRESH_REQ_CNT */
3168 0x00000001, /* EMC_PDEX2WR */
3169 0x00000008, /* EMC_PDEX2RD */
3170 0x00000001, /* EMC_PCHG2PDEN */
3171 0x00000000, /* EMC_ACT2PDEN */
3172 0x00000007, /* EMC_AR2PDEN */
3173 0x0000000f, /* EMC_RW2PDEN */
3174 0x00000066, /* EMC_TXSR */
3175 0x00000200, /* EMC_TXSRDLL */
3176 0x00000004, /* EMC_TCKE */
3177 0x0000000c, /* EMC_TFAW */
3178 0x00000000, /* EMC_TRPAB */
3179 0x00000004, /* EMC_TCLKSTABLE */
3180 0x00000005, /* EMC_TCLKSTOP */
3181 0x00000b6d, /* EMC_TREFBW */
3182 0x00000000, /* EMC_QUSE_EXTRA */
3183 0x00000006, /* EMC_FBIO_CFG6 */
3184 0x00000000, /* EMC_ODT_WRITE */
3185 0x00000000, /* EMC_ODT_READ */
3186 0x00007088, /* EMC_FBIO_CFG5 */
3187 0x00200084, /* EMC_CFG_DIG_DLL */
3188 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3189 0x00014000, /* EMC_DLL_XFORM_DQS0 */
3190 0x00014000, /* EMC_DLL_XFORM_DQS1 */
3191 0x00014000, /* EMC_DLL_XFORM_DQS2 */
3192 0x00014000, /* EMC_DLL_XFORM_DQS3 */
3193 0x00014000, /* EMC_DLL_XFORM_DQS4 */
3194 0x00014000, /* EMC_DLL_XFORM_DQS5 */
3195 0x00014000, /* EMC_DLL_XFORM_DQS6 */
3196 0x00014000, /* EMC_DLL_XFORM_DQS7 */
3197 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3198 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3199 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3200 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3201 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
3202 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
3203 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
3204 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
3205 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3206 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3207 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3208 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3209 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3210 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3211 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3212 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3213 0x00020000, /* EMC_DLL_XFORM_DQ0 */
3214 0x00020000, /* EMC_DLL_XFORM_DQ1 */
3215 0x00020000, /* EMC_DLL_XFORM_DQ2 */
3216 0x00020000, /* EMC_DLL_XFORM_DQ3 */
3217 0x000002a0, /* EMC_XM2CMDPADCTRL */
3218 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
3219 0x00000000, /* EMC_XM2DQPADCTRL2 */
3220 0x77fff884, /* EMC_XM2CLKPADCTRL */
3221 0x01f1f508, /* EMC_XM2COMPPADCTRL */
3222 0x05057404, /* EMC_XM2VTTGENPADCTRL */
3223 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
3224 0x080001e8, /* EMC_XM2QUSEPADCTRL */
3225 0x08000021, /* EMC_XM2DQSPADCTRL3 */
3226 0x00000802, /* EMC_CTT_TERM_CTRL */
3227 0x00020000, /* EMC_ZCAL_INTERVAL */
3228 0x00000100, /* EMC_ZCAL_WAIT_CNT */
3229 0x015f000c, /* EMC_MRS_WAIT_CNT */
3230 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3231 0x00000000, /* EMC_CTT */
3232 0x00000000, /* EMC_CTT_DURATION */
3233 0x8000174b, /* EMC_DYN_SELF_REF_CONTROL */
3234 0x00000005, /* MC_EMEM_ARB_CFG */
3235 0x80000044, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3236 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
3237 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
3238 0x00000009, /* MC_EMEM_ARB_TIMING_RC */
3239 0x00000005, /* MC_EMEM_ARB_TIMING_RAS */
3240 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
3241 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3242 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3243 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3244 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
3245 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
3246 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
3247 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
3248 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
3249 0x000d0709, /* MC_EMEM_ARB_DA_COVERS */
3250 0x7086110a, /* MC_EMEM_ARB_MISC0 */
3251 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3252 0x58000000, /* EMC_FBIO_SPARE */
3253 0xff00ff88, /* EMC_CFG_RSV */
3254 },
3255 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
3256 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3257 0x00000000, /* EMC_CFG.PERIODIC_QRST */
3258 0x80000521, /* Mode Register 0 */
3259 0x80100002, /* Mode Register 1 */
3260 0x80200000, /* Mode Register 2 */
3261 0x00000000, /* EMC_CFG.DYN_SELF_REF */
3262 },
3263 {
3264 0x32, /* Rev 3.2 */
3265 400000, /* SDRAM frequency */
3266 {
3267 0x00000012, /* EMC_RC */
3268 0x00000066, /* EMC_RFC */
3269 0x0000000c, /* EMC_RAS */
3270 0x00000004, /* EMC_RP */
3271 0x00000003, /* EMC_R2W */
3272 0x00000008, /* EMC_W2R */
3273 0x00000002, /* EMC_R2P */
3274 0x0000000a, /* EMC_W2P */
3275 0x00000004, /* EMC_RD_RCD */
3276 0x00000004, /* EMC_WR_RCD */
3277 0x00000002, /* EMC_RRD */
3278 0x00000001, /* EMC_REXT */
3279 0x00000000, /* EMC_WEXT */
3280 0x00000004, /* EMC_WDV */
3281 0x00000006, /* EMC_QUSE */
3282 0x00000004, /* EMC_QRST */
3283 0x0000000a, /* EMC_QSAFE */
3284 0x0000000c, /* EMC_RDV */
3285 0x00000bf0, /* EMC_REFRESH */
3286 0x00000000, /* EMC_BURST_REFRESH_NUM */
3287 0x000002fc, /* EMC_PRE_REFRESH_REQ_CNT */
3288 0x00000001, /* EMC_PDEX2WR */
3289 0x00000008, /* EMC_PDEX2RD */
3290 0x00000001, /* EMC_PCHG2PDEN */
3291 0x00000000, /* EMC_ACT2PDEN */
3292 0x00000008, /* EMC_AR2PDEN */
3293 0x0000000f, /* EMC_RW2PDEN */
3294 0x0000006c, /* EMC_TXSR */
3295 0x00000200, /* EMC_TXSRDLL */
3296 0x00000004, /* EMC_TCKE */
3297 0x0000000c, /* EMC_TFAW */
3298 0x00000000, /* EMC_TRPAB */
3299 0x00000004, /* EMC_TCLKSTABLE */
3300 0x00000005, /* EMC_TCLKSTOP */
3301 0x00000c30, /* EMC_TREFBW */
3302 0x00000000, /* EMC_QUSE_EXTRA */
3303 0x00000006, /* EMC_FBIO_CFG6 */
3304 0x00000000, /* EMC_ODT_WRITE */
3305 0x00000000, /* EMC_ODT_READ */
3306 0x00007088, /* EMC_FBIO_CFG5 */
3307 0x001d0084, /* EMC_CFG_DIG_DLL */
3308 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3309 0x00034000, /* EMC_DLL_XFORM_DQS0 */
3310 0x00034000, /* EMC_DLL_XFORM_DQS1 */
3311 0x00034000, /* EMC_DLL_XFORM_DQS2 */
3312 0x00034000, /* EMC_DLL_XFORM_DQS3 */
3313 0x00034000, /* EMC_DLL_XFORM_DQS4 */
3314 0x00034000, /* EMC_DLL_XFORM_DQS5 */
3315 0x00034000, /* EMC_DLL_XFORM_DQS6 */
3316 0x00034000, /* EMC_DLL_XFORM_DQS7 */
3317 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3318 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3319 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3320 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3321 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
3322 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
3323 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
3324 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
3325 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3326 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3327 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3328 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3329 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3330 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3331 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3332 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3333 0x00040000, /* EMC_DLL_XFORM_DQ0 */
3334 0x00040000, /* EMC_DLL_XFORM_DQ1 */
3335 0x00040000, /* EMC_DLL_XFORM_DQ2 */
3336 0x00040000, /* EMC_DLL_XFORM_DQ3 */
3337 0x000002a0, /* EMC_XM2CMDPADCTRL */
3338 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
3339 0x00000000, /* EMC_XM2DQPADCTRL2 */
3340 0x77fff884, /* EMC_XM2CLKPADCTRL */
3341 0x01f1f508, /* EMC_XM2COMPPADCTRL */
3342 0x05057404, /* EMC_XM2VTTGENPADCTRL */
3343 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
3344 0x080001e8, /* EMC_XM2QUSEPADCTRL */
3345 0x08000021, /* EMC_XM2DQSPADCTRL3 */
3346 0x00000802, /* EMC_CTT_TERM_CTRL */
3347 0x00020000, /* EMC_ZCAL_INTERVAL */
3348 0x00000100, /* EMC_ZCAL_WAIT_CNT */
3349 0x0158000c, /* EMC_MRS_WAIT_CNT */
3350 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3351 0x00000000, /* EMC_CTT */
3352 0x00000000, /* EMC_CTT_DURATION */
3353 0x800018c8, /* EMC_DYN_SELF_REF_CONTROL */
3354 0x00000006, /* MC_EMEM_ARB_CFG */
3355 0x80000048, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3356 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
3357 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
3358 0x00000009, /* MC_EMEM_ARB_TIMING_RC */
3359 0x00000005, /* MC_EMEM_ARB_TIMING_RAS */
3360 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
3361 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3362 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3363 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3364 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
3365 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
3366 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
3367 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
3368 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
3369 0x000d0709, /* MC_EMEM_ARB_DA_COVERS */
3370 0x7566120a, /* MC_EMEM_ARB_MISC0 */
3371 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3372 0xe8000000, /* EMC_FBIO_SPARE */
3373 0xff00ff89, /* EMC_CFG_RSV */
3374 },
3375 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
3376 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3377 0x00000000, /* EMC_CFG.PERIODIC_QRST */
3378 0x80000521, /* Mode Register 0 */
3379 0x80100002, /* Mode Register 1 */
3380 0x80200000, /* Mode Register 2 */
3381 0x00000000, /* EMC_CFG.DYN_SELF_REF */
3382 },
3383 {
3384 0x32, /* Rev 3.2 */
3385 750000, /* SDRAM frequency */
3386 {
3387 0x00000023, /* EMC_RC */
3388 0x000000c1, /* EMC_RFC */
3389 0x00000019, /* EMC_RAS */
3390 0x00000009, /* EMC_RP */
3391 0x00000005, /* EMC_R2W */
3392 0x0000000d, /* EMC_W2R */
3393 0x00000004, /* EMC_R2P */
3394 0x00000013, /* EMC_W2P */
3395 0x00000009, /* EMC_RD_RCD */
3396 0x00000009, /* EMC_WR_RCD */
3397 0x00000003, /* EMC_RRD */
3398 0x00000001, /* EMC_REXT */
3399 0x00000000, /* EMC_WEXT */
3400 0x00000007, /* EMC_WDV */
3401 0x0000000b, /* EMC_QUSE */
3402 0x00000009, /* EMC_QRST */
3403 0x0000000c, /* EMC_QSAFE */
3404 0x00000011, /* EMC_RDV */
3405 0x0000169a, /* EMC_REFRESH */
3406 0x00000000, /* EMC_BURST_REFRESH_NUM */
3407 0x000005a6, /* EMC_PRE_REFRESH_REQ_CNT */
3408 0x00000003, /* EMC_PDEX2WR */
3409 0x00000010, /* EMC_PDEX2RD */
3410 0x00000001, /* EMC_PCHG2PDEN */
3411 0x00000000, /* EMC_ACT2PDEN */
3412 0x0000000e, /* EMC_AR2PDEN */
3413 0x00000018, /* EMC_RW2PDEN */
3414 0x000000cb, /* EMC_TXSR */
3415 0x00000200, /* EMC_TXSRDLL */
3416 0x00000005, /* EMC_TCKE */
3417 0x00000017, /* EMC_TFAW */
3418 0x00000000, /* EMC_TRPAB */
3419 0x00000007, /* EMC_TCLKSTABLE */
3420 0x00000008, /* EMC_TCLKSTOP */
3421 0x000016da, /* EMC_TREFBW */
3422 0x0000000c, /* EMC_QUSE_EXTRA */
3423 0x00000004, /* EMC_FBIO_CFG6 */
3424 0x00000000, /* EMC_ODT_WRITE */
3425 0x00000000, /* EMC_ODT_READ */
3426 0x00005088, /* EMC_FBIO_CFG5 */
3427 0xf0080191, /* EMC_CFG_DIG_DLL */
3428 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3429 0x00000008, /* EMC_DLL_XFORM_DQS0 */
3430 0x00000008, /* EMC_DLL_XFORM_DQS1 */
3431 0x00000008, /* EMC_DLL_XFORM_DQS2 */
3432 0x00000008, /* EMC_DLL_XFORM_DQS3 */
3433 0x00000008, /* EMC_DLL_XFORM_DQS4 */
3434 0x00000008, /* EMC_DLL_XFORM_DQS5 */
3435 0x00000008, /* EMC_DLL_XFORM_DQS6 */
3436 0x00000008, /* EMC_DLL_XFORM_DQS7 */
3437 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3438 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3439 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3440 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3441 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
3442 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
3443 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
3444 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
3445 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3446 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3447 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3448 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3449 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3450 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3451 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3452 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3453 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
3454 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
3455 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
3456 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
3457 0x000002a0, /* EMC_XM2CMDPADCTRL */
3458 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
3459 0x22220000, /* EMC_XM2DQPADCTRL2 */
3460 0x77fff884, /* EMC_XM2CLKPADCTRL */
3461 0x01f1f501, /* EMC_XM2COMPPADCTRL */
3462 0x07077404, /* EMC_XM2VTTGENPADCTRL */
3463 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
3464 0x080001e8, /* EMC_XM2QUSEPADCTRL */
3465 0x08000021, /* EMC_XM2DQSPADCTRL3 */
3466 0x00000802, /* EMC_CTT_TERM_CTRL */
3467 0x00020000, /* EMC_ZCAL_INTERVAL */
3468 0x00000100, /* EMC_ZCAL_WAIT_CNT */
3469 0x00fd000c, /* EMC_MRS_WAIT_CNT */
3470 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3471 0x00000000, /* EMC_CTT */
3472 0x00000000, /* EMC_CTT_DURATION */
3473 0x80002d93, /* EMC_DYN_SELF_REF_CONTROL */
3474 0x0000000b, /* MC_EMEM_ARB_CFG */
3475 0x80000087, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3476 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
3477 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
3478 0x00000012, /* MC_EMEM_ARB_TIMING_RC */
3479 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
3480 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
3481 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
3482 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3483 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3484 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
3485 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
3486 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
3487 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
3488 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
3489 0x00160d12, /* MC_EMEM_ARB_DA_COVERS */
3490 0x710c2213, /* MC_EMEM_ARB_MISC0 */
3491 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3492 0xf8000000, /* EMC_FBIO_SPARE */
3493 0xff00ff49, /* EMC_CFG_RSV */
3494 },
3495 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
3496 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3497 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3498 0x80000d71, /* Mode Register 0 */
3499 0x80100002, /* Mode Register 1 */
3500 0x80200018, /* Mode Register 2 */
3501 0x00000000, /* EMC_CFG.DYN_SELF_REF */
3502 },
3503 {
3504 0x32, /* Rev 3.2 */
3505 800000, /* SDRAM frequency */
3506 {
3507 0x00000025, /* EMC_RC */
3508 0x000000ce, /* EMC_RFC */
3509 0x0000001a, /* EMC_RAS */
3510 0x00000009, /* EMC_RP */
3511 0x00000005, /* EMC_R2W */
3512 0x0000000d, /* EMC_W2R */
3513 0x00000004, /* EMC_R2P */
3514 0x00000013, /* EMC_W2P */
3515 0x00000009, /* EMC_RD_RCD */
3516 0x00000009, /* EMC_WR_RCD */
3517 0x00000003, /* EMC_RRD */
3518 0x00000001, /* EMC_REXT */
3519 0x00000000, /* EMC_WEXT */
3520 0x00000007, /* EMC_WDV */
3521 0x0000000b, /* EMC_QUSE */
3522 0x00000009, /* EMC_QRST */
3523 0x0000000b, /* EMC_QSAFE */
3524 0x00000011, /* EMC_RDV */
3525 0x00001820, /* EMC_REFRESH */
3526 0x00000000, /* EMC_BURST_REFRESH_NUM */
3527 0x00000608, /* EMC_PRE_REFRESH_REQ_CNT */
3528 0x00000003, /* EMC_PDEX2WR */
3529 0x00000012, /* EMC_PDEX2RD */
3530 0x00000001, /* EMC_PCHG2PDEN */
3531 0x00000000, /* EMC_ACT2PDEN */
3532 0x0000000f, /* EMC_AR2PDEN */
3533 0x00000018, /* EMC_RW2PDEN */
3534 0x000000d8, /* EMC_TXSR */
3535 0x00000200, /* EMC_TXSRDLL */
3536 0x00000005, /* EMC_TCKE */
3537 0x00000018, /* EMC_TFAW */
3538 0x00000000, /* EMC_TRPAB */
3539 0x00000007, /* EMC_TCLKSTABLE */
3540 0x00000008, /* EMC_TCLKSTOP */
3541 0x00001860, /* EMC_TREFBW */
3542 0x0000000c, /* EMC_QUSE_EXTRA */
3543 0x00000004, /* EMC_FBIO_CFG6 */
3544 0x00000000, /* EMC_ODT_WRITE */
3545 0x00000000, /* EMC_ODT_READ */
3546 0x00005088, /* EMC_FBIO_CFG5 */
3547 0xf0070191, /* EMC_CFG_DIG_DLL */
3548 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3549 0x0000800a, /* EMC_DLL_XFORM_DQS0 */
3550 0x0000800a, /* EMC_DLL_XFORM_DQS1 */
3551 0x0000800a, /* EMC_DLL_XFORM_DQS2 */
3552 0x0000800a, /* EMC_DLL_XFORM_DQS3 */
3553 0x0000800a, /* EMC_DLL_XFORM_DQS4 */
3554 0x0000800a, /* EMC_DLL_XFORM_DQS5 */
3555 0x0000800a, /* EMC_DLL_XFORM_DQS6 */
3556 0x0000800a, /* EMC_DLL_XFORM_DQS7 */
3557 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3558 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3559 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3560 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3561 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
3562 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
3563 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
3564 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
3565 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3566 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3567 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3568 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3569 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3570 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3571 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3572 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3573 0x0000000a, /* EMC_DLL_XFORM_DQ0 */
3574 0x0000000a, /* EMC_DLL_XFORM_DQ1 */
3575 0x0000000a, /* EMC_DLL_XFORM_DQ2 */
3576 0x0000000a, /* EMC_DLL_XFORM_DQ3 */
3577 0x000002a0, /* EMC_XM2CMDPADCTRL */
3578 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
3579 0x22220000, /* EMC_XM2DQPADCTRL2 */
3580 0x77fff884, /* EMC_XM2CLKPADCTRL */
3581 0x01f1f501, /* EMC_XM2COMPPADCTRL */
3582 0x07077404, /* EMC_XM2VTTGENPADCTRL */
3583 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
3584 0x080001e8, /* EMC_XM2QUSEPADCTRL */
3585 0x09000021, /* EMC_XM2DQSPADCTRL3 */
3586 0x00000802, /* EMC_CTT_TERM_CTRL */
3587 0x00020000, /* EMC_ZCAL_INTERVAL */
3588 0x00000100, /* EMC_ZCAL_WAIT_CNT */
3589 0x00f0000c, /* EMC_MRS_WAIT_CNT */
3590 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3591 0x00000000, /* EMC_CTT */
3592 0x00000000, /* EMC_CTT_DURATION */
3593 0x8000308c, /* EMC_DYN_SELF_REF_CONTROL */
3594 0x0000000c, /* MC_EMEM_ARB_CFG */
3595 0x80000090, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3596 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
3597 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
3598 0x00000013, /* MC_EMEM_ARB_TIMING_RC */
3599 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
3600 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
3601 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
3602 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3603 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3604 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
3605 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
3606 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
3607 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
3608 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
3609 0x00160d13, /* MC_EMEM_ARB_DA_COVERS */
3610 0x734c2414, /* MC_EMEM_ARB_MISC0 */
3611 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3612 0xf8000000, /* EMC_FBIO_SPARE */
3613 0xff00ff49, /* EMC_CFG_RSV */
3614 },
3615 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
3616 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3617 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3618 0x80000d71, /* Mode Register 0 */
3619 0x80100002, /* Mode Register 1 */
3620 0x80200018, /* Mode Register 2 */
3621 0x00000000, /* EMC_CFG.DYN_SELF_REF */
3622 },
3623};
3624
3625static const struct tegra_emc_table cardhu_emc_tables_k4p8g304eb[] = {
3626 {
3627 0x32, /* Rev 3.2 */
3628 25500, /* SDRAM frequency */
3629 {
3630 0x00000001, /* EMC_RC */
3631 0x00000003, /* EMC_RFC */
3632 0x00000002, /* EMC_RAS */
3633 0x00000002, /* EMC_RP */
3634 0x00000004, /* EMC_R2W */
3635 0x00000004, /* EMC_W2R */
3636 0x00000001, /* EMC_R2P */
3637 0x00000005, /* EMC_W2P */
3638 0x00000002, /* EMC_RD_RCD */
3639 0x00000002, /* EMC_WR_RCD */
3640 0x00000001, /* EMC_RRD */
3641 0x00000001, /* EMC_REXT */
3642 0x00000000, /* EMC_WEXT */
3643 0x00000001, /* EMC_WDV */
3644 0x00000003, /* EMC_QUSE */
3645 0x00000001, /* EMC_QRST */
3646 0x00000009, /* EMC_QSAFE */
3647 0x0000000a, /* EMC_RDV */
3648 0x0000005e, /* EMC_REFRESH */
3649 0x00000000, /* EMC_BURST_REFRESH_NUM */
3650 0x00000017, /* EMC_PRE_REFRESH_REQ_CNT */
3651 0x00000001, /* EMC_PDEX2WR */
3652 0x00000001, /* EMC_PDEX2RD */
3653 0x00000002, /* EMC_PCHG2PDEN */
3654 0x00000000, /* EMC_ACT2PDEN */
3655 0x00000001, /* EMC_AR2PDEN */
3656 0x00000007, /* EMC_RW2PDEN */
3657 0x00000004, /* EMC_TXSR */
3658 0x00000004, /* EMC_TXSRDLL */
3659 0x00000003, /* EMC_TCKE */
3660 0x00000008, /* EMC_TFAW */
3661 0x00000004, /* EMC_TRPAB */
3662 0x00000004, /* EMC_TCLKSTABLE */
3663 0x00000002, /* EMC_TCLKSTOP */
3664 0x00000068, /* EMC_TREFBW */
3665 0x00000004, /* EMC_QUSE_EXTRA */
3666 0x00000004, /* EMC_FBIO_CFG6 */
3667 0x00000000, /* EMC_ODT_WRITE */
3668 0x00000000, /* EMC_ODT_READ */
3669 0x00004282, /* EMC_FBIO_CFG5 */
3670 0x007800a4, /* EMC_CFG_DIG_DLL */
3671 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3672 0x00098000, /* EMC_DLL_XFORM_DQS0 */
3673 0x00098000, /* EMC_DLL_XFORM_DQS1 */
3674 0x00098000, /* EMC_DLL_XFORM_DQS2 */
3675 0x00098000, /* EMC_DLL_XFORM_DQS3 */
3676 0x00000010, /* EMC_DLL_XFORM_DQS4 */
3677 0x00000010, /* EMC_DLL_XFORM_DQS5 */
3678 0x00000010, /* EMC_DLL_XFORM_DQS6 */
3679 0x00000010, /* EMC_DLL_XFORM_DQS7 */
3680 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3681 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3682 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3683 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3684 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
3685 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
3686 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
3687 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
3688 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3689 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3690 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3691 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3692 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3693 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3694 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3695 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3696 0x00080000, /* EMC_DLL_XFORM_DQ0 */
3697 0x00080000, /* EMC_DLL_XFORM_DQ1 */
3698 0x00080000, /* EMC_DLL_XFORM_DQ2 */
3699 0x00080000, /* EMC_DLL_XFORM_DQ3 */
3700 0x00100220, /* EMC_XM2CMDPADCTRL */
3701 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
3702 0x00000000, /* EMC_XM2DQPADCTRL2 */
3703 0x77ffc004, /* EMC_XM2CLKPADCTRL */
3704 0x01f1f008, /* EMC_XM2COMPPADCTRL */
3705 0x00000000, /* EMC_XM2VTTGENPADCTRL */
3706 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
3707 0x08000068, /* EMC_XM2QUSEPADCTRL */
3708 0x08000000, /* EMC_XM2DQSPADCTRL3 */
3709 0x00000802, /* EMC_CTT_TERM_CTRL */
3710 0x00064000, /* EMC_ZCAL_INTERVAL */
3711 0x0000000a, /* EMC_ZCAL_WAIT_CNT */
3712 0x00090009, /* EMC_MRS_WAIT_CNT */
3713 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3714 0x00000000, /* EMC_CTT */
3715 0x00000000, /* EMC_CTT_DURATION */
3716 0x800001c2, /* EMC_DYN_SELF_REF_CONTROL */
3717 0x00020001, /* MC_EMEM_ARB_CFG */
3718 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3719 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
3720 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
3721 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
3722 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
3723 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
3724 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3725 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3726 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3727 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
3728 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
3729 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
3730 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
3731 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
3732 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
3733 0x74030303, /* MC_EMEM_ARB_MISC0 */
3734 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3735 0x50000000, /* EMC_FBIO_SPARE */
3736 0xff00ff00, /* EMC_CFG_RSV */
3737 },
3738 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
3739 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3740 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3741 0x00000000, /* Mode Register 0 */
3742 0x00010022, /* Mode Register 1 */
3743 0x00020001, /* Mode Register 2 */
3744 0x00000001, /* EMC_CFG.DYN_SELF_REF */
3745 },
3746 {
3747 0x32, /* Rev 3.2 */
3748 51000, /* SDRAM frequency */
3749 {
3750 0x00000003, /* EMC_RC */
3751 0x00000006, /* EMC_RFC */
3752 0x00000002, /* EMC_RAS */
3753 0x00000002, /* EMC_RP */
3754 0x00000004, /* EMC_R2W */
3755 0x00000004, /* EMC_W2R */
3756 0x00000001, /* EMC_R2P */
3757 0x00000005, /* EMC_W2P */
3758 0x00000002, /* EMC_RD_RCD */
3759 0x00000002, /* EMC_WR_RCD */
3760 0x00000001, /* EMC_RRD */
3761 0x00000001, /* EMC_REXT */
3762 0x00000000, /* EMC_WEXT */
3763 0x00000001, /* EMC_WDV */
3764 0x00000003, /* EMC_QUSE */
3765 0x00000001, /* EMC_QRST */
3766 0x00000009, /* EMC_QSAFE */
3767 0x0000000a, /* EMC_RDV */
3768 0x000000c0, /* EMC_REFRESH */
3769 0x00000000, /* EMC_BURST_REFRESH_NUM */
3770 0x00000030, /* EMC_PRE_REFRESH_REQ_CNT */
3771 0x00000001, /* EMC_PDEX2WR */
3772 0x00000001, /* EMC_PDEX2RD */
3773 0x00000002, /* EMC_PCHG2PDEN */
3774 0x00000000, /* EMC_ACT2PDEN */
3775 0x00000001, /* EMC_AR2PDEN */
3776 0x00000007, /* EMC_RW2PDEN */
3777 0x00000008, /* EMC_TXSR */
3778 0x00000008, /* EMC_TXSRDLL */
3779 0x00000003, /* EMC_TCKE */
3780 0x00000008, /* EMC_TFAW */
3781 0x00000004, /* EMC_TRPAB */
3782 0x00000004, /* EMC_TCLKSTABLE */
3783 0x00000002, /* EMC_TCLKSTOP */
3784 0x000000d5, /* EMC_TREFBW */
3785 0x00000004, /* EMC_QUSE_EXTRA */
3786 0x00000004, /* EMC_FBIO_CFG6 */
3787 0x00000000, /* EMC_ODT_WRITE */
3788 0x00000000, /* EMC_ODT_READ */
3789 0x00004282, /* EMC_FBIO_CFG5 */
3790 0x007800a4, /* EMC_CFG_DIG_DLL */
3791 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3792 0x000a0000, /* EMC_DLL_XFORM_DQS0 */
3793 0x000a0000, /* EMC_DLL_XFORM_DQS1 */
3794 0x000a0000, /* EMC_DLL_XFORM_DQS2 */
3795 0x000a0000, /* EMC_DLL_XFORM_DQS3 */
3796 0x00000010, /* EMC_DLL_XFORM_DQS4 */
3797 0x00000010, /* EMC_DLL_XFORM_DQS5 */
3798 0x00000010, /* EMC_DLL_XFORM_DQS6 */
3799 0x00000010, /* EMC_DLL_XFORM_DQS7 */
3800 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3801 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3802 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3803 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3804 0x00000018, /* EMC_DLL_XFORM_QUSE4 */
3805 0x00000018, /* EMC_DLL_XFORM_QUSE5 */
3806 0x00000018, /* EMC_DLL_XFORM_QUSE6 */
3807 0x00000018, /* EMC_DLL_XFORM_QUSE7 */
3808 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3809 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3810 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3811 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3812 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3813 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3814 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3815 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3816 0x00080000, /* EMC_DLL_XFORM_DQ0 */
3817 0x00080000, /* EMC_DLL_XFORM_DQ1 */
3818 0x00080000, /* EMC_DLL_XFORM_DQ2 */
3819 0x00080000, /* EMC_DLL_XFORM_DQ3 */
3820 0x00100220, /* EMC_XM2CMDPADCTRL */
3821 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
3822 0x00000000, /* EMC_XM2DQPADCTRL2 */
3823 0x77ffc004, /* EMC_XM2CLKPADCTRL */
3824 0x01f1f008, /* EMC_XM2COMPPADCTRL */
3825 0x00000000, /* EMC_XM2VTTGENPADCTRL */
3826 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
3827 0x08000068, /* EMC_XM2QUSEPADCTRL */
3828 0x08000000, /* EMC_XM2DQSPADCTRL3 */
3829 0x00000802, /* EMC_CTT_TERM_CTRL */
3830 0x00064000, /* EMC_ZCAL_INTERVAL */
3831 0x00000013, /* EMC_ZCAL_WAIT_CNT */
3832 0x00090009, /* EMC_MRS_WAIT_CNT */
3833 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3834 0x00000000, /* EMC_CTT */
3835 0x00000000, /* EMC_CTT_DURATION */
3836 0x80000287, /* EMC_DYN_SELF_REF_CONTROL */
3837 0x00010001, /* MC_EMEM_ARB_CFG */
3838 0xc000000a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3839 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
3840 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
3841 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
3842 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
3843 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
3844 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3845 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3846 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3847 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
3848 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
3849 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
3850 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
3851 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
3852 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
3853 0x72c30303, /* MC_EMEM_ARB_MISC0 */
3854 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3855 0x50000000, /* EMC_FBIO_SPARE */
3856 0xff00ff00, /* EMC_CFG_RSV */
3857 },
3858 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
3859 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3860 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3861 0x00000000, /* Mode Register 0 */
3862 0x00010022, /* Mode Register 1 */
3863 0x00020001, /* Mode Register 2 */
3864 0x00000001, /* EMC_CFG.DYN_SELF_REF */
3865 },
3866 {
3867 0x32, /* Rev 3.2 */
3868 102000, /* SDRAM frequency */
3869 {
3870 0x00000006, /* EMC_RC */
3871 0x0000000d, /* EMC_RFC */
3872 0x00000004, /* EMC_RAS */
3873 0x00000002, /* EMC_RP */
3874 0x00000004, /* EMC_R2W */
3875 0x00000004, /* EMC_W2R */
3876 0x00000001, /* EMC_R2P */
3877 0x00000005, /* EMC_W2P */
3878 0x00000002, /* EMC_RD_RCD */
3879 0x00000002, /* EMC_WR_RCD */
3880 0x00000001, /* EMC_RRD */
3881 0x00000001, /* EMC_REXT */
3882 0x00000000, /* EMC_WEXT */
3883 0x00000001, /* EMC_WDV */
3884 0x00000003, /* EMC_QUSE */
3885 0x00000001, /* EMC_QRST */
3886 0x00000009, /* EMC_QSAFE */
3887 0x00000009, /* EMC_RDV */
3888 0x00000181, /* EMC_REFRESH */
3889 0x00000000, /* EMC_BURST_REFRESH_NUM */
3890 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
3891 0x00000001, /* EMC_PDEX2WR */
3892 0x00000001, /* EMC_PDEX2RD */
3893 0x00000002, /* EMC_PCHG2PDEN */
3894 0x00000000, /* EMC_ACT2PDEN */
3895 0x00000001, /* EMC_AR2PDEN */
3896 0x00000007, /* EMC_RW2PDEN */
3897 0x0000000f, /* EMC_TXSR */
3898 0x0000000f, /* EMC_TXSRDLL */
3899 0x00000003, /* EMC_TCKE */
3900 0x00000008, /* EMC_TFAW */
3901 0x00000004, /* EMC_TRPAB */
3902 0x00000004, /* EMC_TCLKSTABLE */
3903 0x00000002, /* EMC_TCLKSTOP */
3904 0x000001a9, /* EMC_TREFBW */
3905 0x00000004, /* EMC_QUSE_EXTRA */
3906 0x00000004, /* EMC_FBIO_CFG6 */
3907 0x00000000, /* EMC_ODT_WRITE */
3908 0x00000000, /* EMC_ODT_READ */
3909 0x00004282, /* EMC_FBIO_CFG5 */
3910 0x007800a4, /* EMC_CFG_DIG_DLL */
3911 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
3912 0x000a0000, /* EMC_DLL_XFORM_DQS0 */
3913 0x000a0000, /* EMC_DLL_XFORM_DQS1 */
3914 0x000a0000, /* EMC_DLL_XFORM_DQS2 */
3915 0x000a0000, /* EMC_DLL_XFORM_DQS3 */
3916 0x00000010, /* EMC_DLL_XFORM_DQS4 */
3917 0x00000010, /* EMC_DLL_XFORM_DQS5 */
3918 0x00000010, /* EMC_DLL_XFORM_DQS6 */
3919 0x00000010, /* EMC_DLL_XFORM_DQS7 */
3920 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
3921 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
3922 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
3923 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
3924 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
3925 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
3926 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
3927 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
3928 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
3929 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
3930 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
3931 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
3932 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
3933 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
3934 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
3935 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
3936 0x00080000, /* EMC_DLL_XFORM_DQ0 */
3937 0x00080000, /* EMC_DLL_XFORM_DQ1 */
3938 0x00080000, /* EMC_DLL_XFORM_DQ2 */
3939 0x00080000, /* EMC_DLL_XFORM_DQ3 */
3940 0x00120220, /* EMC_XM2CMDPADCTRL */
3941 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
3942 0x00000000, /* EMC_XM2DQPADCTRL2 */
3943 0x77ffc004, /* EMC_XM2CLKPADCTRL */
3944 0x01f1f008, /* EMC_XM2COMPPADCTRL */
3945 0x00000000, /* EMC_XM2VTTGENPADCTRL */
3946 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
3947 0x08000068, /* EMC_XM2QUSEPADCTRL */
3948 0x08000000, /* EMC_XM2DQSPADCTRL3 */
3949 0x00000802, /* EMC_CTT_TERM_CTRL */
3950 0x00064000, /* EMC_ZCAL_INTERVAL */
3951 0x00000025, /* EMC_ZCAL_WAIT_CNT */
3952 0x00090009, /* EMC_MRS_WAIT_CNT */
3953 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
3954 0x00000000, /* EMC_CTT */
3955 0x00000000, /* EMC_CTT_DURATION */
3956 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
3957 0x00000001, /* MC_EMEM_ARB_CFG */
3958 0xc0000013, /* MC_EMEM_ARB_OUTSTANDING_REQ */
3959 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
3960 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
3961 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
3962 0x00000001, /* MC_EMEM_ARB_TIMING_RAS */
3963 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
3964 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
3965 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
3966 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
3967 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
3968 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
3969 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
3970 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
3971 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
3972 0x00060403, /* MC_EMEM_ARB_DA_COVERS */
3973 0x72430504, /* MC_EMEM_ARB_MISC0 */
3974 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
3975 0x10000000, /* EMC_FBIO_SPARE */
3976 0xff00ff00, /* EMC_CFG_RSV */
3977 },
3978 0x0000000a, /* EMC_ZCAL_WAIT_CNT after clock change */
3979 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
3980 0x00000001, /* EMC_CFG.PERIODIC_QRST */
3981 0x00000000, /* Mode Register 0 */
3982 0x00010022, /* Mode Register 1 */
3983 0x00020001, /* Mode Register 2 */
3984 0x00000001, /* EMC_CFG.DYN_SELF_REF */
3985 },
3986 {
3987 0x32, /* Rev 3.2 */
3988 204000, /* SDRAM frequency */
3989 {
3990 0x0000000c, /* EMC_RC */
3991 0x0000001a, /* EMC_RFC */
3992 0x00000008, /* EMC_RAS */
3993 0x00000003, /* EMC_RP */
3994 0x00000005, /* EMC_R2W */
3995 0x00000004, /* EMC_W2R */
3996 0x00000001, /* EMC_R2P */
3997 0x00000006, /* EMC_W2P */
3998 0x00000003, /* EMC_RD_RCD */
3999 0x00000003, /* EMC_WR_RCD */
4000 0x00000002, /* EMC_RRD */
4001 0x00000002, /* EMC_REXT */
4002 0x00000000, /* EMC_WEXT */
4003 0x00000001, /* EMC_WDV */
4004 0x00000003, /* EMC_QUSE */
4005 0x00000001, /* EMC_QRST */
4006 0x0000000a, /* EMC_QSAFE */
4007 0x0000000a, /* EMC_RDV */
4008 0x00000303, /* EMC_REFRESH */
4009 0x00000000, /* EMC_BURST_REFRESH_NUM */
4010 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
4011 0x00000001, /* EMC_PDEX2WR */
4012 0x00000001, /* EMC_PDEX2RD */
4013 0x00000003, /* EMC_PCHG2PDEN */
4014 0x00000000, /* EMC_ACT2PDEN */
4015 0x00000001, /* EMC_AR2PDEN */
4016 0x00000007, /* EMC_RW2PDEN */
4017 0x0000001d, /* EMC_TXSR */
4018 0x0000001d, /* EMC_TXSRDLL */
4019 0x00000004, /* EMC_TCKE */
4020 0x0000000b, /* EMC_TFAW */
4021 0x00000005, /* EMC_TRPAB */
4022 0x00000004, /* EMC_TCLKSTABLE */
4023 0x00000002, /* EMC_TCLKSTOP */
4024 0x00000351, /* EMC_TREFBW */
4025 0x00000004, /* EMC_QUSE_EXTRA */
4026 0x00000006, /* EMC_FBIO_CFG6 */
4027 0x00000000, /* EMC_ODT_WRITE */
4028 0x00000000, /* EMC_ODT_READ */
4029 0x00004282, /* EMC_FBIO_CFG5 */
4030 0x004400a4, /* EMC_CFG_DIG_DLL */
4031 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4032 0x00074000, /* EMC_DLL_XFORM_DQS0 */
4033 0x00074000, /* EMC_DLL_XFORM_DQS1 */
4034 0x00074000, /* EMC_DLL_XFORM_DQS2 */
4035 0x00074000, /* EMC_DLL_XFORM_DQS3 */
4036 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4037 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4038 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4039 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4040 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4041 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4042 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4043 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4044 0x00000018, /* EMC_DLL_XFORM_QUSE4 */
4045 0x00000018, /* EMC_DLL_XFORM_QUSE5 */
4046 0x00000018, /* EMC_DLL_XFORM_QUSE6 */
4047 0x00000018, /* EMC_DLL_XFORM_QUSE7 */
4048 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4049 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4050 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4051 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4052 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4053 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4054 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4055 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4056 0x00078000, /* EMC_DLL_XFORM_DQ0 */
4057 0x00078000, /* EMC_DLL_XFORM_DQ1 */
4058 0x00078000, /* EMC_DLL_XFORM_DQ2 */
4059 0x00078000, /* EMC_DLL_XFORM_DQ3 */
4060 0x00100220, /* EMC_XM2CMDPADCTRL */
4061 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
4062 0x00000000, /* EMC_XM2DQPADCTRL2 */
4063 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4064 0x01f1f008, /* EMC_XM2COMPPADCTRL */
4065 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4066 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4067 0x08000068, /* EMC_XM2QUSEPADCTRL */
4068 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4069 0x00000802, /* EMC_CTT_TERM_CTRL */
4070 0x00064000, /* EMC_ZCAL_INTERVAL */
4071 0x0000004a, /* EMC_ZCAL_WAIT_CNT */
4072 0x00090009, /* EMC_MRS_WAIT_CNT */
4073 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
4074 0x00000000, /* EMC_CTT */
4075 0x00000000, /* EMC_CTT_DURATION */
4076 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
4077 0x00000003, /* MC_EMEM_ARB_CFG */
4078 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4079 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
4080 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
4081 0x00000006, /* MC_EMEM_ARB_TIMING_RC */
4082 0x00000003, /* MC_EMEM_ARB_TIMING_RAS */
4083 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
4084 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
4085 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4086 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4087 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
4088 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4089 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
4090 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
4091 0x02030001, /* MC_EMEM_ARB_DA_TURNS */
4092 0x00070506, /* MC_EMEM_ARB_DA_COVERS */
4093 0x71e40a07, /* MC_EMEM_ARB_MISC0 */
4094 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4095 0x50000000, /* EMC_FBIO_SPARE */
4096 0xff00ff00, /* EMC_CFG_RSV */
4097 },
4098 0x00000013, /* EMC_ZCAL_WAIT_CNT after clock change */
4099 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4100 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4101 0x00000000, /* Mode Register 0 */
4102 0x00010042, /* Mode Register 1 */
4103 0x00020001, /* Mode Register 2 */
4104 0x00000001, /* EMC_CFG.DYN_SELF_REF */
4105 },
4106 {
4107 0x32, /* Rev 3.2 */
4108 533000, /* SDRAM frequency */
4109 {
4110 0x0000001f, /* EMC_RC */
4111 0x00000045, /* EMC_RFC */
4112 0x00000016, /* EMC_RAS */
4113 0x00000009, /* EMC_RP */
4114 0x00000008, /* EMC_R2W */
4115 0x00000009, /* EMC_W2R */
4116 0x00000003, /* EMC_R2P */
4117 0x0000000d, /* EMC_W2P */
4118 0x00000009, /* EMC_RD_RCD */
4119 0x00000009, /* EMC_WR_RCD */
4120 0x00000005, /* EMC_RRD */
4121 0x00000003, /* EMC_REXT */
4122 0x00000000, /* EMC_WEXT */
4123 0x00000004, /* EMC_WDV */
4124 0x00000009, /* EMC_QUSE */
4125 0x00000006, /* EMC_QRST */
4126 0x0000000c, /* EMC_QSAFE */
4127 0x00000010, /* EMC_RDV */
4128 0x000007df, /* EMC_REFRESH */
4129 0x00000000, /* EMC_BURST_REFRESH_NUM */
4130 0x000001f7, /* EMC_PRE_REFRESH_REQ_CNT */
4131 0x00000003, /* EMC_PDEX2WR */
4132 0x00000003, /* EMC_PDEX2RD */
4133 0x00000009, /* EMC_PCHG2PDEN */
4134 0x00000000, /* EMC_ACT2PDEN */
4135 0x00000001, /* EMC_AR2PDEN */
4136 0x0000000f, /* EMC_RW2PDEN */
4137 0x0000004b, /* EMC_TXSR */
4138 0x0000004b, /* EMC_TXSRDLL */
4139 0x00000008, /* EMC_TCKE */
4140 0x0000001b, /* EMC_TFAW */
4141 0x0000000c, /* EMC_TRPAB */
4142 0x00000004, /* EMC_TCLKSTABLE */
4143 0x00000002, /* EMC_TCLKSTOP */
4144 0x000008aa, /* EMC_TREFBW */
4145 0x00000000, /* EMC_QUSE_EXTRA */
4146 0x00000006, /* EMC_FBIO_CFG6 */
4147 0x00000000, /* EMC_ODT_WRITE */
4148 0x00000000, /* EMC_ODT_READ */
4149 0x00006282, /* EMC_FBIO_CFG5 */
4150 0xf0120091, /* EMC_CFG_DIG_DLL */
4151 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4152 0x0000000a, /* EMC_DLL_XFORM_DQS0 */
4153 0x0000000a, /* EMC_DLL_XFORM_DQS1 */
4154 0x0000000a, /* EMC_DLL_XFORM_DQS2 */
4155 0x0000000a, /* EMC_DLL_XFORM_DQS3 */
4156 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4157 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4158 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4159 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4160 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4161 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4162 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4163 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4164 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
4165 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
4166 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
4167 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
4168 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4169 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4170 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4171 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4172 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4173 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4174 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4175 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4176 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
4177 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
4178 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
4179 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
4180 0x000b0220, /* EMC_XM2CMDPADCTRL */
4181 0x0800003d, /* EMC_XM2DQSPADCTRL2 */
4182 0x00000000, /* EMC_XM2DQPADCTRL2 */
4183 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4184 0x01f1f408, /* EMC_XM2COMPPADCTRL */
4185 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4186 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4187 0x08000068, /* EMC_XM2QUSEPADCTRL */
4188 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4189 0x00000802, /* EMC_CTT_TERM_CTRL */
4190 0x00064000, /* EMC_ZCAL_INTERVAL */
4191 0x000000c0, /* EMC_ZCAL_WAIT_CNT */
4192 0x000e000e, /* EMC_MRS_WAIT_CNT */
4193 0xa0f10202, /* EMC_AUTO_CAL_CONFIG */
4194 0x00000000, /* EMC_CTT */
4195 0x00000000, /* EMC_CTT_DURATION */
4196 0x800010d9, /* EMC_DYN_SELF_REF_CONTROL */
4197 0x00000008, /* MC_EMEM_ARB_CFG */
4198 0x80000060, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4199 0x00000003, /* MC_EMEM_ARB_TIMING_RCD */
4200 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
4201 0x00000010, /* MC_EMEM_ARB_TIMING_RC */
4202 0x0000000a, /* MC_EMEM_ARB_TIMING_RAS */
4203 0x0000000d, /* MC_EMEM_ARB_TIMING_FAW */
4204 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
4205 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4206 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4207 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
4208 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4209 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
4210 0x00000005, /* MC_EMEM_ARB_TIMING_W2R */
4211 0x05040002, /* MC_EMEM_ARB_DA_TURNS */
4212 0x00110b10, /* MC_EMEM_ARB_DA_COVERS */
4213 0x71c81811, /* MC_EMEM_ARB_MISC0 */
4214 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4215 0xe0000000, /* EMC_FBIO_SPARE */
4216 0xff00ff88, /* EMC_CFG_RSV */
4217 },
4218 0x00000030, /* EMC_ZCAL_WAIT_CNT after clock change */
4219 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4220 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4221 0x00000000, /* Mode Register 0 */
4222 0x000100c2, /* Mode Register 1 */
4223 0x00020006, /* Mode Register 2 */
4224 0x00000000, /* EMC_CFG.DYN_SELF_REF */
4225 },
4226};
4227
4228static const struct tegra_emc_table cardhu_emc_tables_edb8132b2ma[] = {
4229 {
4230 0x32, /* Rev 3.2 */
4231 25500, /* SDRAM frequency */
4232 {
4233 0x00000001, /* EMC_RC */
4234 0x00000003, /* EMC_RFC */
4235 0x00000002, /* EMC_RAS */
4236 0x00000002, /* EMC_RP */
4237 0x00000004, /* EMC_R2W */
4238 0x00000004, /* EMC_W2R */
4239 0x00000001, /* EMC_R2P */
4240 0x00000005, /* EMC_W2P */
4241 0x00000002, /* EMC_RD_RCD */
4242 0x00000002, /* EMC_WR_RCD */
4243 0x00000001, /* EMC_RRD */
4244 0x00000001, /* EMC_REXT */
4245 0x00000000, /* EMC_WEXT */
4246 0x00000001, /* EMC_WDV */
4247 0x00000003, /* EMC_QUSE */
4248 0x00000001, /* EMC_QRST */
4249 0x00000009, /* EMC_QSAFE */
4250 0x0000000a, /* EMC_RDV */
4251 0x00000060, /* EMC_REFRESH */
4252 0x00000000, /* EMC_BURST_REFRESH_NUM */
4253 0x00000018, /* EMC_PRE_REFRESH_REQ_CNT */
4254 0x00000001, /* EMC_PDEX2WR */
4255 0x00000001, /* EMC_PDEX2RD */
4256 0x00000002, /* EMC_PCHG2PDEN */
4257 0x00000000, /* EMC_ACT2PDEN */
4258 0x00000001, /* EMC_AR2PDEN */
4259 0x00000007, /* EMC_RW2PDEN */
4260 0x00000004, /* EMC_TXSR */
4261 0x00000004, /* EMC_TXSRDLL */
4262 0x00000003, /* EMC_TCKE */
4263 0x00000008, /* EMC_TFAW */
4264 0x00000004, /* EMC_TRPAB */
4265 0x00000004, /* EMC_TCLKSTABLE */
4266 0x00000002, /* EMC_TCLKSTOP */
4267 0x0000006b, /* EMC_TREFBW */
4268 0x00000004, /* EMC_QUSE_EXTRA */
4269 0x00000006, /* EMC_FBIO_CFG6 */
4270 0x00000000, /* EMC_ODT_WRITE */
4271 0x00000000, /* EMC_ODT_READ */
4272 0x00004282, /* EMC_FBIO_CFG5 */
4273 0x007800a4, /* EMC_CFG_DIG_DLL */
4274 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4275 0x000a0000, /* EMC_DLL_XFORM_DQS0 */
4276 0x000a0000, /* EMC_DLL_XFORM_DQS1 */
4277 0x000a0000, /* EMC_DLL_XFORM_DQS2 */
4278 0x000a0000, /* EMC_DLL_XFORM_DQS3 */
4279 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4280 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4281 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4282 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4283 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4284 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4285 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4286 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4287 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
4288 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
4289 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
4290 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
4291 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4292 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4293 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4294 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4295 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4296 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4297 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4298 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4299 0x00080000, /* EMC_DLL_XFORM_DQ0 */
4300 0x00080000, /* EMC_DLL_XFORM_DQ1 */
4301 0x00080000, /* EMC_DLL_XFORM_DQ2 */
4302 0x00080000, /* EMC_DLL_XFORM_DQ3 */
4303 0x00120220, /* EMC_XM2CMDPADCTRL */
4304 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
4305 0x00000000, /* EMC_XM2DQPADCTRL2 */
4306 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4307 0x01f1f008, /* EMC_XM2COMPPADCTRL */
4308 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4309 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4310 0x08000068, /* EMC_XM2QUSEPADCTRL */
4311 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4312 0x00000802, /* EMC_CTT_TERM_CTRL */
4313 0x00064000, /* EMC_ZCAL_INTERVAL */
4314 0x0000000a, /* EMC_ZCAL_WAIT_CNT */
4315 0x00090009, /* EMC_MRS_WAIT_CNT */
4316 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
4317 0x00000000, /* EMC_CTT */
4318 0x00000000, /* EMC_CTT_DURATION */
4319 0x800001c5, /* EMC_DYN_SELF_REF_CONTROL */
4320 0x00020001, /* MC_EMEM_ARB_CFG */
4321 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4322 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
4323 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
4324 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
4325 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
4326 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
4327 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
4328 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4329 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4330 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
4331 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4332 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
4333 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
4334 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
4335 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
4336 0x73e30303, /* MC_EMEM_ARB_MISC0 */
4337 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4338 0x50000000, /* EMC_FBIO_SPARE */
4339 0xff00ff00, /* EMC_CFG_RSV */
4340 },
4341 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
4342 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4343 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4344 0x00000000, /* Mode Register 0 */
4345 0x00010022, /* Mode Register 1 */
4346 0x00020001, /* Mode Register 2 */
4347 0x00000001, /* EMC_CFG.DYN_SELF_REF */
4348 },
4349 {
4350 0x32, /* Rev 3.2 */
4351 51000, /* SDRAM frequency */
4352 {
4353 0x00000003, /* EMC_RC */
4354 0x00000006, /* EMC_RFC */
4355 0x00000002, /* EMC_RAS */
4356 0x00000002, /* EMC_RP */
4357 0x00000004, /* EMC_R2W */
4358 0x00000004, /* EMC_W2R */
4359 0x00000001, /* EMC_R2P */
4360 0x00000005, /* EMC_W2P */
4361 0x00000002, /* EMC_RD_RCD */
4362 0x00000002, /* EMC_WR_RCD */
4363 0x00000001, /* EMC_RRD */
4364 0x00000001, /* EMC_REXT */
4365 0x00000000, /* EMC_WEXT */
4366 0x00000001, /* EMC_WDV */
4367 0x00000003, /* EMC_QUSE */
4368 0x00000001, /* EMC_QRST */
4369 0x00000009, /* EMC_QSAFE */
4370 0x0000000a, /* EMC_RDV */
4371 0x000000c0, /* EMC_REFRESH */
4372 0x00000000, /* EMC_BURST_REFRESH_NUM */
4373 0x00000030, /* EMC_PRE_REFRESH_REQ_CNT */
4374 0x00000001, /* EMC_PDEX2WR */
4375 0x00000001, /* EMC_PDEX2RD */
4376 0x00000002, /* EMC_PCHG2PDEN */
4377 0x00000000, /* EMC_ACT2PDEN */
4378 0x00000001, /* EMC_AR2PDEN */
4379 0x00000007, /* EMC_RW2PDEN */
4380 0x00000008, /* EMC_TXSR */
4381 0x00000008, /* EMC_TXSRDLL */
4382 0x00000003, /* EMC_TCKE */
4383 0x00000008, /* EMC_TFAW */
4384 0x00000004, /* EMC_TRPAB */
4385 0x00000004, /* EMC_TCLKSTABLE */
4386 0x00000002, /* EMC_TCLKSTOP */
4387 0x000000d5, /* EMC_TREFBW */
4388 0x00000004, /* EMC_QUSE_EXTRA */
4389 0x00000006, /* EMC_FBIO_CFG6 */
4390 0x00000000, /* EMC_ODT_WRITE */
4391 0x00000000, /* EMC_ODT_READ */
4392 0x00004282, /* EMC_FBIO_CFG5 */
4393 0x007800a4, /* EMC_CFG_DIG_DLL */
4394 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4395 0x000a0000, /* EMC_DLL_XFORM_DQS0 */
4396 0x000a0000, /* EMC_DLL_XFORM_DQS1 */
4397 0x000a0000, /* EMC_DLL_XFORM_DQS2 */
4398 0x000a0000, /* EMC_DLL_XFORM_DQS3 */
4399 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4400 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4401 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4402 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4403 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4404 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4405 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4406 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4407 0x00000018, /* EMC_DLL_XFORM_QUSE4 */
4408 0x00000018, /* EMC_DLL_XFORM_QUSE5 */
4409 0x00000018, /* EMC_DLL_XFORM_QUSE6 */
4410 0x00000018, /* EMC_DLL_XFORM_QUSE7 */
4411 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4412 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4413 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4414 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4415 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4416 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4417 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4418 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4419 0x00080000, /* EMC_DLL_XFORM_DQ0 */
4420 0x00080000, /* EMC_DLL_XFORM_DQ1 */
4421 0x00080000, /* EMC_DLL_XFORM_DQ2 */
4422 0x00080000, /* EMC_DLL_XFORM_DQ3 */
4423 0x00120220, /* EMC_XM2CMDPADCTRL */
4424 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
4425 0x00000000, /* EMC_XM2DQPADCTRL2 */
4426 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4427 0x01f1f008, /* EMC_XM2COMPPADCTRL */
4428 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4429 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4430 0x08000068, /* EMC_XM2QUSEPADCTRL */
4431 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4432 0x00000802, /* EMC_CTT_TERM_CTRL */
4433 0x00064000, /* EMC_ZCAL_INTERVAL */
4434 0x00000013, /* EMC_ZCAL_WAIT_CNT */
4435 0x00090009, /* EMC_MRS_WAIT_CNT */
4436 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
4437 0x00000000, /* EMC_CTT */
4438 0x00000000, /* EMC_CTT_DURATION */
4439 0x80000287, /* EMC_DYN_SELF_REF_CONTROL */
4440 0x00010001, /* MC_EMEM_ARB_CFG */
4441 0xc000000a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4442 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
4443 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
4444 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
4445 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
4446 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
4447 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
4448 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4449 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4450 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
4451 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4452 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
4453 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
4454 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
4455 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
4456 0x72c30303, /* MC_EMEM_ARB_MISC0 */
4457 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4458 0x50000000, /* EMC_FBIO_SPARE */
4459 0xff00ff00, /* EMC_CFG_RSV */
4460 },
4461 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
4462 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4463 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4464 0x00000000, /* Mode Register 0 */
4465 0x00010022, /* Mode Register 1 */
4466 0x00020001, /* Mode Register 2 */
4467 0x00000001, /* EMC_CFG.DYN_SELF_REF */
4468 },
4469 {
4470 0x32, /* Rev 3.2 */
4471 102000, /* SDRAM frequency */
4472 {
4473 0x00000006, /* EMC_RC */
4474 0x0000000d, /* EMC_RFC */
4475 0x00000004, /* EMC_RAS */
4476 0x00000002, /* EMC_RP */
4477 0x00000004, /* EMC_R2W */
4478 0x00000004, /* EMC_W2R */
4479 0x00000001, /* EMC_R2P */
4480 0x00000005, /* EMC_W2P */
4481 0x00000002, /* EMC_RD_RCD */
4482 0x00000002, /* EMC_WR_RCD */
4483 0x00000001, /* EMC_RRD */
4484 0x00000001, /* EMC_REXT */
4485 0x00000000, /* EMC_WEXT */
4486 0x00000001, /* EMC_WDV */
4487 0x00000003, /* EMC_QUSE */
4488 0x00000001, /* EMC_QRST */
4489 0x00000009, /* EMC_QSAFE */
4490 0x0000000a, /* EMC_RDV */
4491 0x00000181, /* EMC_REFRESH */
4492 0x00000000, /* EMC_BURST_REFRESH_NUM */
4493 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
4494 0x00000001, /* EMC_PDEX2WR */
4495 0x00000001, /* EMC_PDEX2RD */
4496 0x00000002, /* EMC_PCHG2PDEN */
4497 0x00000000, /* EMC_ACT2PDEN */
4498 0x00000001, /* EMC_AR2PDEN */
4499 0x00000007, /* EMC_RW2PDEN */
4500 0x0000000f, /* EMC_TXSR */
4501 0x0000000f, /* EMC_TXSRDLL */
4502 0x00000003, /* EMC_TCKE */
4503 0x00000008, /* EMC_TFAW */
4504 0x00000004, /* EMC_TRPAB */
4505 0x00000004, /* EMC_TCLKSTABLE */
4506 0x00000002, /* EMC_TCLKSTOP */
4507 0x000001a9, /* EMC_TREFBW */
4508 0x00000004, /* EMC_QUSE_EXTRA */
4509 0x00000006, /* EMC_FBIO_CFG6 */
4510 0x00000000, /* EMC_ODT_WRITE */
4511 0x00000000, /* EMC_ODT_READ */
4512 0x00004282, /* EMC_FBIO_CFG5 */
4513 0x007800a4, /* EMC_CFG_DIG_DLL */
4514 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4515 0x000a0000, /* EMC_DLL_XFORM_DQS0 */
4516 0x000a0000, /* EMC_DLL_XFORM_DQS1 */
4517 0x000a0000, /* EMC_DLL_XFORM_DQS2 */
4518 0x000a0000, /* EMC_DLL_XFORM_DQS3 */
4519 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4520 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4521 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4522 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4523 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4524 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4525 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4526 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4527 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
4528 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
4529 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
4530 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
4531 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4532 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4533 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4534 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4535 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4536 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4537 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4538 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4539 0x00080000, /* EMC_DLL_XFORM_DQ0 */
4540 0x00080000, /* EMC_DLL_XFORM_DQ1 */
4541 0x00080000, /* EMC_DLL_XFORM_DQ2 */
4542 0x00080000, /* EMC_DLL_XFORM_DQ3 */
4543 0x00120220, /* EMC_XM2CMDPADCTRL */
4544 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
4545 0x00000000, /* EMC_XM2DQPADCTRL2 */
4546 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4547 0x01f1f008, /* EMC_XM2COMPPADCTRL */
4548 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4549 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4550 0x08000068, /* EMC_XM2QUSEPADCTRL */
4551 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4552 0x00000802, /* EMC_CTT_TERM_CTRL */
4553 0x00064000, /* EMC_ZCAL_INTERVAL */
4554 0x00000025, /* EMC_ZCAL_WAIT_CNT */
4555 0x00090009, /* EMC_MRS_WAIT_CNT */
4556 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
4557 0x00000000, /* EMC_CTT */
4558 0x00000000, /* EMC_CTT_DURATION */
4559 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
4560 0x00000001, /* MC_EMEM_ARB_CFG */
4561 0xc0000013, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4562 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
4563 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
4564 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
4565 0x00000001, /* MC_EMEM_ARB_TIMING_RAS */
4566 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
4567 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
4568 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4569 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4570 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
4571 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4572 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
4573 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
4574 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
4575 0x00060403, /* MC_EMEM_ARB_DA_COVERS */
4576 0x72430504, /* MC_EMEM_ARB_MISC0 */
4577 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4578 0x50000000, /* EMC_FBIO_SPARE */
4579 0xff00ff00, /* EMC_CFG_RSV */
4580 },
4581 0x0000000a, /* EMC_ZCAL_WAIT_CNT after clock change */
4582 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4583 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4584 0x00000000, /* Mode Register 0 */
4585 0x00010022, /* Mode Register 1 */
4586 0x00020001, /* Mode Register 2 */
4587 0x00000001, /* EMC_CFG.DYN_SELF_REF */
4588 },
4589 {
4590 0x32, /* Rev 3.2 */
4591 204000, /* SDRAM frequency */
4592 {
4593 0x0000000c, /* EMC_RC */
4594 0x0000001a, /* EMC_RFC */
4595 0x00000008, /* EMC_RAS */
4596 0x00000003, /* EMC_RP */
4597 0x00000005, /* EMC_R2W */
4598 0x00000004, /* EMC_W2R */
4599 0x00000001, /* EMC_R2P */
4600 0x00000006, /* EMC_W2P */
4601 0x00000003, /* EMC_RD_RCD */
4602 0x00000003, /* EMC_WR_RCD */
4603 0x00000002, /* EMC_RRD */
4604 0x00000002, /* EMC_REXT */
4605 0x00000000, /* EMC_WEXT */
4606 0x00000001, /* EMC_WDV */
4607 0x00000004, /* EMC_QUSE */
4608 0x00000001, /* EMC_QRST */
4609 0x0000000b, /* EMC_QSAFE */
4610 0x0000000a, /* EMC_RDV */
4611 0x00000303, /* EMC_REFRESH */
4612 0x00000000, /* EMC_BURST_REFRESH_NUM */
4613 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
4614 0x00000001, /* EMC_PDEX2WR */
4615 0x00000001, /* EMC_PDEX2RD */
4616 0x00000003, /* EMC_PCHG2PDEN */
4617 0x00000000, /* EMC_ACT2PDEN */
4618 0x00000001, /* EMC_AR2PDEN */
4619 0x00000007, /* EMC_RW2PDEN */
4620 0x0000001d, /* EMC_TXSR */
4621 0x0000001d, /* EMC_TXSRDLL */
4622 0x00000004, /* EMC_TCKE */
4623 0x0000000b, /* EMC_TFAW */
4624 0x00000005, /* EMC_TRPAB */
4625 0x00000004, /* EMC_TCLKSTABLE */
4626 0x00000002, /* EMC_TCLKSTOP */
4627 0x00000351, /* EMC_TREFBW */
4628 0x00000005, /* EMC_QUSE_EXTRA */
4629 0x00000004, /* EMC_FBIO_CFG6 */
4630 0x00000000, /* EMC_ODT_WRITE */
4631 0x00000000, /* EMC_ODT_READ */
4632 0x00004282, /* EMC_FBIO_CFG5 */
4633 0x004400a4, /* EMC_CFG_DIG_DLL */
4634 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4635 0x00070000, /* EMC_DLL_XFORM_DQS0 */
4636 0x00070000, /* EMC_DLL_XFORM_DQS1 */
4637 0x00070000, /* EMC_DLL_XFORM_DQS2 */
4638 0x00070000, /* EMC_DLL_XFORM_DQS3 */
4639 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4640 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4641 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4642 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4643 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4644 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4645 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4646 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4647 0x00000018, /* EMC_DLL_XFORM_QUSE4 */
4648 0x00000018, /* EMC_DLL_XFORM_QUSE5 */
4649 0x00000018, /* EMC_DLL_XFORM_QUSE6 */
4650 0x00000018, /* EMC_DLL_XFORM_QUSE7 */
4651 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4652 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4653 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4654 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4655 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4656 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4657 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4658 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4659 0x00078000, /* EMC_DLL_XFORM_DQ0 */
4660 0x00078000, /* EMC_DLL_XFORM_DQ1 */
4661 0x00078000, /* EMC_DLL_XFORM_DQ2 */
4662 0x00078000, /* EMC_DLL_XFORM_DQ3 */
4663 0x000d0220, /* EMC_XM2CMDPADCTRL */
4664 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
4665 0x00000000, /* EMC_XM2DQPADCTRL2 */
4666 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4667 0x01f1f008, /* EMC_XM2COMPPADCTRL */
4668 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4669 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4670 0x08000068, /* EMC_XM2QUSEPADCTRL */
4671 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4672 0x00000802, /* EMC_CTT_TERM_CTRL */
4673 0x00064000, /* EMC_ZCAL_INTERVAL */
4674 0x0000004a, /* EMC_ZCAL_WAIT_CNT */
4675 0x00090009, /* EMC_MRS_WAIT_CNT */
4676 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
4677 0x00000000, /* EMC_CTT */
4678 0x00000000, /* EMC_CTT_DURATION */
4679 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
4680 0x00000003, /* MC_EMEM_ARB_CFG */
4681 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4682 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
4683 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
4684 0x00000006, /* MC_EMEM_ARB_TIMING_RC */
4685 0x00000003, /* MC_EMEM_ARB_TIMING_RAS */
4686 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
4687 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
4688 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4689 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4690 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
4691 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4692 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
4693 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
4694 0x02030001, /* MC_EMEM_ARB_DA_TURNS */
4695 0x00070506, /* MC_EMEM_ARB_DA_COVERS */
4696 0x71e40a07, /* MC_EMEM_ARB_MISC0 */
4697 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4698 0xd0000000, /* EMC_FBIO_SPARE */
4699 0xff00ff00, /* EMC_CFG_RSV */
4700 },
4701 0x00000013, /* EMC_ZCAL_WAIT_CNT after clock change */
4702 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4703 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4704 0x00000000, /* Mode Register 0 */
4705 0x00010042, /* Mode Register 1 */
4706 0x00020001, /* Mode Register 2 */
4707 0x00000001, /* EMC_CFG.DYN_SELF_REF */
4708 },
4709 {
4710 0x32, /* Rev 3.2 */
4711 533000, /* SDRAM frequency */
4712 {
4713 0x0000001f, /* EMC_RC */
4714 0x00000045, /* EMC_RFC */
4715 0x00000016, /* EMC_RAS */
4716 0x00000009, /* EMC_RP */
4717 0x00000008, /* EMC_R2W */
4718 0x00000009, /* EMC_W2R */
4719 0x00000003, /* EMC_R2P */
4720 0x0000000d, /* EMC_W2P */
4721 0x00000009, /* EMC_RD_RCD */
4722 0x00000009, /* EMC_WR_RCD */
4723 0x00000005, /* EMC_RRD */
4724 0x00000003, /* EMC_REXT */
4725 0x00000000, /* EMC_WEXT */
4726 0x00000004, /* EMC_WDV */
4727 0x00000009, /* EMC_QUSE */
4728 0x00000006, /* EMC_QRST */
4729 0x0000000c, /* EMC_QSAFE */
4730 0x00000010, /* EMC_RDV */
4731 0x000007df, /* EMC_REFRESH */
4732 0x00000000, /* EMC_BURST_REFRESH_NUM */
4733 0x000001f7, /* EMC_PRE_REFRESH_REQ_CNT */
4734 0x00000003, /* EMC_PDEX2WR */
4735 0x00000003, /* EMC_PDEX2RD */
4736 0x00000009, /* EMC_PCHG2PDEN */
4737 0x00000000, /* EMC_ACT2PDEN */
4738 0x00000001, /* EMC_AR2PDEN */
4739 0x0000000f, /* EMC_RW2PDEN */
4740 0x0000004b, /* EMC_TXSR */
4741 0x0000004b, /* EMC_TXSRDLL */
4742 0x00000008, /* EMC_TCKE */
4743 0x0000001b, /* EMC_TFAW */
4744 0x0000000c, /* EMC_TRPAB */
4745 0x00000004, /* EMC_TCLKSTABLE */
4746 0x00000002, /* EMC_TCLKSTOP */
4747 0x000008aa, /* EMC_TREFBW */
4748 0x00000000, /* EMC_QUSE_EXTRA */
4749 0x00000006, /* EMC_FBIO_CFG6 */
4750 0x00000000, /* EMC_ODT_WRITE */
4751 0x00000000, /* EMC_ODT_READ */
4752 0x00006282, /* EMC_FBIO_CFG5 */
4753 0xf0120091, /* EMC_CFG_DIG_DLL */
4754 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4755 0x00000008, /* EMC_DLL_XFORM_DQS0 */
4756 0x00000008, /* EMC_DLL_XFORM_DQS1 */
4757 0x00000008, /* EMC_DLL_XFORM_DQS2 */
4758 0x00000008, /* EMC_DLL_XFORM_DQS3 */
4759 0x00000010, /* EMC_DLL_XFORM_DQS4 */
4760 0x00000010, /* EMC_DLL_XFORM_DQS5 */
4761 0x00000010, /* EMC_DLL_XFORM_DQS6 */
4762 0x00000010, /* EMC_DLL_XFORM_DQS7 */
4763 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4764 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4765 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4766 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4767 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
4768 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
4769 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
4770 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
4771 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4772 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4773 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4774 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4775 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4776 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4777 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4778 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4779 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
4780 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
4781 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
4782 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
4783 0x00070220, /* EMC_XM2CMDPADCTRL */
4784 0x0400003d, /* EMC_XM2DQSPADCTRL2 */
4785 0x00000000, /* EMC_XM2DQPADCTRL2 */
4786 0x77ffc004, /* EMC_XM2CLKPADCTRL */
4787 0x01f1f408, /* EMC_XM2COMPPADCTRL */
4788 0x00000000, /* EMC_XM2VTTGENPADCTRL */
4789 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
4790 0x08000068, /* EMC_XM2QUSEPADCTRL */
4791 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4792 0x00000802, /* EMC_CTT_TERM_CTRL */
4793 0x00064000, /* EMC_ZCAL_INTERVAL */
4794 0x000000c0, /* EMC_ZCAL_WAIT_CNT */
4795 0x000e000e, /* EMC_MRS_WAIT_CNT */
4796 0xa0f10202, /* EMC_AUTO_CAL_CONFIG */
4797 0x00000000, /* EMC_CTT */
4798 0x00000000, /* EMC_CTT_DURATION */
4799 0x800010d9, /* EMC_DYN_SELF_REF_CONTROL */
4800 0x00000008, /* MC_EMEM_ARB_CFG */
4801 0x80000060, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4802 0x00000003, /* MC_EMEM_ARB_TIMING_RCD */
4803 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
4804 0x00000010, /* MC_EMEM_ARB_TIMING_RC */
4805 0x0000000a, /* MC_EMEM_ARB_TIMING_RAS */
4806 0x0000000d, /* MC_EMEM_ARB_TIMING_FAW */
4807 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
4808 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4809 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4810 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
4811 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
4812 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
4813 0x00000005, /* MC_EMEM_ARB_TIMING_W2R */
4814 0x05040002, /* MC_EMEM_ARB_DA_TURNS */
4815 0x00110b10, /* MC_EMEM_ARB_DA_COVERS */
4816 0x71c81811, /* MC_EMEM_ARB_MISC0 */
4817 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4818 0x60000000, /* EMC_FBIO_SPARE */
4819 0xff00ff88, /* EMC_CFG_RSV */
4820 },
4821 0x00000030, /* EMC_ZCAL_WAIT_CNT after clock change */
4822 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4823 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4824 0x00000000, /* Mode Register 0 */
4825 0x000100c2, /* Mode Register 1 */
4826 0x00020006, /* Mode Register 2 */
4827 0x00000000, /* EMC_CFG.DYN_SELF_REF */
4828 },
4829};
4830
4831static const struct tegra_emc_table cardhu_emc_tables_h5tc2g_pm311[] = {
4832 {
4833 0x32, /* Rev 3.2 */
4834 51000, /* SDRAM frequency */
4835 {
4836 0x00000002, /* EMC_RC */
4837 0x00000008, /* EMC_RFC */
4838 0x00000001, /* EMC_RAS */
4839 0x00000000, /* EMC_RP */
4840 0x00000002, /* EMC_R2W */
4841 0x0000000a, /* EMC_W2R */
4842 0x00000003, /* EMC_R2P */
4843 0x0000000b, /* EMC_W2P */
4844 0x00000000, /* EMC_RD_RCD */
4845 0x00000000, /* EMC_WR_RCD */
4846 0x00000003, /* EMC_RRD */
4847 0x00000001, /* EMC_REXT */
4848 0x00000000, /* EMC_WEXT */
4849 0x00000005, /* EMC_WDV */
4850 0x00000005, /* EMC_QUSE */
4851 0x00000004, /* EMC_QRST */
4852 0x00000009, /* EMC_QSAFE */
4853 0x0000000b, /* EMC_RDV */
4854 0x00000181, /* EMC_REFRESH */
4855 0x00000000, /* EMC_BURST_REFRESH_NUM */
4856 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
4857 0x00000002, /* EMC_PDEX2WR */
4858 0x00000002, /* EMC_PDEX2RD */
4859 0x00000001, /* EMC_PCHG2PDEN */
4860 0x00000000, /* EMC_ACT2PDEN */
4861 0x00000007, /* EMC_AR2PDEN */
4862 0x0000000f, /* EMC_RW2PDEN */
4863 0x00000009, /* EMC_TXSR */
4864 0x00000009, /* EMC_TXSRDLL */
4865 0x00000004, /* EMC_TCKE */
4866 0x00000002, /* EMC_TFAW */
4867 0x00000000, /* EMC_TRPAB */
4868 0x00000004, /* EMC_TCLKSTABLE */
4869 0x00000005, /* EMC_TCLKSTOP */
4870 0x0000018e, /* EMC_TREFBW */
4871 0x00000006, /* EMC_QUSE_EXTRA */
4872 0x00000004, /* EMC_FBIO_CFG6 */
4873 0x00000000, /* EMC_ODT_WRITE */
4874 0x00000000, /* EMC_ODT_READ */
4875 0x00004288, /* EMC_FBIO_CFG5 */
4876 0x007800a4, /* EMC_CFG_DIG_DLL */
4877 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4878 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
4879 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
4880 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
4881 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
4882 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
4883 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
4884 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
4885 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
4886 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
4887 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
4888 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
4889 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
4890 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
4891 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
4892 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
4893 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
4894 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
4895 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
4896 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
4897 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
4898 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
4899 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
4900 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
4901 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
4902 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
4903 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
4904 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
4905 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
4906 0x000002a0, /* EMC_XM2CMDPADCTRL */
4907 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
4908 0x00000000, /* EMC_XM2DQPADCTRL2 */
4909 0x77ffc084, /* EMC_XM2CLKPADCTRL */
4910 0x01f1f108, /* EMC_XM2COMPPADCTRL */
4911 0x05057404, /* EMC_XM2VTTGENPADCTRL */
4912 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
4913 0x08000168, /* EMC_XM2QUSEPADCTRL */
4914 0x08000000, /* EMC_XM2DQSPADCTRL3 */
4915 0x00000802, /* EMC_CTT_TERM_CTRL */
4916 0x00000000, /* EMC_ZCAL_INTERVAL */
4917 0x00000040, /* EMC_ZCAL_WAIT_CNT */
4918 0x000c000c, /* EMC_MRS_WAIT_CNT */
4919 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
4920 0x00000000, /* EMC_CTT */
4921 0x00000000, /* EMC_CTT_DURATION */
4922 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
4923 0x00010001, /* MC_EMEM_ARB_CFG */
4924 0xc000000a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
4925 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
4926 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
4927 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
4928 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
4929 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
4930 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
4931 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
4932 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
4933 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
4934 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
4935 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
4936 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
4937 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
4938 0x000a0402, /* MC_EMEM_ARB_DA_COVERS */
4939 0x73430303, /* MC_EMEM_ARB_MISC0 */
4940 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
4941 0xe8000000, /* EMC_FBIO_SPARE */
4942 0xff00ff00, /* EMC_CFG_RSV */
4943 },
4944 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
4945 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
4946 0x00000001, /* EMC_CFG.PERIODIC_QRST */
4947 0x80001221, /* Mode Register 0 */
4948 0x80100003, /* Mode Register 1 */
4949 0x80200008, /* Mode Register 2 */
4950 0x00000001, /* EMC_CFG.DYN_SELF_REF */
4951 },
4952 {
4953 0x32, /* Rev 3.2 */
4954 102000, /* SDRAM frequency */
4955 {
4956 0x00000005, /* EMC_RC */
4957 0x00000010, /* EMC_RFC */
4958 0x00000003, /* EMC_RAS */
4959 0x00000001, /* EMC_RP */
4960 0x00000002, /* EMC_R2W */
4961 0x0000000a, /* EMC_W2R */
4962 0x00000003, /* EMC_R2P */
4963 0x0000000b, /* EMC_W2P */
4964 0x00000001, /* EMC_RD_RCD */
4965 0x00000001, /* EMC_WR_RCD */
4966 0x00000003, /* EMC_RRD */
4967 0x00000001, /* EMC_REXT */
4968 0x00000000, /* EMC_WEXT */
4969 0x00000005, /* EMC_WDV */
4970 0x00000005, /* EMC_QUSE */
4971 0x00000004, /* EMC_QRST */
4972 0x00000009, /* EMC_QSAFE */
4973 0x0000000c, /* EMC_RDV */
4974 0x00000303, /* EMC_REFRESH */
4975 0x00000000, /* EMC_BURST_REFRESH_NUM */
4976 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
4977 0x00000002, /* EMC_PDEX2WR */
4978 0x00000002, /* EMC_PDEX2RD */
4979 0x00000001, /* EMC_PCHG2PDEN */
4980 0x00000000, /* EMC_ACT2PDEN */
4981 0x00000007, /* EMC_AR2PDEN */
4982 0x0000000f, /* EMC_RW2PDEN */
4983 0x00000012, /* EMC_TXSR */
4984 0x00000012, /* EMC_TXSRDLL */
4985 0x00000004, /* EMC_TCKE */
4986 0x00000004, /* EMC_TFAW */
4987 0x00000000, /* EMC_TRPAB */
4988 0x00000004, /* EMC_TCLKSTABLE */
4989 0x00000005, /* EMC_TCLKSTOP */
4990 0x0000031c, /* EMC_TREFBW */
4991 0x00000006, /* EMC_QUSE_EXTRA */
4992 0x00000004, /* EMC_FBIO_CFG6 */
4993 0x00000000, /* EMC_ODT_WRITE */
4994 0x00000000, /* EMC_ODT_READ */
4995 0x00004288, /* EMC_FBIO_CFG5 */
4996 0x007800a4, /* EMC_CFG_DIG_DLL */
4997 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
4998 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
4999 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
5000 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
5001 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
5002 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
5003 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
5004 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
5005 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
5006 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
5007 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
5008 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
5009 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
5010 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
5011 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
5012 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
5013 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
5014 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
5015 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
5016 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
5017 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
5018 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
5019 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
5020 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
5021 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
5022 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
5023 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
5024 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
5025 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
5026 0x000002a0, /* EMC_XM2CMDPADCTRL */
5027 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
5028 0x00000000, /* EMC_XM2DQPADCTRL2 */
5029 0x77ffc084, /* EMC_XM2CLKPADCTRL */
5030 0x01f1f108, /* EMC_XM2COMPPADCTRL */
5031 0x03037404, /* EMC_XM2VTTGENPADCTRL */
5032 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
5033 0x08000168, /* EMC_XM2QUSEPADCTRL */
5034 0x08000000, /* EMC_XM2DQSPADCTRL3 */
5035 0x00000802, /* EMC_CTT_TERM_CTRL */
5036 0x00000000, /* EMC_ZCAL_INTERVAL */
5037 0x00000040, /* EMC_ZCAL_WAIT_CNT */
5038 0x000c000c, /* EMC_MRS_WAIT_CNT */
5039 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
5040 0x00000000, /* EMC_CTT */
5041 0x00000000, /* EMC_CTT_DURATION */
5042 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
5043 0x00000001, /* MC_EMEM_ARB_CFG */
5044 0xc0000013, /* MC_EMEM_ARB_OUTSTANDING_REQ */
5045 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
5046 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
5047 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
5048 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
5049 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
5050 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
5051 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
5052 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
5053 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
5054 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
5055 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
5056 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
5057 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
5058 0x000a0403, /* MC_EMEM_ARB_DA_COVERS */
5059 0x72830504, /* MC_EMEM_ARB_MISC0 */
5060 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
5061 0xe8000000, /* EMC_FBIO_SPARE */
5062 0xff00ff00, /* EMC_CFG_RSV */
5063 },
5064 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
5065 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
5066 0x00000001, /* EMC_CFG.PERIODIC_QRST */
5067 0x80001221, /* Mode Register 0 */
5068 0x80100003, /* Mode Register 1 */
5069 0x80200008, /* Mode Register 2 */
5070 0x00000001, /* EMC_CFG.DYN_SELF_REF */
5071 },
5072 {
5073 0x32, /* Rev 3.2 */
5074 204000, /* SDRAM frequency */
5075 {
5076 0x0000000a, /* EMC_RC */
5077 0x00000020, /* EMC_RFC */
5078 0x00000007, /* EMC_RAS */
5079 0x00000002, /* EMC_RP */
5080 0x00000002, /* EMC_R2W */
5081 0x0000000a, /* EMC_W2R */
5082 0x00000003, /* EMC_R2P */
5083 0x0000000b, /* EMC_W2P */
5084 0x00000002, /* EMC_RD_RCD */
5085 0x00000002, /* EMC_WR_RCD */
5086 0x00000003, /* EMC_RRD */
5087 0x00000001, /* EMC_REXT */
5088 0x00000000, /* EMC_WEXT */
5089 0x00000005, /* EMC_WDV */
5090 0x00000006, /* EMC_QUSE */
5091 0x00000004, /* EMC_QRST */
5092 0x00000009, /* EMC_QSAFE */
5093 0x0000000b, /* EMC_RDV */
5094 0x00000607, /* EMC_REFRESH */
5095 0x00000000, /* EMC_BURST_REFRESH_NUM */
5096 0x00000181, /* EMC_PRE_REFRESH_REQ_CNT */
5097 0x00000002, /* EMC_PDEX2WR */
5098 0x00000002, /* EMC_PDEX2RD */
5099 0x00000001, /* EMC_PCHG2PDEN */
5100 0x00000000, /* EMC_ACT2PDEN */
5101 0x00000007, /* EMC_AR2PDEN */
5102 0x0000000f, /* EMC_RW2PDEN */
5103 0x00000023, /* EMC_TXSR */
5104 0x00000023, /* EMC_TXSRDLL */
5105 0x00000004, /* EMC_TCKE */
5106 0x00000007, /* EMC_TFAW */
5107 0x00000000, /* EMC_TRPAB */
5108 0x00000004, /* EMC_TCLKSTABLE */
5109 0x00000005, /* EMC_TCLKSTOP */
5110 0x00000638, /* EMC_TREFBW */
5111 0x00000007, /* EMC_QUSE_EXTRA */
5112 0x00000004, /* EMC_FBIO_CFG6 */
5113 0x00000000, /* EMC_ODT_WRITE */
5114 0x00000000, /* EMC_ODT_READ */
5115 0x00004288, /* EMC_FBIO_CFG5 */
5116 0x004400a4, /* EMC_CFG_DIG_DLL */
5117 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
5118 0x00080000, /* EMC_DLL_XFORM_DQS0 */
5119 0x00080000, /* EMC_DLL_XFORM_DQS1 */
5120 0x00080000, /* EMC_DLL_XFORM_DQS2 */
5121 0x00080000, /* EMC_DLL_XFORM_DQS3 */
5122 0x00080000, /* EMC_DLL_XFORM_DQS4 */
5123 0x00080000, /* EMC_DLL_XFORM_DQS5 */
5124 0x00080000, /* EMC_DLL_XFORM_DQS6 */
5125 0x00080000, /* EMC_DLL_XFORM_DQS7 */
5126 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
5127 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
5128 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
5129 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
5130 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
5131 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
5132 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
5133 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
5134 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
5135 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
5136 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
5137 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
5138 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
5139 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
5140 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
5141 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
5142 0x00080000, /* EMC_DLL_XFORM_DQ0 */
5143 0x00080000, /* EMC_DLL_XFORM_DQ1 */
5144 0x00080000, /* EMC_DLL_XFORM_DQ2 */
5145 0x00080000, /* EMC_DLL_XFORM_DQ3 */
5146 0x000002a0, /* EMC_XM2CMDPADCTRL */
5147 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
5148 0x00000000, /* EMC_XM2DQPADCTRL2 */
5149 0x77fff884, /* EMC_XM2CLKPADCTRL */
5150 0x01f1f108, /* EMC_XM2COMPPADCTRL */
5151 0x05057404, /* EMC_XM2VTTGENPADCTRL */
5152 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
5153 0x08000168, /* EMC_XM2QUSEPADCTRL */
5154 0x08000000, /* EMC_XM2DQSPADCTRL3 */
5155 0x00000802, /* EMC_CTT_TERM_CTRL */
5156 0x00020000, /* EMC_ZCAL_INTERVAL */
5157 0x00000100, /* EMC_ZCAL_WAIT_CNT */
5158 0x000c000c, /* EMC_MRS_WAIT_CNT */
5159 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
5160 0x00000000, /* EMC_CTT */
5161 0x00000000, /* EMC_CTT_DURATION */
5162 0x80000d22, /* EMC_DYN_SELF_REF_CONTROL */
5163 0x00000003, /* MC_EMEM_ARB_CFG */
5164 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
5165 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
5166 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
5167 0x00000005, /* MC_EMEM_ARB_TIMING_RC */
5168 0x00000002, /* MC_EMEM_ARB_TIMING_RAS */
5169 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
5170 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
5171 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
5172 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
5173 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
5174 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
5175 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
5176 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
5177 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
5178 0x000a0405, /* MC_EMEM_ARB_DA_COVERS */
5179 0x72440a06, /* MC_EMEM_ARB_MISC0 */
5180 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
5181 0xe8000000, /* EMC_FBIO_SPARE */
5182 0xff00ff00, /* EMC_CFG_RSV */
5183 },
5184 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
5185 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
5186 0x00000001, /* EMC_CFG.PERIODIC_QRST */
5187 0x80001221, /* Mode Register 0 */
5188 0x80100003, /* Mode Register 1 */
5189 0x80200008, /* Mode Register 2 */
5190 0x00000001, /* EMC_CFG.DYN_SELF_REF */
5191 },
5192 {
5193 0x32, /* Rev 3.2 */
5194 333500, /* SDRAM frequency */
5195 {
5196 0x0000000f, /* EMC_RC */
5197 0x00000034, /* EMC_RFC */
5198 0x0000000a, /* EMC_RAS */
5199 0x00000003, /* EMC_RP */
5200 0x00000003, /* EMC_R2W */
5201 0x00000008, /* EMC_W2R */
5202 0x00000002, /* EMC_R2P */
5203 0x00000009, /* EMC_W2P */
5204 0x00000003, /* EMC_RD_RCD */
5205 0x00000003, /* EMC_WR_RCD */
5206 0x00000002, /* EMC_RRD */
5207 0x00000001, /* EMC_REXT */
5208 0x00000000, /* EMC_WEXT */
5209 0x00000004, /* EMC_WDV */
5210 0x00000006, /* EMC_QUSE */
5211 0x00000004, /* EMC_QRST */
5212 0x0000000a, /* EMC_QSAFE */
5213 0x0000000c, /* EMC_RDV */
5214 0x000009e9, /* EMC_REFRESH */
5215 0x00000000, /* EMC_BURST_REFRESH_NUM */
5216 0x0000027a, /* EMC_PRE_REFRESH_REQ_CNT */
5217 0x00000001, /* EMC_PDEX2WR */
5218 0x00000008, /* EMC_PDEX2RD */
5219 0x00000001, /* EMC_PCHG2PDEN */
5220 0x00000000, /* EMC_ACT2PDEN */
5221 0x00000007, /* EMC_AR2PDEN */
5222 0x0000000e, /* EMC_RW2PDEN */
5223 0x00000039, /* EMC_TXSR */
5224 0x00000200, /* EMC_TXSRDLL */
5225 0x00000004, /* EMC_TCKE */
5226 0x0000000a, /* EMC_TFAW */
5227 0x00000000, /* EMC_TRPAB */
5228 0x00000004, /* EMC_TCLKSTABLE */
5229 0x00000005, /* EMC_TCLKSTOP */
5230 0x00000a2a, /* EMC_TREFBW */
5231 0x00000000, /* EMC_QUSE_EXTRA */
5232 0x00000006, /* EMC_FBIO_CFG6 */
5233 0x00000000, /* EMC_ODT_WRITE */
5234 0x00000000, /* EMC_ODT_READ */
5235 0x00007088, /* EMC_FBIO_CFG5 */
5236 0x002600a4, /* EMC_CFG_DIG_DLL */
5237 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
5238 0x00014000, /* EMC_DLL_XFORM_DQS0 */
5239 0x00014000, /* EMC_DLL_XFORM_DQS1 */
5240 0x00014000, /* EMC_DLL_XFORM_DQS2 */
5241 0x00014000, /* EMC_DLL_XFORM_DQS3 */
5242 0x00014000, /* EMC_DLL_XFORM_DQS4 */
5243 0x00014000, /* EMC_DLL_XFORM_DQS5 */
5244 0x00014000, /* EMC_DLL_XFORM_DQS6 */
5245 0x00014000, /* EMC_DLL_XFORM_DQS7 */
5246 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
5247 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
5248 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
5249 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
5250 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
5251 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
5252 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
5253 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
5254 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
5255 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
5256 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
5257 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
5258 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
5259 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
5260 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
5261 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
5262 0x00050000, /* EMC_DLL_XFORM_DQ0 */
5263 0x00050000, /* EMC_DLL_XFORM_DQ1 */
5264 0x00050000, /* EMC_DLL_XFORM_DQ2 */
5265 0x00050000, /* EMC_DLL_XFORM_DQ3 */
5266 0x000002a0, /* EMC_XM2CMDPADCTRL */
5267 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
5268 0x00000000, /* EMC_XM2DQPADCTRL2 */
5269 0x77fff884, /* EMC_XM2CLKPADCTRL */
5270 0x01f1f508, /* EMC_XM2COMPPADCTRL */
5271 0x05057404, /* EMC_XM2VTTGENPADCTRL */
5272 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
5273 0x080001e8, /* EMC_XM2QUSEPADCTRL */
5274 0x08000021, /* EMC_XM2DQSPADCTRL3 */
5275 0x00000802, /* EMC_CTT_TERM_CTRL */
5276 0x00020000, /* EMC_ZCAL_INTERVAL */
5277 0x00000100, /* EMC_ZCAL_WAIT_CNT */
5278 0x018b000c, /* EMC_MRS_WAIT_CNT */
5279 0xa0f11c1c, /* EMC_AUTO_CAL_CONFIG */
5280 0x00000000, /* EMC_CTT */
5281 0x00000000, /* EMC_CTT_DURATION */
5282 0x800014d4, /* EMC_DYN_SELF_REF_CONTROL */
5283 0x00000005, /* MC_EMEM_ARB_CFG */
5284 0x8000003d, /* MC_EMEM_ARB_OUTSTANDING_REQ */
5285 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
5286 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
5287 0x00000008, /* MC_EMEM_ARB_TIMING_RC */
5288 0x00000004, /* MC_EMEM_ARB_TIMING_RAS */
5289 0x00000004, /* MC_EMEM_ARB_TIMING_FAW */
5290 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
5291 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
5292 0x00000007, /* MC_EMEM_ARB_TIMING_WAP2PRE */
5293 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
5294 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
5295 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
5296 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
5297 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
5298 0x000b0608, /* MC_EMEM_ARB_DA_COVERS */
5299 0x76850f09, /* MC_EMEM_ARB_MISC0 */
5300 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
5301 0xe8000000, /* EMC_FBIO_SPARE */
5302 0xff00ff89, /* EMC_CFG_RSV */
5303 },
5304 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
5305 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
5306 0x00000000, /* EMC_CFG.PERIODIC_QRST */
5307 0x80000321, /* Mode Register 0 */
5308 0x80100002, /* Mode Register 1 */
5309 0x80200000, /* Mode Register 2 */
5310 0x00000000, /* EMC_CFG.DYN_SELF_REF */
5311 },
5312 {
5313 0x32, /* Rev 3.2 */
5314 667000, /* SDRAM frequency */
5315 {
5316 0x00000020, /* EMC_RC */
5317 0x00000069, /* EMC_RFC */
5318 0x00000017, /* EMC_RAS */
5319 0x00000007, /* EMC_RP */
5320 0x00000005, /* EMC_R2W */
5321 0x0000000c, /* EMC_W2R */
5322 0x00000003, /* EMC_R2P */
5323 0x00000011, /* EMC_W2P */
5324 0x00000007, /* EMC_RD_RCD */
5325 0x00000007, /* EMC_WR_RCD */
5326 0x00000002, /* EMC_RRD */
5327 0x00000001, /* EMC_REXT */
5328 0x00000000, /* EMC_WEXT */
5329 0x00000007, /* EMC_WDV */
5330 0x0000000b, /* EMC_QUSE */
5331 0x00000009, /* EMC_QRST */
5332 0x0000000c, /* EMC_QSAFE */
5333 0x00000011, /* EMC_RDV */
5334 0x00001412, /* EMC_REFRESH */
5335 0x00000000, /* EMC_BURST_REFRESH_NUM */
5336 0x00000504, /* EMC_PRE_REFRESH_REQ_CNT */
5337 0x00000002, /* EMC_PDEX2WR */
5338 0x0000000e, /* EMC_PDEX2RD */
5339 0x00000001, /* EMC_PCHG2PDEN */
5340 0x00000000, /* EMC_ACT2PDEN */
5341 0x0000000c, /* EMC_AR2PDEN */
5342 0x00000016, /* EMC_RW2PDEN */
5343 0x00000072, /* EMC_TXSR */
5344 0x00000200, /* EMC_TXSRDLL */
5345 0x00000005, /* EMC_TCKE */
5346 0x00000015, /* EMC_TFAW */
5347 0x00000000, /* EMC_TRPAB */
5348 0x00000006, /* EMC_TCLKSTABLE */
5349 0x00000007, /* EMC_TCLKSTOP */
5350 0x00001453, /* EMC_TREFBW */
5351 0x0000000c, /* EMC_QUSE_EXTRA */
5352 0x00000004, /* EMC_FBIO_CFG6 */
5353 0x00000000, /* EMC_ODT_WRITE */
5354 0x00000000, /* EMC_ODT_READ */
5355 0x00005088, /* EMC_FBIO_CFG5 */
5356 0xf00b0191, /* EMC_CFG_DIG_DLL */
5357 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
5358 0x0000000a, /* EMC_DLL_XFORM_DQS0 */
5359 0x0000000a, /* EMC_DLL_XFORM_DQS1 */
5360 0x0000000a, /* EMC_DLL_XFORM_DQS2 */
5361 0x0000000a, /* EMC_DLL_XFORM_DQS3 */
5362 0x0000000a, /* EMC_DLL_XFORM_DQS4 */
5363 0x0000000a, /* EMC_DLL_XFORM_DQS5 */
5364 0x0000000a, /* EMC_DLL_XFORM_DQS6 */
5365 0x0000000a, /* EMC_DLL_XFORM_DQS7 */
5366 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
5367 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
5368 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
5369 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
5370 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
5371 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
5372 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
5373 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
5374 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
5375 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
5376 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
5377 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
5378 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
5379 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
5380 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
5381 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
5382 0x0000000a, /* EMC_DLL_XFORM_DQ0 */
5383 0x0000000a, /* EMC_DLL_XFORM_DQ1 */
5384 0x0000000a, /* EMC_DLL_XFORM_DQ2 */
5385 0x0000000a, /* EMC_DLL_XFORM_DQ3 */
5386 0x000002a0, /* EMC_XM2CMDPADCTRL */
5387 0x0700013d, /* EMC_XM2DQSPADCTRL2 */
5388 0x22220000, /* EMC_XM2DQPADCTRL2 */
5389 0x77fff884, /* EMC_XM2CLKPADCTRL */
5390 0x01f1f501, /* EMC_XM2COMPPADCTRL */
5391 0x07077404, /* EMC_XM2VTTGENPADCTRL */
5392 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
5393 0x080001e8, /* EMC_XM2QUSEPADCTRL */
5394 0x07000021, /* EMC_XM2DQSPADCTRL3 */
5395 0x00000802, /* EMC_CTT_TERM_CTRL */
5396 0x00020000, /* EMC_ZCAL_INTERVAL */
5397 0x00000100, /* EMC_ZCAL_WAIT_CNT */
5398 0x0156000c, /* EMC_MRS_WAIT_CNT */
5399 0xa0f11d1d, /* EMC_AUTO_CAL_CONFIG */
5400 0x00000000, /* EMC_CTT */
5401 0x00000000, /* EMC_CTT_DURATION */
5402 0x800028a5, /* EMC_DYN_SELF_REF_CONTROL */
5403 0x0000000a, /* MC_EMEM_ARB_CFG */
5404 0x80000079, /* MC_EMEM_ARB_OUTSTANDING_REQ */
5405 0x00000003, /* MC_EMEM_ARB_TIMING_RCD */
5406 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
5407 0x00000010, /* MC_EMEM_ARB_TIMING_RC */
5408 0x0000000b, /* MC_EMEM_ARB_TIMING_RAS */
5409 0x0000000a, /* MC_EMEM_ARB_TIMING_FAW */
5410 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
5411 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
5412 0x0000000b, /* MC_EMEM_ARB_TIMING_WAP2PRE */
5413 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
5414 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
5415 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
5416 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
5417 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
5418 0x00130b10, /* MC_EMEM_ARB_DA_COVERS */
5419 0x734a1f11, /* MC_EMEM_ARB_MISC0 */
5420 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
5421 0xe8000000, /* EMC_FBIO_SPARE */
5422 0xff00ff49, /* EMC_CFG_RSV */
5423 },
5424 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
5425 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
5426 0x00000001, /* EMC_CFG.PERIODIC_QRST */
5427 0x80000b71, /* Mode Register 0 */
5428 0x80100002, /* Mode Register 1 */
5429 0x80200018, /* Mode Register 2 */
5430 0x00000000, /* EMC_CFG.DYN_SELF_REF */
5431 },
5432};
5433
5434static const u32 pm269_bit_swap_map[32] = {
5435 /* DDR bit # SoC bit # */
5436 [0] = 0x1 << 1,
5437 [1] = 0x1 << 2,
5438 [2] = 0x1 << 3,
5439 [3] = 0x1 << 0,
5440 [4] = 0x1 << 7,
5441 [5] = 0x1 << 5,
5442 [6] = 0x1 << 6,
5443 [7] = 0x1 << 4,
5444
5445 [8] = 0x1 << 13,
5446 [9] = 0x1 << 9,
5447 [10] = 0x1 << 8,
5448 [11] = 0x1 << 12,
5449 [12] = 0x1 << 11,
5450 [13] = 0x1 << 10,
5451 [14] = 0x1 << 14,
5452 [15] = 0x1 << 15,
5453
5454 [16] = 0x1 << 20,
5455 [17] = 0x1 << 23,
5456 [18] = 0x1 << 16,
5457 [19] = 0x1 << 19,
5458 [20] = 0x1 << 18,
5459 [21] = 0x1 << 21,
5460 [22] = 0x1 << 22,
5461 [23] = 0x1 << 17,
5462
5463 [24] = 0x1 << 27,
5464 [25] = 0x1 << 30,
5465 [26] = 0x1 << 31,
5466 [27] = 0x1 << 28,
5467 [28] = 0x1 << 26,
5468 [29] = 0x1 << 25,
5469 [30] = 0x1 << 24,
5470 [31] = 0x1 << 29,
5471};
5472
5473int cardhu_emc_init(void)
5474{
5475 struct board_info board;
5476
5477 tegra_get_board_info(&board);
5478
5479 switch (board.board_id) {
5480 case BOARD_PM269:
5481 tegra_init_dram_bit_map(pm269_bit_swap_map,
5482 ARRAY_SIZE(pm269_bit_swap_map));
5483 /* fall through */
5484 case BOARD_E1257:
5485 if (MEMORY_TYPE(board.sku) == SKU_MEMORY_ELPIDA)
5486 tegra_init_emc(cardhu_emc_tables_edb8132b2ma,
5487 ARRAY_SIZE(cardhu_emc_tables_edb8132b2ma));
5488 else
5489 tegra_init_emc(cardhu_emc_tables_k4p8g304eb,
5490 ARRAY_SIZE(cardhu_emc_tables_k4p8g304eb));
5491 break;
5492
5493 case BOARD_PM305:
5494 break;
5495 case BOARD_PM311:
5496 tegra_init_emc(cardhu_emc_tables_h5tc2g_pm311,
5497 ARRAY_SIZE(cardhu_emc_tables_h5tc2g_pm311));
5498 break;
5499 default:
5500 if (tegra_get_revision() == TEGRA_REVISION_A01)
5501 tegra_init_emc(cardhu_emc_tables_h5tc2g,
5502 ARRAY_SIZE(cardhu_emc_tables_h5tc2g));
5503 else if (MEMORY_TYPE(board.sku) == SKU_MEMORY_CARDHU_1GB_1R)
5504 tegra_init_emc(cardhu_emc_tables_h5tc2g_a2,
5505 ARRAY_SIZE(cardhu_emc_tables_h5tc2g_a2));
5506 else if (MEMORY_TYPE(board.sku) ==
5507 SKU_MEMORY_CARDHU_2GB_1R_HYK0)
5508 tegra_init_emc(cardhu_emc_tables_k4b4g0846b_hyk0,
5509 ARRAY_SIZE(cardhu_emc_tables_k4b4g0846b_hyk0));
5510 else if (MEMORY_TYPE(board.sku) ==
5511 SKU_MEMORY_CARDHU_2GB_1R_HYNIX)
5512 tegra_init_emc(cardhu_emc_tables_h5tc2g_a2_2GB1R,
5513 ARRAY_SIZE(cardhu_emc_tables_h5tc2g_a2_2GB1R));
5514 break;
5515 }
5516
5517 return 0;
5518}
diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c
new file mode 100644
index 00000000000..8636a4d6743
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-panel.c
@@ -0,0 +1,1288 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-panel.c
3 *
4 * Copyright (c) 2010-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/ion.h>
23#include <linux/tegra_ion.h>
24#include <linux/gpio.h>
25#include <linux/regulator/consumer.h>
26#include <linux/resource.h>
27#include <asm/mach-types.h>
28#include <linux/platform_device.h>
29#include <linux/earlysuspend.h>
30#include <linux/pwm_backlight.h>
31#include <asm/atomic.h>
32#include <linux/nvhost.h>
33#include <mach/nvmap.h>
34#include <mach/irqs.h>
35#include <mach/iomap.h>
36#include <mach/dc.h>
37#include <mach/fb.h>
38#include <mach/smmu.h>
39
40#include "board.h"
41#include "board-cardhu.h"
42#include "devices.h"
43#include "gpio-names.h"
44
45/* Select panel to be used. */
46#define DSI_PANEL_219 1
47#define DSI_PANEL_218 0
48#define AVDD_LCD PMU_TCA6416_GPIO_PORT17
49#define DSI_PANEL_RESET 1
50
51/* Select LVDS panel resolution. 13X7 is default */
52#define PM313_LVDS_PANEL_19X12 1
53#define PM313_LVDS_PANEL_BPP 0 /* 0:24bpp, 1:18bpp */
54
55/* PM313 display board specific pins */
56#define pm313_R_FDE TEGRA_GPIO_PW0
57#define pm313_R_FB TEGRA_GPIO_PN4
58#define pm313_MODE0 TEGRA_GPIO_PZ4
59#define pm313_MODE1 TEGRA_GPIO_PW1
60#define pm313_BPP TEGRA_GPIO_PN6 /* 0:24bpp, 1:18bpp */
61#define pm313_lvds_shutdown TEGRA_GPIO_PH1
62
63/* E1247 reworked for pm269 pins */
64#define e1247_pm269_lvds_shutdown TEGRA_GPIO_PN6
65
66/* E1247 cardhu default display board pins */
67#define cardhu_lvds_shutdown TEGRA_GPIO_PL2
68
69/* common pins( backlight ) for all display boards */
70#define cardhu_bl_enb TEGRA_GPIO_PH2
71#define cardhu_bl_pwm TEGRA_GPIO_PH0
72#define cardhu_hdmi_hpd TEGRA_GPIO_PN7
73
74#if defined(DSI_PANEL_219) || defined(DSI_PANEL_218)
75#define cardhu_dsia_bl_enb TEGRA_GPIO_PW1
76#define cardhu_dsib_bl_enb TEGRA_GPIO_PW0
77#define cardhu_dsi_218_panel_reset TEGRA_GPIO_PD2
78#define cardhu_dsi_219_panel_reset TEGRA_GPIO_PW0
79#endif
80
81#ifdef CONFIG_TEGRA_DC
82static struct regulator *cardhu_hdmi_reg = NULL;
83static struct regulator *cardhu_hdmi_pll = NULL;
84static struct regulator *cardhu_hdmi_vddio = NULL;
85#endif
86
87static atomic_t sd_brightness = ATOMIC_INIT(255);
88
89#ifdef CONFIG_TEGRA_CARDHU_DSI
90static struct regulator *cardhu_dsi_reg = NULL;
91#else
92static struct regulator *cardhu_lvds_reg = NULL;
93static struct regulator *cardhu_lvds_vdd_bl = NULL;
94static struct regulator *cardhu_lvds_vdd_panel = NULL;
95#endif
96
97static struct board_info board_info;
98static struct board_info display_board_info;
99
100static tegra_dc_bl_output cardhu_bl_output_measured = {
101 0, 1, 2, 3, 4, 5, 6, 7,
102 8, 9, 10, 11, 12, 13, 14, 15,
103 16, 17, 18, 19, 20, 21, 22, 23,
104 24, 25, 26, 27, 28, 29, 30, 31,
105 32, 33, 34, 35, 36, 37, 38, 39,
106 40, 41, 42, 43, 44, 45, 46, 47,
107 48, 49, 49, 50, 51, 52, 53, 54,
108 55, 56, 57, 58, 59, 60, 61, 62,
109 63, 64, 65, 66, 67, 68, 69, 70,
110 70, 72, 73, 74, 75, 76, 77, 78,
111 79, 80, 81, 82, 83, 84, 85, 86,
112 87, 88, 89, 90, 91, 92, 93, 94,
113 95, 96, 97, 98, 99, 100, 101, 102,
114 103, 104, 105, 106, 107, 108, 110, 111,
115 112, 113, 114, 115, 116, 117, 118, 119,
116 120, 121, 122, 123, 124, 124, 125, 126,
117 127, 128, 129, 130, 131, 132, 133, 133,
118 134, 135, 136, 137, 138, 139, 140, 141,
119 142, 143, 144, 145, 146, 147, 148, 148,
120 149, 150, 151, 152, 153, 154, 155, 156,
121 157, 158, 159, 160, 161, 162, 163, 164,
122 165, 166, 167, 168, 169, 170, 171, 172,
123 173, 174, 175, 176, 177, 179, 180, 181,
124 182, 184, 185, 186, 187, 188, 189, 190,
125 191, 192, 193, 194, 195, 196, 197, 198,
126 199, 200, 201, 202, 203, 204, 205, 206,
127 207, 208, 209, 211, 212, 213, 214, 215,
128 216, 217, 218, 219, 220, 221, 222, 223,
129 224, 225, 226, 227, 228, 229, 230, 231,
130 232, 233, 234, 235, 236, 237, 238, 239,
131 240, 241, 242, 243, 244, 245, 246, 247,
132 248, 249, 250, 251, 252, 253, 254, 255
133};
134
135static p_tegra_dc_bl_output bl_output;
136
137static int cardhu_backlight_init(struct device *dev)
138{
139 int ret;
140
141 bl_output = cardhu_bl_output_measured;
142
143 if (WARN_ON(ARRAY_SIZE(cardhu_bl_output_measured) != 256))
144 pr_err("bl_output array does not have 256 elements\n");
145
146#ifndef CONFIG_TEGRA_CARDHU_DSI
147 tegra_gpio_disable(cardhu_bl_pwm);
148
149 ret = gpio_request(cardhu_bl_enb, "backlight_enb");
150 if (ret < 0)
151 return ret;
152
153 ret = gpio_direction_output(cardhu_bl_enb, 1);
154 if (ret < 0)
155 gpio_free(cardhu_bl_enb);
156 else
157 tegra_gpio_enable(cardhu_bl_enb);
158
159 return ret;
160#endif
161
162#if DSI_PANEL_218
163 /* Enable back light for DSIa panel */
164 ret = gpio_request(cardhu_dsia_bl_enb, "dsia_bl_enable");
165 if (ret < 0)
166 return ret;
167
168 ret = gpio_direction_output(cardhu_dsia_bl_enb, 1);
169 if (ret < 0)
170 gpio_free(cardhu_dsia_bl_enb);
171 else
172 tegra_gpio_enable(cardhu_dsia_bl_enb);
173
174 /* Enable back light for DSIb panel */
175 ret = gpio_request(cardhu_dsib_bl_enb, "dsib_bl_enable");
176 if (ret < 0)
177 return ret;
178
179 ret = gpio_direction_output(cardhu_dsib_bl_enb, 1);
180 if (ret < 0)
181 gpio_free(cardhu_dsib_bl_enb);
182 else
183 tegra_gpio_enable(cardhu_dsib_bl_enb);
184#endif
185
186#if DSI_PANEL_219
187 /* Enable back light for DSIa panel */
188 ret = gpio_request(cardhu_dsia_bl_enb, "dsia_bl_enable");
189 if (ret < 0)
190 return ret;
191
192 ret = gpio_direction_output(cardhu_dsia_bl_enb, 1);
193 if (ret < 0)
194 gpio_free(cardhu_dsia_bl_enb);
195 else
196 tegra_gpio_enable(cardhu_dsia_bl_enb);
197#endif
198
199 return ret;
200};
201
202static void cardhu_backlight_exit(struct device *dev)
203{
204#ifndef CONFIG_TEGRA_CARDHU_DSI
205 /* int ret; */
206 /*ret = gpio_request(cardhu_bl_enb, "backlight_enb");*/
207 gpio_set_value(cardhu_bl_enb, 0);
208 gpio_free(cardhu_bl_enb);
209 tegra_gpio_disable(cardhu_bl_enb);
210 return;
211#endif
212
213#if DSI_PANEL_218
214 /* Disable back light for DSIa panel */
215 gpio_set_value(cardhu_dsia_bl_enb, 0);
216 gpio_free(cardhu_dsia_bl_enb);
217 tegra_gpio_disable(cardhu_dsia_bl_enb);
218
219 /* Disable back light for DSIb panel */
220 gpio_set_value(cardhu_dsib_bl_enb, 0);
221 gpio_free(cardhu_dsib_bl_enb);
222 tegra_gpio_disable(cardhu_dsib_bl_enb);
223
224 gpio_set_value(cardhu_lvds_shutdown, 1);
225 mdelay(20);
226#endif
227
228#if DSI_PANEL_219
229 /* Disable back light for DSIa panel */
230 gpio_set_value(cardhu_dsia_bl_enb, 0);
231 gpio_free(cardhu_dsia_bl_enb);
232 tegra_gpio_disable(cardhu_dsia_bl_enb);
233
234 gpio_set_value(cardhu_lvds_shutdown, 1);
235 mdelay(20);
236#endif
237}
238
239static int cardhu_backlight_notify(struct device *unused, int brightness)
240{
241 int cur_sd_brightness = atomic_read(&sd_brightness);
242
243#ifndef CONFIG_TEGRA_CARDHU_DSI
244 /* Set the backlight GPIO pin mode to 'backlight_enable' */
245 gpio_set_value(cardhu_bl_enb, !!brightness);
246#elif DSI_PANEL_218
247 /* DSIa */
248 gpio_set_value(cardhu_dsia_bl_enb, !!brightness);
249
250 /* DSIb */
251 gpio_set_value(cardhu_dsib_bl_enb, !!brightness);
252#elif DSI_PANEL_219
253 /* DSIa */
254 gpio_set_value(cardhu_dsia_bl_enb, !!brightness);
255#endif
256
257 /* SD brightness is a percentage, 8-bit value. */
258 brightness = (brightness * cur_sd_brightness) / 255;
259
260 /* Apply any backlight response curve */
261 if (brightness > 255) {
262 pr_info("Error: Brightness > 255!\n");
263 } else {
264 /* This value depends on the panel.
265 Current 19X12 panel with PM313 gets
266 full brightness when the output is 0. */
267 if (display_board_info.board_id == BOARD_DISPLAY_PM313)
268 brightness = 255 - bl_output[brightness];
269 else
270 brightness = bl_output[brightness];
271 }
272
273 return brightness;
274}
275
276static int cardhu_disp1_check_fb(struct device *dev, struct fb_info *info);
277
278static struct platform_pwm_backlight_data cardhu_backlight_data = {
279 .pwm_id = 0,
280 .max_brightness = 255,
281 .dft_brightness = 224,
282 .pwm_period_ns = 1000000,
283 .init = cardhu_backlight_init,
284 .exit = cardhu_backlight_exit,
285 .notify = cardhu_backlight_notify,
286 /* Only toggle backlight on fb blank notifications for disp1 */
287 .check_fb = cardhu_disp1_check_fb,
288};
289
290static struct platform_device cardhu_backlight_device = {
291 .name = "pwm-backlight",
292 .id = -1,
293 .dev = {
294 .platform_data = &cardhu_backlight_data,
295 },
296};
297
298#ifndef CONFIG_TEGRA_CARDHU_DSI
299static int cardhu_panel_enable(void)
300{
301 if (cardhu_lvds_reg == NULL) {
302 cardhu_lvds_reg = regulator_get(NULL, "vdd_lvds");
303 if (WARN_ON(IS_ERR(cardhu_lvds_reg)))
304 pr_err("%s: couldn't get regulator vdd_lvds: %ld\n",
305 __func__, PTR_ERR(cardhu_lvds_reg));
306 else
307 regulator_enable(cardhu_lvds_reg);
308 }
309
310 if (cardhu_lvds_vdd_bl == NULL) {
311 cardhu_lvds_vdd_bl = regulator_get(NULL, "vdd_backlight");
312 if (WARN_ON(IS_ERR(cardhu_lvds_vdd_bl)))
313 pr_err("%s: couldn't get regulator vdd_backlight: %ld\n",
314 __func__, PTR_ERR(cardhu_lvds_vdd_bl));
315 else
316 regulator_enable(cardhu_lvds_vdd_bl);
317 }
318
319 if (cardhu_lvds_vdd_panel == NULL) {
320 cardhu_lvds_vdd_panel = regulator_get(NULL, "vdd_lcd_panel");
321 if (WARN_ON(IS_ERR(cardhu_lvds_vdd_panel)))
322 pr_err("%s: couldn't get regulator vdd_lcd_panel: %ld\n",
323 __func__, PTR_ERR(cardhu_lvds_vdd_panel));
324 else
325 regulator_enable(cardhu_lvds_vdd_panel);
326 }
327
328 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
329 /* lvds configuration */
330 gpio_set_value(pm313_R_FDE, 1);
331 gpio_set_value(pm313_R_FB, 1);
332 gpio_set_value(pm313_MODE0, 1);
333 gpio_set_value(pm313_MODE1, 0);
334 gpio_set_value(pm313_BPP, PM313_LVDS_PANEL_BPP);
335
336 /* FIXME : it may require more or less delay for latching
337 values correctly before enabling RGB2LVDS */
338 mdelay(100);
339 gpio_set_value(pm313_lvds_shutdown, 1);
340 } else if ((display_board_info.board_id == BOARD_DISPLAY_E1247 &&
341 board_info.board_id == BOARD_PM269) ||
342 (board_info.board_id == BOARD_E1257) ||
343 (board_info.board_id == BOARD_PM305) ||
344 (board_info.board_id == BOARD_PM311))
345 gpio_set_value(e1247_pm269_lvds_shutdown, 1);
346 else
347 gpio_set_value(cardhu_lvds_shutdown, 1);
348
349 return 0;
350}
351
352static int cardhu_panel_disable(void)
353{
354 regulator_disable(cardhu_lvds_reg);
355 regulator_put(cardhu_lvds_reg);
356 cardhu_lvds_reg = NULL;
357
358 regulator_disable(cardhu_lvds_vdd_bl);
359 regulator_put(cardhu_lvds_vdd_bl);
360 cardhu_lvds_vdd_bl = NULL;
361
362 regulator_disable(cardhu_lvds_vdd_panel);
363 regulator_put(cardhu_lvds_vdd_panel);
364
365 cardhu_lvds_vdd_panel= NULL;
366
367 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
368 gpio_set_value(pm313_lvds_shutdown, 0);
369 } else if ((display_board_info.board_id == BOARD_DISPLAY_E1247 &&
370 board_info.board_id == BOARD_PM269) ||
371 (board_info.board_id == BOARD_E1257) ||
372 (board_info.board_id == BOARD_PM305) ||
373 (board_info.board_id == BOARD_PM311)) {
374 gpio_set_value(e1247_pm269_lvds_shutdown, 0);
375 } else {
376 gpio_set_value(cardhu_lvds_shutdown, 0);
377 }
378 return 0;
379}
380#endif
381
382#ifdef CONFIG_TEGRA_DC
383static int cardhu_hdmi_vddio_enable(void)
384{
385 int ret;
386 if (!cardhu_hdmi_vddio) {
387 cardhu_hdmi_vddio = regulator_get(NULL, "vdd_hdmi_con");
388 if (IS_ERR_OR_NULL(cardhu_hdmi_vddio)) {
389 ret = PTR_ERR(cardhu_hdmi_vddio);
390 pr_err("hdmi: couldn't get regulator vdd_hdmi_con\n");
391 cardhu_hdmi_vddio = NULL;
392 return ret;
393 }
394 }
395 ret = regulator_enable(cardhu_hdmi_vddio);
396 if (ret < 0) {
397 pr_err("hdmi: couldn't enable regulator vdd_hdmi_con\n");
398 regulator_put(cardhu_hdmi_vddio);
399 cardhu_hdmi_vddio = NULL;
400 return ret;
401 }
402 return ret;
403}
404
405static int cardhu_hdmi_vddio_disable(void)
406{
407 if (cardhu_hdmi_vddio) {
408 regulator_disable(cardhu_hdmi_vddio);
409 regulator_put(cardhu_hdmi_vddio);
410 cardhu_hdmi_vddio = NULL;
411 }
412 return 0;
413}
414
415static int cardhu_hdmi_enable(void)
416{
417 int ret;
418 if (!cardhu_hdmi_reg) {
419 cardhu_hdmi_reg = regulator_get(NULL, "avdd_hdmi");
420 if (IS_ERR_OR_NULL(cardhu_hdmi_reg)) {
421 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
422 cardhu_hdmi_reg = NULL;
423 return PTR_ERR(cardhu_hdmi_reg);
424 }
425 }
426 ret = regulator_enable(cardhu_hdmi_reg);
427 if (ret < 0) {
428 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
429 return ret;
430 }
431 if (!cardhu_hdmi_pll) {
432 cardhu_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll");
433 if (IS_ERR_OR_NULL(cardhu_hdmi_pll)) {
434 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
435 cardhu_hdmi_pll = NULL;
436 regulator_put(cardhu_hdmi_reg);
437 cardhu_hdmi_reg = NULL;
438 return PTR_ERR(cardhu_hdmi_pll);
439 }
440 }
441 ret = regulator_enable(cardhu_hdmi_pll);
442 if (ret < 0) {
443 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
444 return ret;
445 }
446 return 0;
447}
448
449static int cardhu_hdmi_disable(void)
450{
451 regulator_disable(cardhu_hdmi_reg);
452 regulator_put(cardhu_hdmi_reg);
453 cardhu_hdmi_reg = NULL;
454
455 regulator_disable(cardhu_hdmi_pll);
456 regulator_put(cardhu_hdmi_pll);
457 cardhu_hdmi_pll = NULL;
458 return 0;
459}
460
461static struct resource cardhu_disp1_resources[] = {
462 {
463 .name = "irq",
464 .start = INT_DISPLAY_GENERAL,
465 .end = INT_DISPLAY_GENERAL,
466 .flags = IORESOURCE_IRQ,
467 },
468 {
469 .name = "regs",
470 .start = TEGRA_DISPLAY_BASE,
471 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
472 .flags = IORESOURCE_MEM,
473 },
474 {
475 .name = "fbmem",
476 .start = 0, /* Filled in by cardhu_panel_init() */
477 .end = 0, /* Filled in by cardhu_panel_init() */
478 .flags = IORESOURCE_MEM,
479 },
480#ifdef CONFIG_TEGRA_DSI_INSTANCE_1
481 {
482 .name = "dsi_regs",
483 .start = TEGRA_DSIB_BASE,
484 .end = TEGRA_DSIB_BASE + TEGRA_DSIB_SIZE - 1,
485 .flags = IORESOURCE_MEM,
486 },
487#else
488 {
489 .name = "dsi_regs",
490 .start = TEGRA_DSI_BASE,
491 .end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
492 .flags = IORESOURCE_MEM,
493 },
494#endif
495};
496
497static struct resource cardhu_disp2_resources[] = {
498 {
499 .name = "irq",
500 .start = INT_DISPLAY_B_GENERAL,
501 .end = INT_DISPLAY_B_GENERAL,
502 .flags = IORESOURCE_IRQ,
503 },
504 {
505 .name = "regs",
506 .start = TEGRA_DISPLAY2_BASE,
507 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
508 .flags = IORESOURCE_MEM,
509 },
510 {
511 .name = "fbmem",
512 .flags = IORESOURCE_MEM,
513 .start = 0,
514 .end = 0,
515 },
516 {
517 .name = "hdmi_regs",
518 .start = TEGRA_HDMI_BASE,
519 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
520 .flags = IORESOURCE_MEM,
521 },
522};
523#endif
524
525#ifndef CONFIG_TEGRA_CARDHU_DSI
526static struct tegra_dc_mode panel_19X12_modes[] = {
527 {
528 .pclk = 154000000,
529 .h_ref_to_sync = 11,
530 .v_ref_to_sync = 1,
531 .h_sync_width = 32,
532 .v_sync_width = 6,
533 .h_back_porch = 80,
534 .v_back_porch = 26,
535 .h_active = 1920,
536 .v_active = 1200,
537 .h_front_porch = 48,
538 .v_front_porch = 3,
539 },
540};
541
542static struct tegra_dc_mode cardhu_panel_modes[] = {
543 {
544 /* 1366x768@60Hz */
545 .pclk = 74180000,
546 .h_ref_to_sync = 1,
547 .v_ref_to_sync = 1,
548 .h_sync_width = 30,
549 .v_sync_width = 5,
550 .h_back_porch = 52,
551 .v_back_porch = 20,
552 .h_active = 1366,
553 .v_active = 768,
554 .h_front_porch = 64,
555 .v_front_porch = 25,
556 },
557};
558
559static struct tegra_dc_mode cardhu_panel_modes_55hz[] = {
560 {
561 /* 1366x768p 55Hz */
562 .pclk = 68000000,
563 .h_ref_to_sync = 0,
564 .v_ref_to_sync = 12,
565 .h_sync_width = 30,
566 .v_sync_width = 5,
567 .h_back_porch = 52,
568 .v_back_porch = 20,
569 .h_active = 1366,
570 .v_active = 768,
571 .h_front_porch = 64,
572 .v_front_porch = 25,
573 },
574};
575#endif
576
577static struct tegra_dc_sd_settings cardhu_sd_settings = {
578 .enable = 1, /* enabled by default. */
579 .use_auto_pwm = false,
580 .hw_update_delay = 0,
581 .bin_width = -1,
582 .aggressiveness = 1,
583 .phase_in_adjustments = true,
584 .use_vid_luma = false,
585 /* Default video coefficients */
586 .coeff = {5, 9, 2},
587 .fc = {0, 0},
588 /* Immediate backlight changes */
589 .blp = {1024, 255},
590 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
591 /* Default BL TF */
592 .bltf = {
593 {
594 {57, 65, 74, 83},
595 {93, 103, 114, 126},
596 {138, 151, 165, 179},
597 {194, 209, 225, 242},
598 },
599 {
600 {58, 66, 75, 84},
601 {94, 105, 116, 127},
602 {140, 153, 166, 181},
603 {196, 211, 227, 244},
604 },
605 {
606 {60, 68, 77, 87},
607 {97, 107, 119, 130},
608 {143, 156, 170, 184},
609 {199, 215, 231, 248},
610 },
611 {
612 {64, 73, 82, 91},
613 {102, 113, 124, 137},
614 {149, 163, 177, 192},
615 {207, 223, 240, 255},
616 },
617 },
618 /* Default LUT */
619 .lut = {
620 {
621 {250, 250, 250},
622 {194, 194, 194},
623 {149, 149, 149},
624 {113, 113, 113},
625 {82, 82, 82},
626 {56, 56, 56},
627 {34, 34, 34},
628 {15, 15, 15},
629 {0, 0, 0},
630 },
631 {
632 {246, 246, 246},
633 {191, 191, 191},
634 {147, 147, 147},
635 {111, 111, 111},
636 {80, 80, 80},
637 {55, 55, 55},
638 {33, 33, 33},
639 {14, 14, 14},
640 {0, 0, 0},
641 },
642 {
643 {239, 239, 239},
644 {185, 185, 185},
645 {142, 142, 142},
646 {107, 107, 107},
647 {77, 77, 77},
648 {52, 52, 52},
649 {30, 30, 30},
650 {12, 12, 12},
651 {0, 0, 0},
652 },
653 {
654 {224, 224, 224},
655 {173, 173, 173},
656 {133, 133, 133},
657 {99, 99, 99},
658 {70, 70, 70},
659 {46, 46, 46},
660 {25, 25, 25},
661 {7, 7, 7},
662 {0, 0, 0},
663 },
664 },
665 .sd_brightness = &sd_brightness,
666 .bl_device = &cardhu_backlight_device,
667};
668
669#ifdef CONFIG_TEGRA_DC
670#ifndef CONFIG_TEGRA_CARDHU_DSI
671static struct tegra_fb_data cardhu_fb_data = {
672 .win = 0,
673 .xres = 1366,
674 .yres = 768,
675 .bits_per_pixel = 32,
676 .flags = TEGRA_FB_FLIP_ON_PROBE,
677};
678#endif
679
680static struct tegra_fb_data cardhu_hdmi_fb_data = {
681 .win = 0,
682 .xres = 1366,
683 .yres = 768,
684 .bits_per_pixel = 32,
685 .flags = TEGRA_FB_FLIP_ON_PROBE,
686};
687
688static struct tegra_dc_out cardhu_disp2_out = {
689 .type = TEGRA_DC_OUT_HDMI,
690 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
691
692 .dcc_bus = 3,
693 .hotplug_gpio = cardhu_hdmi_hpd,
694
695 .max_pixclock = KHZ2PICOS(148500),
696
697 .align = TEGRA_DC_ALIGN_MSB,
698 .order = TEGRA_DC_ORDER_RED_BLUE,
699
700 .enable = cardhu_hdmi_enable,
701 .disable = cardhu_hdmi_disable,
702
703 .postsuspend = cardhu_hdmi_vddio_disable,
704 .hotplug_init = cardhu_hdmi_vddio_enable,
705};
706
707static struct tegra_dc_platform_data cardhu_disp2_pdata = {
708 .flags = 0,
709 .default_out = &cardhu_disp2_out,
710 .fb = &cardhu_hdmi_fb_data,
711 .emc_clk_rate = 300000000,
712};
713#endif
714
715#ifdef CONFIG_TEGRA_CARDHU_DSI
716static int cardhu_dsi_panel_enable(void)
717{
718 int ret;
719
720 if (cardhu_dsi_reg == NULL) {
721 cardhu_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
722 if (IS_ERR_OR_NULL(cardhu_dsi_reg)) {
723 pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
724 cardhu_dsi_reg = NULL;
725 return PTR_ERR(cardhu_dsi_reg);
726 }
727 }
728 regulator_enable(cardhu_dsi_reg);
729
730 ret = gpio_request(AVDD_LCD, "avdd_lcd");
731 if (ret < 0)
732 gpio_free(AVDD_LCD);
733 ret = gpio_direction_output(AVDD_LCD, 1);
734 if (ret < 0)
735 gpio_free(AVDD_LCD);
736 else
737 tegra_gpio_enable(AVDD_LCD);
738
739#if DSI_PANEL_219
740
741 ret = gpio_request(cardhu_bl_pwm, "bl_pwm");
742 if (ret < 0)
743 return ret;
744 ret = gpio_direction_output(cardhu_bl_pwm, 0);
745 if (ret < 0) {
746 gpio_free(cardhu_bl_pwm);
747 return ret;
748 } else
749 tegra_gpio_enable(cardhu_bl_pwm);
750
751 ret = gpio_request(cardhu_bl_enb, "bl_enb");
752 if (ret < 0)
753 return ret;
754 ret = gpio_direction_output(cardhu_bl_enb, 0);
755 if (ret < 0) {
756 gpio_free(cardhu_bl_enb);
757 return ret;
758 } else
759 tegra_gpio_enable(cardhu_bl_enb);
760
761 gpio_set_value(cardhu_lvds_shutdown, 1);
762 mdelay(20);
763 gpio_set_value(cardhu_bl_pwm, 1);
764 mdelay(10);
765 gpio_set_value(cardhu_bl_enb, 1);
766 mdelay(15);
767#endif
768
769#if DSI_PANEL_RESET
770#if DSI_PANEL_218
771 ret = gpio_request(cardhu_dsi_218_panel_reset, "dsi_panel_reset");
772 if (ret < 0) {
773 return ret;
774 }
775 ret = gpio_direction_output(cardhu_dsi_218_panel_reset, 0);
776 if (ret < 0) {
777 gpio_free(cardhu_dsi_218_panel_reset);
778 return ret;
779 } else
780 tegra_gpio_enable(cardhu_dsi_218_panel_reset);
781
782 gpio_set_value(cardhu_dsi_218_panel_reset, 1);
783 gpio_set_value(cardhu_dsi_218_panel_reset, 0);
784 mdelay(2);
785 gpio_set_value(cardhu_dsi_218_panel_reset, 1);
786 mdelay(2);
787#endif
788
789#if DSI_PANEL_219
790 ret = gpio_request(cardhu_dsi_219_panel_reset, "dsi_panel_reset");
791 if (ret < 0)
792 return ret;
793 ret = gpio_direction_output(cardhu_dsi_219_panel_reset, 0);
794 if (ret < 0) {
795 gpio_free(cardhu_dsi_219_panel_reset);
796 return ret;
797 } else
798 tegra_gpio_enable(cardhu_dsi_219_panel_reset);
799
800 gpio_set_value(cardhu_dsi_219_panel_reset, 0);
801 gpio_set_value(cardhu_dsi_219_panel_reset, 1);
802 mdelay(10);
803 gpio_set_value(cardhu_dsi_219_panel_reset, 0);
804 mdelay(10);
805 gpio_set_value(cardhu_dsi_219_panel_reset, 1);
806 mdelay(15);
807#endif
808#endif
809
810 return 0;
811}
812
813static int cardhu_dsi_panel_disable(void)
814{
815 int err;
816
817 err = 0;
818 printk(KERN_INFO "DSI panel disable\n");
819
820#if DSI_PANEL_219
821 tegra_gpio_disable(cardhu_dsi_219_panel_reset);
822 gpio_free(cardhu_dsi_219_panel_reset);
823 tegra_gpio_disable(cardhu_bl_enb);
824 gpio_free(cardhu_bl_enb);
825 tegra_gpio_disable(cardhu_bl_pwm);
826 gpio_free(cardhu_bl_pwm);
827 tegra_gpio_disable(cardhu_lvds_shutdown);
828 gpio_free(cardhu_lvds_shutdown);
829#endif
830
831#if DSI_PANEL_218
832 tegra_gpio_disable(cardhu_dsi_218_panel_reset);
833 gpio_free(cardhu_dsi_218_panel_reset);
834#endif
835
836 return err;
837}
838
839static int cardhu_dsi_panel_postsuspend(void)
840{
841 int err;
842
843 err = 0;
844 printk(KERN_INFO "DSI panel postsuspend\n");
845
846 if (cardhu_dsi_reg) {
847 err = regulator_disable(cardhu_dsi_reg);
848 if (err < 0)
849 printk(KERN_ERR
850 "DSI regulator avdd_dsi_csi disable failed\n");
851 regulator_put(cardhu_dsi_reg);
852 cardhu_dsi_reg = NULL;
853 }
854
855#if DSI_PANEL_218
856 tegra_gpio_disable(AVDD_LCD);
857 gpio_free(AVDD_LCD);
858#endif
859
860 return err;
861}
862
863static struct tegra_dsi_cmd dsi_init_cmd[] = {
864 DSI_CMD_SHORT(0x05, 0x11, 0x00),
865 DSI_DLY_MS(150),
866 DSI_CMD_SHORT(0x05, 0x29, 0x00),
867 DSI_DLY_MS(20),
868};
869
870static struct tegra_dsi_cmd dsi_suspend_cmd[] = {
871 DSI_CMD_SHORT(0x05, 0x28, 0x00),
872 DSI_DLY_MS(20),
873 DSI_CMD_SHORT(0x05, 0x10, 0x00),
874 DSI_DLY_MS(5),
875};
876
877struct tegra_dsi_out cardhu_dsi = {
878 .n_data_lanes = 2,
879 .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
880 .refresh_rate = 60,
881 .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
882
883 .panel_has_frame_buffer = true,
884#ifdef CONFIG_TEGRA_DSI_INSTANCE_1
885 .dsi_instance = 1,
886#else
887 .dsi_instance = 0,
888#endif
889 .panel_reset = DSI_PANEL_RESET,
890 .power_saving_suspend = true,
891
892 .n_init_cmd = ARRAY_SIZE(dsi_init_cmd),
893 .dsi_init_cmd = dsi_init_cmd,
894
895 .n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd),
896 .dsi_suspend_cmd = dsi_suspend_cmd,
897
898 .video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
899 .lp_cmd_mode_freq_khz = 430000,
900};
901
902static struct tegra_dc_mode cardhu_dsi_modes[] = {
903#if DSI_PANEL_219
904 {
905 .pclk = 10000000,
906 .h_ref_to_sync = 4,
907 .v_ref_to_sync = 1,
908 .h_sync_width = 16,
909 .v_sync_width = 1,
910 .h_back_porch = 32,
911 .v_back_porch = 1,
912 .h_active = 540,
913 .v_active = 960,
914 .h_front_porch = 32,
915 .v_front_porch = 2,
916 },
917#endif
918
919#if DSI_PANEL_218
920 {
921 .pclk = 323000000,
922 .h_ref_to_sync = 11,
923 .v_ref_to_sync = 1,
924 .h_sync_width = 16,
925 .v_sync_width = 4,
926 .h_back_porch = 16,
927 .v_back_porch = 4,
928 .h_active = 864,
929 .v_active = 480,
930 .h_front_porch = 16,
931 .v_front_porch = 4,
932 },
933#endif
934
935};
936
937
938static struct tegra_fb_data cardhu_dsi_fb_data = {
939#if DSI_PANEL_219
940 .win = 0,
941 .xres = 540,
942 .yres = 960,
943 .bits_per_pixel = 32,
944#endif
945
946#if DSI_PANEL_218
947 .win = 0,
948 .xres = 864,
949 .yres = 480,
950 .bits_per_pixel = 32,
951#endif
952 .flags = TEGRA_FB_FLIP_ON_PROBE,
953};
954#endif
955
956static struct tegra_dc_out cardhu_disp1_out = {
957 .align = TEGRA_DC_ALIGN_MSB,
958 .order = TEGRA_DC_ORDER_RED_BLUE,
959 .sd_settings = &cardhu_sd_settings,
960
961#ifndef CONFIG_TEGRA_CARDHU_DSI
962 .parent_clk = "pll_p",
963 .parent_clk_backup = "pll_d2_out0",
964
965 .type = TEGRA_DC_OUT_RGB,
966#ifdef CONFIG_TEGRA_LVDS_18_BITS
967 .depth = 18,
968#endif
969#ifdef CONFIG_TEGRA_LVDS_24_BITS
970 .depth = 24,
971#endif
972 .dither = TEGRA_DC_ORDERED_DITHER,
973
974 .modes = cardhu_panel_modes,
975 .n_modes = ARRAY_SIZE(cardhu_panel_modes),
976
977 .enable = cardhu_panel_enable,
978 .disable = cardhu_panel_disable,
979#else
980 .type = TEGRA_DC_OUT_DSI,
981
982 .modes = cardhu_dsi_modes,
983 .n_modes = ARRAY_SIZE(cardhu_dsi_modes),
984
985 .dsi = &cardhu_dsi,
986
987 .enable = cardhu_dsi_panel_enable,
988 .disable = cardhu_dsi_panel_disable,
989 .postsuspend = cardhu_dsi_panel_postsuspend,
990#endif
991};
992
993#ifdef CONFIG_TEGRA_DC
994static struct tegra_dc_platform_data cardhu_disp1_pdata = {
995 .flags = TEGRA_DC_FLAG_ENABLED,
996 .default_out = &cardhu_disp1_out,
997 .emc_clk_rate = 300000000,
998#ifndef CONFIG_TEGRA_CARDHU_DSI
999 .fb = &cardhu_fb_data,
1000#else
1001 .fb = &cardhu_dsi_fb_data,
1002#endif
1003};
1004
1005static struct nvhost_device cardhu_disp1_device = {
1006 .name = "tegradc",
1007 .id = 0,
1008 .resource = cardhu_disp1_resources,
1009 .num_resources = ARRAY_SIZE(cardhu_disp1_resources),
1010 .dev = {
1011 .platform_data = &cardhu_disp1_pdata,
1012 },
1013};
1014
1015static int cardhu_disp1_check_fb(struct device *dev, struct fb_info *info)
1016{
1017 return info->device == &cardhu_disp1_device.dev;
1018}
1019
1020static struct nvhost_device cardhu_disp2_device = {
1021 .name = "tegradc",
1022 .id = 1,
1023 .resource = cardhu_disp2_resources,
1024 .num_resources = ARRAY_SIZE(cardhu_disp2_resources),
1025 .dev = {
1026 .platform_data = &cardhu_disp2_pdata,
1027 },
1028};
1029#else
1030static int cardhu_disp1_check_fb(struct device *dev, struct fb_info *info)
1031{
1032 return 0;
1033}
1034#endif
1035
1036#if defined(CONFIG_TEGRA_NVMAP)
1037static struct nvmap_platform_carveout cardhu_carveouts[] = {
1038 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
1039 [1] = {
1040 .name = "generic-0",
1041 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
1042 .base = 0, /* Filled in by cardhu_panel_init() */
1043 .size = 0, /* Filled in by cardhu_panel_init() */
1044 .buddy_size = SZ_32K,
1045 },
1046};
1047
1048static struct nvmap_platform_data cardhu_nvmap_data = {
1049 .carveouts = cardhu_carveouts,
1050 .nr_carveouts = ARRAY_SIZE(cardhu_carveouts),
1051};
1052
1053static struct platform_device cardhu_nvmap_device = {
1054 .name = "tegra-nvmap",
1055 .id = -1,
1056 .dev = {
1057 .platform_data = &cardhu_nvmap_data,
1058 },
1059};
1060#endif
1061
1062#if defined(CONFIG_ION_TEGRA)
1063
1064static struct platform_device tegra_iommu_device = {
1065 .name = "tegra_iommu_device",
1066 .id = -1,
1067 .dev = {
1068 .platform_data = (void *)((1 << HWGRP_COUNT) - 1),
1069 },
1070};
1071
1072static struct ion_platform_data tegra_ion_data = {
1073 .nr = 4,
1074 .heaps = {
1075 {
1076 .type = ION_HEAP_TYPE_CARVEOUT,
1077 .id = TEGRA_ION_HEAP_CARVEOUT,
1078 .name = "carveout",
1079 .base = 0,
1080 .size = 0,
1081 },
1082 {
1083 .type = ION_HEAP_TYPE_CARVEOUT,
1084 .id = TEGRA_ION_HEAP_IRAM,
1085 .name = "iram",
1086 .base = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
1087 .size = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
1088 },
1089 {
1090 .type = ION_HEAP_TYPE_CARVEOUT,
1091 .id = TEGRA_ION_HEAP_VPR,
1092 .name = "vpr",
1093 .base = 0,
1094 .size = 0,
1095 },
1096 {
1097 .type = ION_HEAP_TYPE_IOMMU,
1098 .id = TEGRA_ION_HEAP_IOMMU,
1099 .name = "iommu",
1100 .base = TEGRA_SMMU_BASE,
1101 .size = TEGRA_SMMU_SIZE,
1102 .priv = &tegra_iommu_device.dev,
1103 },
1104 },
1105};
1106
1107static struct platform_device tegra_ion_device = {
1108 .name = "ion-tegra",
1109 .id = -1,
1110 .dev = {
1111 .platform_data = &tegra_ion_data,
1112 },
1113};
1114#endif
1115
1116static struct platform_device *cardhu_gfx_devices[] __initdata = {
1117#if defined(CONFIG_TEGRA_NVMAP)
1118 &cardhu_nvmap_device,
1119#endif
1120#if defined(CONFIG_ION_TEGRA)
1121 &tegra_ion_device,
1122#endif
1123 &tegra_pwfm0_device,
1124 &cardhu_backlight_device,
1125};
1126
1127
1128#ifdef CONFIG_HAS_EARLYSUSPEND
1129/* put early_suspend/late_resume handlers here for the display in order
1130 * to keep the code out of the display driver, keeping it closer to upstream
1131 */
1132struct early_suspend cardhu_panel_early_suspender;
1133
1134static void cardhu_panel_early_suspend(struct early_suspend *h)
1135{
1136 /* power down LCD, add use a black screen for HDMI */
1137 if (num_registered_fb > 0)
1138 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
1139 if (num_registered_fb > 1)
1140 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
1141}
1142
1143static void cardhu_panel_late_resume(struct early_suspend *h)
1144{
1145 unsigned i;
1146 for (i = 0; i < num_registered_fb; i++)
1147 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
1148}
1149#endif
1150
1151int __init cardhu_panel_init(void)
1152{
1153 int err;
1154 struct resource __maybe_unused *res;
1155
1156 tegra_get_board_info(&board_info);
1157 tegra_get_display_board_info(&display_board_info);
1158
1159#if defined(CONFIG_TEGRA_NVMAP)
1160 cardhu_carveouts[1].base = tegra_carveout_start;
1161 cardhu_carveouts[1].size = tegra_carveout_size;
1162#endif
1163
1164#if defined(CONFIG_ION_TEGRA)
1165 tegra_ion_data.heaps[0].base = tegra_carveout_start;
1166 tegra_ion_data.heaps[0].size = tegra_carveout_size;
1167#endif
1168
1169#if defined(CONFIG_TEGRA_DC) && !defined(CONFIG_TEGRA_CARDHU_DSI)
1170 if (board_info.board_id == BOARD_E1291 &&
1171 ((board_info.sku & SKU_TOUCHSCREEN_MECH_FIX) == 0)) {
1172 /* use 55Hz panel timings to reduce noise on sensitive touch */
1173 printk("Using cardhu_panel_modes_55hz\n");
1174 cardhu_disp1_out.modes = cardhu_panel_modes_55hz;
1175 cardhu_disp1_out.n_modes = ARRAY_SIZE(cardhu_panel_modes_55hz);
1176 }
1177
1178 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
1179 /* initialize the values */
1180#if defined(PM313_LVDS_PANEL_19X12)
1181 cardhu_disp1_out.modes = panel_19X12_modes;
1182 cardhu_disp1_out.n_modes = ARRAY_SIZE(panel_19X12_modes);
1183 cardhu_disp1_out.parent_clk = "pll_d_out0";
1184#if (PM313_LVDS_PANEL_BPP == 1)
1185 cardhu_disp1_out.depth = 18;
1186#else
1187 cardhu_disp1_out.depth = 24;
1188#endif
1189 cardhu_fb_data.xres = 1920;
1190 cardhu_fb_data.yres = 1200;
1191
1192 cardhu_disp2_out.parent_clk = "pll_d2_out0";
1193 cardhu_hdmi_fb_data.xres = 1920;
1194 cardhu_hdmi_fb_data.yres = 1200;
1195#endif
1196
1197 /* lvds configuration */
1198 err = gpio_request(pm313_R_FDE, "R_FDE");
1199 err |= gpio_direction_output(pm313_R_FDE, 1);
1200 tegra_gpio_enable(pm313_R_FDE);
1201
1202 err |= gpio_request(pm313_R_FB, "R_FB");
1203 err |= gpio_direction_output(pm313_R_FB, 1);
1204 tegra_gpio_enable(pm313_R_FB);
1205
1206 err |= gpio_request(pm313_MODE0, "MODE0");
1207 err |= gpio_direction_output(pm313_MODE0, 1);
1208 tegra_gpio_enable(pm313_MODE0);
1209
1210 err |= gpio_request(pm313_MODE1, "MODE1");
1211 err |= gpio_direction_output(pm313_MODE1, 0);
1212 tegra_gpio_enable(pm313_MODE1);
1213
1214 err |= gpio_request(pm313_BPP, "BPP");
1215 err |= gpio_direction_output(pm313_BPP, PM313_LVDS_PANEL_BPP);
1216 tegra_gpio_enable(pm313_BPP);
1217
1218 err = gpio_request(pm313_lvds_shutdown, "lvds_shutdown");
1219 /* free ride provided by bootloader */
1220 err |= gpio_direction_output(pm313_lvds_shutdown, 1);
1221 tegra_gpio_enable(pm313_lvds_shutdown);
1222
1223 if (err)
1224 printk(KERN_ERR "ERROR(s) in LVDS configuration\n");
1225 } else if ((display_board_info.board_id == BOARD_DISPLAY_E1247 &&
1226 board_info.board_id == BOARD_PM269) ||
1227 (board_info.board_id == BOARD_E1257) ||
1228 (board_info.board_id == BOARD_PM305) ||
1229 (board_info.board_id == BOARD_PM311)) {
1230 gpio_request(e1247_pm269_lvds_shutdown, "lvds_shutdown");
1231 gpio_direction_output(e1247_pm269_lvds_shutdown, 1);
1232 tegra_gpio_enable(e1247_pm269_lvds_shutdown);
1233 } else {
1234 gpio_request(cardhu_lvds_shutdown, "lvds_shutdown");
1235 gpio_direction_output(cardhu_lvds_shutdown, 1);
1236 tegra_gpio_enable(cardhu_lvds_shutdown);
1237 }
1238#endif
1239
1240 tegra_gpio_enable(cardhu_hdmi_hpd);
1241 gpio_request(cardhu_hdmi_hpd, "hdmi_hpd");
1242 gpio_direction_input(cardhu_hdmi_hpd);
1243
1244#ifdef CONFIG_HAS_EARLYSUSPEND
1245 cardhu_panel_early_suspender.suspend = cardhu_panel_early_suspend;
1246 cardhu_panel_early_suspender.resume = cardhu_panel_late_resume;
1247 cardhu_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
1248 register_early_suspend(&cardhu_panel_early_suspender);
1249#endif
1250
1251#ifdef CONFIG_TEGRA_GRHOST
1252 err = nvhost_device_register(&tegra_grhost_device);
1253 if (err)
1254 return err;
1255#endif
1256
1257 err = platform_add_devices(cardhu_gfx_devices,
1258 ARRAY_SIZE(cardhu_gfx_devices));
1259
1260#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
1261 res = nvhost_get_resource_byname(&cardhu_disp1_device,
1262 IORESOURCE_MEM, "fbmem");
1263 res->start = tegra_fb_start;
1264 res->end = tegra_fb_start + tegra_fb_size - 1;
1265#endif
1266
1267 /* Copy the bootloader fb to the fb. */
1268 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
1269 min(tegra_fb_size, tegra_bootloader_fb_size));
1270
1271#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
1272 if (!err)
1273 err = nvhost_device_register(&cardhu_disp1_device);
1274
1275 res = nvhost_get_resource_byname(&cardhu_disp2_device,
1276 IORESOURCE_MEM, "fbmem");
1277 res->start = tegra_fb2_start;
1278 res->end = tegra_fb2_start + tegra_fb2_size - 1;
1279 if (!err)
1280 err = nvhost_device_register(&cardhu_disp2_device);
1281#endif
1282
1283#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
1284 if (!err)
1285 err = nvhost_device_register(&nvavp_device);
1286#endif
1287 return err;
1288}
diff --git a/arch/arm/mach-tegra/board-cardhu-pinmux.c b/arch/arm/mach-tegra/board-cardhu-pinmux.c
new file mode 100644
index 00000000000..de6f8d269b5
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-pinmux.c
@@ -0,0 +1,796 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-pinmux.c
3 *
4 * Copyright (C) 2010 NVIDIA Corporation
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 <mach/pinmux.h>
20#include "board.h"
21#include "board-cardhu.h"
22#include "gpio-names.h"
23
24#define DEFAULT_DRIVE(_name) \
25 { \
26 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
27 .hsm = TEGRA_HSM_DISABLE, \
28 .schmitt = TEGRA_SCHMITT_ENABLE, \
29 .drive = TEGRA_DRIVE_DIV_1, \
30 .pull_down = TEGRA_PULL_31, \
31 .pull_up = TEGRA_PULL_31, \
32 .slew_rising = TEGRA_SLEW_SLOWEST, \
33 .slew_falling = TEGRA_SLEW_SLOWEST, \
34 }
35/* Setting the drive strength of pins
36 * hsm: Enable High speed mode (ENABLE/DISABLE)
37 * Schimit: Enable/disable schimit (ENABLE/DISABLE)
38 * drive: low power mode (DIV_1, DIV_2, DIV_4, DIV_8)
39 * pulldn_drive - drive down (falling edge) - Driver Output Pull-Down drive
40 * strength code. Value from 0 to 31.
41 * pullup_drive - drive up (rising edge) - Driver Output Pull-Up drive
42 * strength code. Value from 0 to 31.
43 * pulldn_slew - Driver Output Pull-Up slew control code - 2bit code
44 * code 11 is least slewing of signal. code 00 is highest
45 * slewing of the signal.
46 * Value - FASTEST, FAST, SLOW, SLOWEST
47 * pullup_slew - Driver Output Pull-Down slew control code -
48 * code 11 is least slewing of signal. code 00 is highest
49 * slewing of the signal.
50 * Value - FASTEST, FAST, SLOW, SLOWEST
51 */
52#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
53 { \
54 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
55 .hsm = TEGRA_HSM_##_hsm, \
56 .schmitt = TEGRA_SCHMITT_##_schmitt, \
57 .drive = TEGRA_DRIVE_##_drive, \
58 .pull_down = TEGRA_PULL_##_pulldn_drive, \
59 .pull_up = TEGRA_PULL_##_pullup_drive, \
60 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
61 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
62 }
63
64/* !!!FIXME!!!! POPULATE THIS TABLE */
65static __initdata struct tegra_drive_pingroup_config cardhu_drive_pinmux[] = {
66 /* DEFAULT_DRIVE(<pin_group>), */
67 /* SET_DRIVE(ATA, DISABLE, DISABLE, DIV_1, 31, 31, FAST, FAST) */
68 SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
69
70 /* All I2C pins are driven to maximum drive strength */
71 /* GEN1 I2C */
72 SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
73
74 /* GEN2 I2C */
75 SET_DRIVE(AT5, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
76
77 /* CAM I2C */
78 SET_DRIVE(GME, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
79
80 /* DDC I2C */
81 SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
82
83 /* PWR_I2C */
84 SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
85
86 /* UART3 */
87 SET_DRIVE(UART3, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
88
89 /* SDMMC1 */
90 SET_DRIVE(SDIO1, DISABLE, DISABLE, DIV_1, 46, 42, FAST, FAST),
91
92 /* SDMMC3 */
93 SET_DRIVE(SDIO3, DISABLE, DISABLE, DIV_1, 46, 42, FAST, FAST),
94
95 /* SDMMC4 */
96 SET_DRIVE(GMA, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
97 SET_DRIVE(GMB, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
98 SET_DRIVE(GMC, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
99 SET_DRIVE(GMD, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
100
101};
102
103#define DEFAULT_PINMUX(_pingroup, _mux, _pupd, _tri, _io) \
104 { \
105 .pingroup = TEGRA_PINGROUP_##_pingroup, \
106 .func = TEGRA_MUX_##_mux, \
107 .pupd = TEGRA_PUPD_##_pupd, \
108 .tristate = TEGRA_TRI_##_tri, \
109 .io = TEGRA_PIN_##_io, \
110 .lock = TEGRA_PIN_LOCK_DEFAULT, \
111 .od = TEGRA_PIN_OD_DEFAULT, \
112 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
113 }
114
115#define I2C_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _od) \
116 { \
117 .pingroup = TEGRA_PINGROUP_##_pingroup, \
118 .func = TEGRA_MUX_##_mux, \
119 .pupd = TEGRA_PUPD_##_pupd, \
120 .tristate = TEGRA_TRI_##_tri, \
121 .io = TEGRA_PIN_##_io, \
122 .lock = TEGRA_PIN_LOCK_##_lock, \
123 .od = TEGRA_PIN_OD_##_od, \
124 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
125 }
126
127#define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
128 { \
129 .pingroup = TEGRA_PINGROUP_##_pingroup, \
130 .func = TEGRA_MUX_##_mux, \
131 .pupd = TEGRA_PUPD_##_pupd, \
132 .tristate = TEGRA_TRI_##_tri, \
133 .io = TEGRA_PIN_##_io, \
134 .lock = TEGRA_PIN_LOCK_##_lock, \
135 .od = TEGRA_PIN_OD_DEFAULT, \
136 .ioreset = TEGRA_PIN_IO_RESET_##_ioreset \
137 }
138
139static __initdata struct tegra_pingroup_config cardhu_pinmux_common[] = {
140 /* SDMMC1 pinmux */
141 DEFAULT_PINMUX(SDMMC1_CLK, SDMMC1, NORMAL, NORMAL, INPUT),
142 DEFAULT_PINMUX(SDMMC1_CMD, SDMMC1, PULL_UP, NORMAL, INPUT),
143 DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, PULL_UP, NORMAL, INPUT),
144 DEFAULT_PINMUX(SDMMC1_DAT2, SDMMC1, PULL_UP, NORMAL, INPUT),
145 DEFAULT_PINMUX(SDMMC1_DAT1, SDMMC1, PULL_UP, NORMAL, INPUT),
146 DEFAULT_PINMUX(SDMMC1_DAT0, SDMMC1, PULL_UP, NORMAL, INPUT),
147
148 /* SDMMC3 pinmux */
149 DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT),
150 DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, PULL_UP, NORMAL, INPUT),
151 DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, PULL_UP, NORMAL, INPUT),
152 DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, PULL_UP, NORMAL, INPUT),
153 DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, PULL_UP, NORMAL, INPUT),
154 DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, PULL_UP, NORMAL, INPUT),
155 DEFAULT_PINMUX(SDMMC3_DAT6, SDMMC3, PULL_UP, NORMAL, INPUT),
156 DEFAULT_PINMUX(SDMMC3_DAT7, SDMMC3, PULL_UP, NORMAL, INPUT),
157
158 /* SDMMC4 pinmux */
159 DEFAULT_PINMUX(SDMMC4_CLK, SDMMC4, NORMAL, NORMAL, INPUT),
160 DEFAULT_PINMUX(SDMMC4_CMD, SDMMC4, PULL_UP, NORMAL, INPUT),
161 DEFAULT_PINMUX(SDMMC4_DAT0, SDMMC4, PULL_UP, NORMAL, INPUT),
162 DEFAULT_PINMUX(SDMMC4_DAT1, SDMMC4, PULL_UP, NORMAL, INPUT),
163 DEFAULT_PINMUX(SDMMC4_DAT2, SDMMC4, PULL_UP, NORMAL, INPUT),
164 DEFAULT_PINMUX(SDMMC4_DAT3, SDMMC4, PULL_UP, NORMAL, INPUT),
165 DEFAULT_PINMUX(SDMMC4_DAT4, SDMMC4, PULL_UP, NORMAL, INPUT),
166 DEFAULT_PINMUX(SDMMC4_DAT5, SDMMC4, PULL_UP, NORMAL, INPUT),
167 DEFAULT_PINMUX(SDMMC4_DAT6, SDMMC4, PULL_UP, NORMAL, INPUT),
168 DEFAULT_PINMUX(SDMMC4_DAT7, SDMMC4, PULL_UP, NORMAL, INPUT),
169 DEFAULT_PINMUX(SDMMC4_RST_N, RSVD1, PULL_DOWN, NORMAL, INPUT),
170
171 /* I2C1 pinmux */
172 I2C_PINMUX(GEN1_I2C_SCL, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
173 I2C_PINMUX(GEN1_I2C_SDA, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
174
175 /* I2C2 pinmux */
176 I2C_PINMUX(GEN2_I2C_SCL, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
177 I2C_PINMUX(GEN2_I2C_SDA, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
178
179 /* I2C3 pinmux */
180 I2C_PINMUX(CAM_I2C_SCL, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
181 I2C_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
182
183 /* I2C4 pinmux */
184 I2C_PINMUX(DDC_SCL, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
185 I2C_PINMUX(DDC_SDA, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
186
187 /* Power I2C pinmux */
188 I2C_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
189 I2C_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
190
191 //ULPI I/F
192 //just ULPI_CLK/_DIR used on Carma
193 DEFAULT_PINMUX(ULPI_DATA0, UARTA, NORMAL, TRISTATE, OUTPUT),
194 DEFAULT_PINMUX(ULPI_DATA1, UARTA, NORMAL, TRISTATE, OUTPUT),
195 DEFAULT_PINMUX(ULPI_DATA2, UARTA, NORMAL, TRISTATE, OUTPUT),
196 DEFAULT_PINMUX(ULPI_DATA3, UARTA, NORMAL, TRISTATE, OUTPUT),
197 DEFAULT_PINMUX(ULPI_DATA4, UARTA, NORMAL, TRISTATE, OUTPUT),
198 DEFAULT_PINMUX(ULPI_DATA5, UARTA, NORMAL, TRISTATE, OUTPUT),
199 DEFAULT_PINMUX(ULPI_DATA6, UARTA, NORMAL, TRISTATE, OUTPUT),
200 DEFAULT_PINMUX(ULPI_DATA7, UARTA, NORMAL, TRISTATE, OUTPUT),
201 DEFAULT_PINMUX(ULPI_CLK, UARTD, NORMAL, NORMAL, OUTPUT),
202 DEFAULT_PINMUX(ULPI_DIR, UARTD, NORMAL, NORMAL, INPUT),
203 DEFAULT_PINMUX(ULPI_NXT, UARTD, NORMAL, TRISTATE, OUTPUT),
204 DEFAULT_PINMUX(ULPI_STP, UARTD, NORMAL, TRISTATE, OUTPUT),
205 //DAP3 I/F
206 // not used on Carma
207 DEFAULT_PINMUX(DAP3_FS, I2S2, NORMAL, TRISTATE, OUTPUT),
208 DEFAULT_PINMUX(DAP3_DIN, I2S2, NORMAL, TRISTATE, OUTPUT),
209 DEFAULT_PINMUX(DAP3_DOUT, I2S2, NORMAL, TRISTATE, OUTPUT),
210 DEFAULT_PINMUX(DAP3_SCLK, I2S2, NORMAL, TRISTATE, OUTPUT),
211
212 //DEFAULT_PINMUX(GPIO_PV2, OWR, NORMAL, NORMAL, OUTPUT),
213 //DEFAULT_PINMUX(GPIO_PV3, RSVD1, NORMAL, NORMAL, INPUT),
214 DEFAULT_PINMUX(CLK2_OUT, EXTPERIPH2, NORMAL, NORMAL, INPUT),
215 DEFAULT_PINMUX(CLK2_REQ, DAP, NORMAL, NORMAL, INPUT),
216 DEFAULT_PINMUX(LCD_PWR1, DISPLAYA, NORMAL, NORMAL, INPUT),
217 DEFAULT_PINMUX(LCD_PWR2, DISPLAYA, NORMAL, NORMAL, INPUT),
218 DEFAULT_PINMUX(LCD_SDIN, DISPLAYA, NORMAL, NORMAL, INPUT),
219 DEFAULT_PINMUX(LCD_SDOUT, DISPLAYA, NORMAL, NORMAL, INPUT),
220 DEFAULT_PINMUX(LCD_WR_N, DISPLAYA, NORMAL, NORMAL, INPUT),
221 DEFAULT_PINMUX(LCD_DC0, DISPLAYA, NORMAL, NORMAL, INPUT),
222 DEFAULT_PINMUX(LCD_PWR0, DISPLAYA, NORMAL, NORMAL, INPUT),
223 DEFAULT_PINMUX(LCD_PCLK, DISPLAYA, NORMAL, NORMAL, INPUT),
224 DEFAULT_PINMUX(LCD_DE, DISPLAYA, NORMAL, NORMAL, INPUT),
225 DEFAULT_PINMUX(LCD_HSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
226 DEFAULT_PINMUX(LCD_VSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
227 DEFAULT_PINMUX(LCD_D0, DISPLAYA, NORMAL, NORMAL, INPUT),
228 DEFAULT_PINMUX(LCD_D1, DISPLAYA, NORMAL, NORMAL, INPUT),
229 DEFAULT_PINMUX(LCD_D2, DISPLAYA, NORMAL, NORMAL, INPUT),
230 DEFAULT_PINMUX(LCD_D3, DISPLAYA, NORMAL, NORMAL, INPUT),
231 DEFAULT_PINMUX(LCD_D4, DISPLAYA, NORMAL, NORMAL, INPUT),
232 DEFAULT_PINMUX(LCD_D5, DISPLAYA, NORMAL, NORMAL, INPUT),
233 DEFAULT_PINMUX(LCD_D6, DISPLAYA, NORMAL, NORMAL, INPUT),
234 DEFAULT_PINMUX(LCD_D7, DISPLAYA, NORMAL, NORMAL, INPUT),
235 DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
236 DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
237 DEFAULT_PINMUX(LCD_D10, DISPLAYA, NORMAL, NORMAL, INPUT),
238 DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
239 DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
240 DEFAULT_PINMUX(LCD_D13, DISPLAYA, NORMAL, NORMAL, INPUT),
241 DEFAULT_PINMUX(LCD_D14, DISPLAYA, NORMAL, NORMAL, INPUT),
242 DEFAULT_PINMUX(LCD_D15, DISPLAYA, NORMAL, NORMAL, INPUT),
243 DEFAULT_PINMUX(LCD_D16, DISPLAYA, NORMAL, NORMAL, INPUT),
244 DEFAULT_PINMUX(LCD_D17, DISPLAYA, NORMAL, NORMAL, INPUT),
245 DEFAULT_PINMUX(LCD_D18, DISPLAYA, NORMAL, NORMAL, INPUT),
246 DEFAULT_PINMUX(LCD_D19, DISPLAYA, NORMAL, NORMAL, INPUT),
247 DEFAULT_PINMUX(LCD_D20, DISPLAYA, NORMAL, NORMAL, INPUT),
248 DEFAULT_PINMUX(LCD_D21, DISPLAYA, NORMAL, NORMAL, INPUT),
249 DEFAULT_PINMUX(LCD_D22, DISPLAYA, NORMAL, NORMAL, INPUT),
250 DEFAULT_PINMUX(LCD_D23, DISPLAYA, NORMAL, NORMAL, INPUT),
251 DEFAULT_PINMUX(LCD_DC1, DISPLAYA, NORMAL, NORMAL, INPUT),
252 DEFAULT_PINMUX(CRT_HSYNC, CRT, NORMAL, NORMAL, OUTPUT),
253 DEFAULT_PINMUX(CRT_VSYNC, CRT, NORMAL, NORMAL, OUTPUT),
254 //VI I/F (up to 10 bits)
255 DEFAULT_PINMUX(VI_D0, VI, PULL_DOWN, NORMAL, INPUT),
256 DEFAULT_PINMUX(VI_D1, VI, PULL_DOWN, NORMAL, INPUT),
257 DEFAULT_PINMUX(VI_D2, VI, PULL_DOWN, NORMAL, INPUT),
258 DEFAULT_PINMUX(VI_D3, VI, PULL_DOWN, NORMAL, INPUT),
259 DEFAULT_PINMUX(VI_D4, VI, PULL_DOWN, NORMAL, INPUT),
260 DEFAULT_PINMUX(VI_D5, VI, PULL_DOWN, NORMAL, INPUT),
261 DEFAULT_PINMUX(VI_D6, VI, PULL_DOWN, NORMAL, INPUT),
262 DEFAULT_PINMUX(VI_D7, VI, PULL_DOWN, NORMAL, INPUT),
263 DEFAULT_PINMUX(VI_D8, VI, PULL_DOWN, NORMAL, INPUT),
264 DEFAULT_PINMUX(VI_D9, VI, PULL_DOWN, NORMAL, INPUT),
265 DEFAULT_PINMUX(VI_D10, VI, NORMAL, TRISTATE, OUTPUT),
266 DEFAULT_PINMUX(VI_D11, VI, NORMAL, TRISTATE, OUTPUT),
267 DEFAULT_PINMUX(VI_MCLK, VI, PULL_DOWN, NORMAL, INPUT),
268 DEFAULT_PINMUX(VI_PCLK, VI, PULL_UP, NORMAL, INPUT),
269 DEFAULT_PINMUX(VI_HSYNC, VI, PULL_UP, NORMAL, INPUT),
270 DEFAULT_PINMUX(VI_VSYNC, VI, PULL_UP, NORMAL, INPUT),
271
272 //UART2
273 DEFAULT_PINMUX(UART2_RXD, UARTA, NORMAL, NORMAL, INPUT),
274 DEFAULT_PINMUX(UART2_TXD, UARTA, NORMAL, NORMAL, OUTPUT),
275 DEFAULT_PINMUX(UART2_RTS_N, UARTA, NORMAL, NORMAL, OUTPUT),
276 DEFAULT_PINMUX(UART2_CTS_N, UARTA, NORMAL, NORMAL, INPUT),
277 //UART3
278 DEFAULT_PINMUX(UART3_TXD, UARTC, NORMAL, NORMAL, OUTPUT),
279 DEFAULT_PINMUX(UART3_RXD, UARTC, NORMAL, NORMAL, INPUT),
280 DEFAULT_PINMUX(UART3_CTS_N, UARTC, NORMAL, NORMAL, INPUT),
281 DEFAULT_PINMUX(UART3_RTS_N, UARTC, NORMAL, NORMAL, OUTPUT),
282
283 DEFAULT_PINMUX(GPIO_PU0, RSVD1, NORMAL, NORMAL, INPUT),
284 DEFAULT_PINMUX(GPIO_PU1, RSVD1, NORMAL, TRISTATE, OUTPUT),
285 DEFAULT_PINMUX(GPIO_PU2, RSVD1, NORMAL, TRISTATE, INPUT),
286 DEFAULT_PINMUX(GPIO_PU3, PWM0, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_PWM */
287 //DEFAULT_PINMUX(GPIO_PU3, RSVD1, NORMAL, NORMAL, INPUT),
288 DEFAULT_PINMUX(GPIO_PU4, RSVD1, NORMAL, TRISTATE, INPUT),
289 //DEFAULT_PINMUX(GPIO_PU4, PWM1, NORMAL, NORMAL, OUTPUT),
290 DEFAULT_PINMUX(GPIO_PU5, PWM2, NORMAL, NORMAL, INPUT),
291 DEFAULT_PINMUX(GPIO_PU6, PWM3, NORMAL, NORMAL, INPUT),
292 DEFAULT_PINMUX(DAP4_FS, I2S3, NORMAL, NORMAL, INPUT),
293 DEFAULT_PINMUX(DAP4_DIN, I2S3, NORMAL, NORMAL, INPUT),
294 DEFAULT_PINMUX(DAP4_DOUT, I2S3, NORMAL, NORMAL, INPUT),
295 DEFAULT_PINMUX(DAP4_SCLK, I2S3, NORMAL, NORMAL, INPUT),
296 //DEFAULT_PINMUX(CLK3_OUT, EXTPERIPH3, NORMAL, NORMAL, OUTPUT),
297 DEFAULT_PINMUX(CLK3_OUT, RSVD1, NORMAL, NORMAL, INPUT),
298 DEFAULT_PINMUX(CLK3_REQ, DEV3, NORMAL, NORMAL, INPUT),
299 DEFAULT_PINMUX(GMI_WP_N, GMI, NORMAL, NORMAL, INPUT),
300
301 //inputs on Carma
302 //DEFAULT_PINMUX(KB_ROW5, OWR, NORMAL, NORMAL, OUTPUT),
303 //DEFAULT_PINMUX(KB_ROW12, KBC, NORMAL, NORMAL, OUTPUT),
304 //DEFAULT_PINMUX(KB_ROW14, KBC, NORMAL, NORMAL, OUTPUT),
305 //DEFAULT_PINMUX(KB_ROW15, KBC, NORMAL, NORMAL, OUTPUT),
306 DEFAULT_PINMUX(KB_ROW5, OWR, NORMAL, NORMAL, INPUT),
307 DEFAULT_PINMUX(KB_ROW12, KBC, NORMAL, NORMAL, INPUT),
308 DEFAULT_PINMUX(KB_ROW14, KBC, NORMAL, NORMAL, INPUT),
309 DEFAULT_PINMUX(KB_ROW15, KBC, NORMAL, NORMAL, INPUT),
310
311 //////////////////
312 // FIXME:
313 //
314 // set up GMI bus
315
316#if 0 /* for testing on Verbier */
317 DEFAULT_PINMUX(GMI_WAIT, NAND, NORMAL, NORMAL, INPUT),
318 DEFAULT_PINMUX(GMI_ADV_N, NAND, NORMAL, NORMAL, OUTPUT),
319 DEFAULT_PINMUX(GMI_CLK, NAND, NORMAL, NORMAL, OUTPUT),
320 DEFAULT_PINMUX(GMI_CS0_N, NAND, NORMAL, NORMAL, OUTPUT),
321 DEFAULT_PINMUX(GMI_CS1_N, NAND, NORMAL, NORMAL, OUTPUT),
322 DEFAULT_PINMUX(GMI_CS3_N, NAND, NORMAL, NORMAL, OUTPUT),
323 DEFAULT_PINMUX(GMI_CS4_N, NAND, NORMAL, NORMAL, OUTPUT),
324 DEFAULT_PINMUX(GMI_CS6_N, NAND_ALT, NORMAL, NORMAL, OUTPUT),
325 DEFAULT_PINMUX(GMI_CS7_N, NAND_ALT, NORMAL, NORMAL, OUTPUT),
326 DEFAULT_PINMUX(GMI_AD0, NAND, NORMAL, NORMAL, INPUT),
327 DEFAULT_PINMUX(GMI_AD1, NAND, NORMAL, NORMAL, INPUT),
328 DEFAULT_PINMUX(GMI_AD2, NAND, NORMAL, NORMAL, INPUT),
329 DEFAULT_PINMUX(GMI_AD3, NAND, NORMAL, NORMAL, INPUT),
330 DEFAULT_PINMUX(GMI_AD4, NAND, NORMAL, NORMAL, INPUT),
331 DEFAULT_PINMUX(GMI_AD5, NAND, NORMAL, NORMAL, INPUT),
332 DEFAULT_PINMUX(GMI_AD6, NAND, NORMAL, NORMAL, INPUT),
333 DEFAULT_PINMUX(GMI_AD7, NAND, NORMAL, NORMAL, INPUT),
334 DEFAULT_PINMUX(GMI_AD8, NAND, NORMAL, NORMAL, OUTPUT),
335 DEFAULT_PINMUX(GMI_AD9, NAND, NORMAL, NORMAL, INPUT),
336 DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
337 DEFAULT_PINMUX(GMI_AD11, NAND, NORMAL, NORMAL, INPUT),
338 DEFAULT_PINMUX(GMI_AD12, NAND, NORMAL, NORMAL, INPUT),
339 DEFAULT_PINMUX(GMI_AD13, NAND, NORMAL, NORMAL, INPUT),
340 DEFAULT_PINMUX(GMI_AD14, NAND, NORMAL, NORMAL, INPUT),
341 DEFAULT_PINMUX(GMI_AD15, NAND, NORMAL, NORMAL, INPUT),
342 DEFAULT_PINMUX(GMI_WR_N, NAND, NORMAL, NORMAL, OUTPUT),
343 DEFAULT_PINMUX(GMI_OE_N, NAND, NORMAL, NORMAL, OUTPUT),
344 DEFAULT_PINMUX(GMI_DQS, NAND, NORMAL, NORMAL, INPUT),
345#else
346 //LCD1_BL_PWM on GPIO_PU3
347 //DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_PWM */
348#endif
349
350 //
351
352 //DEFAULT_PINMUX(GMI_A16, SPI4, NORMAL, NORMAL, INPUT),
353 //DEFAULT_PINMUX(GMI_A17, SPI4, NORMAL, NORMAL, INPUT),
354 //DEFAULT_PINMUX(GMI_A18, SPI4, NORMAL, NORMAL, INPUT),
355 //DEFAULT_PINMUX(GMI_A19, SPI4, NORMAL, NORMAL, INPUT),
356 DEFAULT_PINMUX(CAM_MCLK, VI_ALT2, PULL_UP, NORMAL, INPUT),
357 //DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, NORMAL, INPUT),
358 //DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, NORMAL, INPUT),
359 DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, TRISTATE, OUTPUT),
360 DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, TRISTATE, OUTPUT),
361 //DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, NORMAL, INPUT),
362 DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, TRISTATE, OUTPUT),
363 DEFAULT_PINMUX(GPIO_PBB4, VGP4, NORMAL, TRISTATE, OUTPUT),
364 DEFAULT_PINMUX(GPIO_PBB5, VGP5, NORMAL, NORMAL, INPUT),
365 DEFAULT_PINMUX(GPIO_PBB6, VGP6, NORMAL, NORMAL, INPUT),
366 DEFAULT_PINMUX(GPIO_PBB7, I2S4, NORMAL, NORMAL, INPUT),
367 DEFAULT_PINMUX(GPIO_PCC2, I2S4, NORMAL, NORMAL, INPUT),
368 DEFAULT_PINMUX(JTAG_RTCK, RTCK, NORMAL, NORMAL, OUTPUT),
369
370 /* KBC keys */
371 DEFAULT_PINMUX(KB_ROW0, KBC, PULL_UP, NORMAL, INPUT),
372 DEFAULT_PINMUX(KB_ROW1, KBC, PULL_UP, NORMAL, INPUT),
373 DEFAULT_PINMUX(KB_ROW2, KBC, PULL_UP, NORMAL, INPUT),
374 DEFAULT_PINMUX(KB_ROW3, KBC, PULL_UP, NORMAL, INPUT),
375 DEFAULT_PINMUX(KB_COL0, KBC, PULL_UP, NORMAL, INPUT),
376 DEFAULT_PINMUX(KB_COL1, KBC, PULL_UP, NORMAL, INPUT),
377 DEFAULT_PINMUX(KB_COL2, KBC, PULL_UP, NORMAL, INPUT),
378 DEFAULT_PINMUX(KB_COL3, KBC, PULL_UP, NORMAL, INPUT),
379 DEFAULT_PINMUX(KB_COL4, KBC, PULL_UP, NORMAL, INPUT),
380 DEFAULT_PINMUX(KB_COL5, KBC, PULL_UP, NORMAL, INPUT),
381 DEFAULT_PINMUX(GPIO_PV0, RSVD, PULL_UP, NORMAL, INPUT),
382
383 DEFAULT_PINMUX(CLK_32K_OUT, BLINK, NORMAL, NORMAL, OUTPUT),
384 DEFAULT_PINMUX(SYS_CLK_REQ, SYSCLK, NORMAL, NORMAL, OUTPUT),
385 DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT),
386 DEFAULT_PINMUX(DAP1_FS, I2S0, NORMAL, NORMAL, INPUT),
387 DEFAULT_PINMUX(DAP1_DIN, I2S0, NORMAL, NORMAL, INPUT),
388 DEFAULT_PINMUX(DAP1_DOUT, I2S0, NORMAL, NORMAL, INPUT),
389 DEFAULT_PINMUX(DAP1_SCLK, I2S0, NORMAL, NORMAL, INPUT),
390 DEFAULT_PINMUX(CLK1_REQ, DAP, NORMAL, NORMAL, INPUT),
391 DEFAULT_PINMUX(CLK1_OUT, EXTPERIPH1, NORMAL, NORMAL, INPUT),
392#ifdef CONFIG_SND_HDA_CODEC_REALTEK
393 DEFAULT_PINMUX(SPDIF_IN, DAPSDMMC2, PULL_DOWN, NORMAL, INPUT),
394#else
395 DEFAULT_PINMUX(SPDIF_IN, SPDIF, NORMAL, NORMAL, INPUT),
396#endif
397 DEFAULT_PINMUX(SPDIF_OUT, SPDIF, NORMAL, NORMAL, OUTPUT),
398#ifdef CONFIG_SND_HDA_CODEC_REALTEK
399 DEFAULT_PINMUX(DAP2_FS, HDA, PULL_DOWN, NORMAL, INPUT),
400 DEFAULT_PINMUX(DAP2_DIN, HDA, PULL_DOWN, NORMAL, INPUT),
401 DEFAULT_PINMUX(DAP2_DOUT, HDA, PULL_DOWN, NORMAL, INPUT),
402 DEFAULT_PINMUX(DAP2_SCLK, HDA, PULL_DOWN, NORMAL, INPUT),
403#else
404 DEFAULT_PINMUX(DAP2_FS, I2S1, NORMAL, NORMAL, INPUT),
405 DEFAULT_PINMUX(DAP2_DIN, I2S1, NORMAL, NORMAL, INPUT),
406 DEFAULT_PINMUX(DAP2_DOUT, I2S1, NORMAL, NORMAL, INPUT),
407 DEFAULT_PINMUX(DAP2_SCLK, I2S1, NORMAL, NORMAL, INPUT),
408#endif
409 DEFAULT_PINMUX(SPI2_CS1_N, SPI2, PULL_UP, NORMAL, INPUT),
410 DEFAULT_PINMUX(SPI1_MOSI, SPI1, NORMAL, NORMAL, INPUT),
411 DEFAULT_PINMUX(SPI1_SCK, SPI1, NORMAL, NORMAL, INPUT),
412 DEFAULT_PINMUX(SPI1_CS0_N, SPI1, NORMAL, NORMAL, INPUT),
413 DEFAULT_PINMUX(SPI1_MISO, SPI1, NORMAL, NORMAL, INPUT),
414 DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
415 DEFAULT_PINMUX(PEX_L0_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
416 DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
417 DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT),
418 DEFAULT_PINMUX(PEX_L1_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
419 DEFAULT_PINMUX(PEX_L1_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
420 DEFAULT_PINMUX(PEX_L1_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
421 DEFAULT_PINMUX(PEX_L2_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
422 DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
423 DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
424 DEFAULT_PINMUX(HDMI_CEC, CEC, NORMAL, NORMAL, INPUT),
425 DEFAULT_PINMUX(HDMI_INT, RSVD0, NORMAL, TRISTATE, INPUT),
426
427 /* Gpios */
428 /* SDMMC1 CD gpio */
429 DEFAULT_PINMUX(GPIO_PV3, RSVD1, NORMAL, NORMAL, INPUT),
430 //DEFAULT_PINMUX(GMI_IORDY, RSVD1, PULL_UP, NORMAL, INPUT),
431 /* SDMMC1 WP gpio */
432 //DEFAULT_PINMUX(VI_D11, RSVD1, PULL_UP, NORMAL, INPUT),
433 DEFAULT_PINMUX(GPIO_PV2, RSVD1, PULL_UP, NORMAL, INPUT),
434
435 /* Touch panel GPIO */
436 /* Touch IRQ */
437 //DEFAULT_PINMUX(GMI_AD12, NAND, PULL_UP, NORMAL, INPUT),
438
439 /* Touch RESET */
440 //DEFAULT_PINMUX(GMI_AD14, NAND, NORMAL, NORMAL, OUTPUT),
441
442 /* Power rails GPIO */
443 //DEFAULT_PINMUX(SPI2_SCK, GMI, NORMAL, NORMAL, INPUT),
444 //DEFAULT_PINMUX(GPIO_PBB4, VGP4, NORMAL, NORMAL, INPUT),
445 DEFAULT_PINMUX(KB_ROW8, KBC, PULL_UP, NORMAL, INPUT),
446 DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, PULL_UP, NORMAL, INPUT),
447 DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, PULL_UP, NORMAL, INPUT),
448
449 //VI_PINMUX(VI_D6, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
450 //VI_PINMUX(VI_D8, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
451 //VI_PINMUX(VI_D9, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
452 //VI_PINMUX(VI_PCLK, RSVD1, PULL_UP, TRISTATE, INPUT, DISABLE, DISABLE),
453 //VI_PINMUX(VI_HSYNC, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
454 //VI_PINMUX(VI_VSYNC, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
455};
456
457static __initdata struct tegra_pingroup_config cardhu_pinmux_e118x[] = {
458 /* Power rails GPIO */
459 DEFAULT_PINMUX(SPI2_SCK, SPI2, NORMAL, NORMAL, INPUT),
460 DEFAULT_PINMUX(GMI_RST_N, RSVD3, PULL_UP, TRISTATE, INPUT),
461 DEFAULT_PINMUX(GMI_AD15, NAND, PULL_UP, TRISTATE, INPUT),
462};
463
464static __initdata struct tegra_pingroup_config cardhu_pinmux_cardhu[] = {
465 DEFAULT_PINMUX(LCD_CS0_N, DISPLAYA, NORMAL, NORMAL, INPUT),
466 DEFAULT_PINMUX(LCD_SCK, DISPLAYA, NORMAL, NORMAL, INPUT),
467 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
468 DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, INPUT),
469
470 DEFAULT_PINMUX(GMI_CS2_N, RSVD1, PULL_UP, NORMAL, INPUT),
471 DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
472 DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
473
474 /* Power rails GPIO */
475 DEFAULT_PINMUX(GMI_CS2_N, NAND, NORMAL, NORMAL, OUTPUT),
476 DEFAULT_PINMUX(GMI_RST_N, RSVD3, PULL_UP, TRISTATE, INPUT),
477 DEFAULT_PINMUX(GMI_AD15, NAND, PULL_UP, TRISTATE, INPUT),
478
479 DEFAULT_PINMUX(GMI_CS0_N, GMI, PULL_UP, NORMAL, INPUT),
480 DEFAULT_PINMUX(GMI_CS1_N, GMI, PULL_UP, TRISTATE, INPUT),
481 /*TP_IRQ*/
482 DEFAULT_PINMUX(GMI_CS4_N, GMI, PULL_UP, NORMAL, INPUT),
483 /*PCIE dock detect*/
484 DEFAULT_PINMUX(GPIO_PU4, PWM1, PULL_UP, NORMAL, INPUT),
485};
486
487static __initdata struct tegra_pingroup_config cardhu_pinmux_cardhu_a03[] = {
488 DEFAULT_PINMUX(LCD_CS0_N, DISPLAYA, NORMAL, NORMAL, INPUT),
489 DEFAULT_PINMUX(LCD_SCK, DISPLAYA, NORMAL, NORMAL, INPUT),
490 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
491 DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, INPUT),
492
493 DEFAULT_PINMUX(GMI_CS2_N, RSVD1, PULL_UP, NORMAL, INPUT),
494 //DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
495 //DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
496
497 /* Power rails GPIO */
498 //DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
499 //DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
500 //DEFAULT_PINMUX(PEX_L1_CLKREQ_N, RSVD3, PULL_UP, TRISTATE, INPUT),
501 //DEFAULT_PINMUX(PEX_L1_PRSNT_N, RSVD3, PULL_UP, TRISTATE, INPUT),
502};
503
504static __initdata struct tegra_pingroup_config cardhu_pinmux_e1291_a04[] = {
505 //DEFAULT_PINMUX(GMI_AD15, NAND, PULL_DOWN, NORMAL, OUTPUT),
506};
507
508static __initdata struct tegra_pingroup_config cardhu_pinmux_e1198[] = {
509 DEFAULT_PINMUX(LCD_CS0_N, DISPLAYA, NORMAL, NORMAL, INPUT),
510 DEFAULT_PINMUX(LCD_SCK, DISPLAYA, NORMAL, NORMAL, INPUT),
511 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
512 DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, INPUT),
513
514 DEFAULT_PINMUX(GMI_CS2_N, RSVD1, PULL_UP, NORMAL, INPUT),
515 DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
516 DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
517
518 /* SPI2 */
519 DEFAULT_PINMUX(SPI2_SCK, SPI2, PULL_UP, NORMAL, INPUT),
520 DEFAULT_PINMUX(SPI2_MOSI, SPI2, PULL_UP, NORMAL, INPUT),
521 DEFAULT_PINMUX(SPI2_MISO, SPI2, PULL_UP, NORMAL, INPUT),
522 DEFAULT_PINMUX(SPI2_CS0_N, SPI2, PULL_UP, NORMAL, INPUT),
523 DEFAULT_PINMUX(SPI2_CS2_N, SPI2, PULL_UP, NORMAL, INPUT),
524};
525
526static __initdata struct tegra_pingroup_config unused_pins_lowpower[] = {
527 DEFAULT_PINMUX(GMI_WAIT, NAND, PULL_UP, TRISTATE, OUTPUT),
528 DEFAULT_PINMUX(GMI_ADV_N, NAND, NORMAL, TRISTATE, OUTPUT),
529 DEFAULT_PINMUX(GMI_CLK, NAND, NORMAL, TRISTATE, OUTPUT),
530 DEFAULT_PINMUX(GMI_CS3_N, NAND, NORMAL, NORMAL, OUTPUT),
531 DEFAULT_PINMUX(GMI_CS6_N, SATA, NORMAL, NORMAL, OUTPUT),
532 DEFAULT_PINMUX(GMI_CS7_N, NAND, PULL_UP, NORMAL, INPUT),
533 DEFAULT_PINMUX(GMI_AD0, NAND, NORMAL, TRISTATE, OUTPUT),
534 DEFAULT_PINMUX(GMI_AD1, NAND, NORMAL, TRISTATE, OUTPUT),
535 DEFAULT_PINMUX(GMI_AD2, NAND, NORMAL, TRISTATE, OUTPUT),
536 DEFAULT_PINMUX(GMI_AD3, NAND, NORMAL, TRISTATE, OUTPUT),
537 DEFAULT_PINMUX(GMI_AD4, NAND, NORMAL, TRISTATE, OUTPUT),
538 DEFAULT_PINMUX(GMI_AD5, NAND, NORMAL, TRISTATE, OUTPUT),
539 DEFAULT_PINMUX(GMI_AD6, NAND, NORMAL, TRISTATE, OUTPUT),
540 DEFAULT_PINMUX(GMI_AD7, NAND, NORMAL, TRISTATE, OUTPUT),
541 DEFAULT_PINMUX(GMI_AD9, PWM1, NORMAL, NORMAL, OUTPUT),
542 DEFAULT_PINMUX(GMI_AD11, NAND, NORMAL, NORMAL, OUTPUT),
543 DEFAULT_PINMUX(GMI_AD13, NAND, PULL_UP, NORMAL, INPUT),
544 DEFAULT_PINMUX(GMI_WR_N, NAND, NORMAL, TRISTATE, OUTPUT),
545 DEFAULT_PINMUX(GMI_OE_N, NAND, NORMAL, TRISTATE, OUTPUT),
546 DEFAULT_PINMUX(GMI_DQS, NAND, NORMAL, TRISTATE, OUTPUT),
547};
548
549static __initdata struct tegra_pingroup_config gmi_pins_269[] = {
550 /* Continuation of table unused_pins_lowpower only for PM269 */
551 DEFAULT_PINMUX(GMI_CS0_N, NAND, PULL_UP, NORMAL, OUTPUT),
552 DEFAULT_PINMUX(GMI_CS1_N, NAND, PULL_UP, TRISTATE, OUTPUT),
553 DEFAULT_PINMUX(GMI_CS2_N, RSVD1, NORMAL, NORMAL, INPUT),
554 DEFAULT_PINMUX(GMI_CS3_N, NAND, NORMAL, TRISTATE, OUTPUT),
555 DEFAULT_PINMUX(GMI_CS4_N, NAND, PULL_UP, NORMAL, INPUT),
556 DEFAULT_PINMUX(GMI_CS6_N, SATA, NORMAL, TRISTATE, OUTPUT),
557 DEFAULT_PINMUX(GMI_CS7_N, NAND, PULL_UP, NORMAL, INPUT),
558 DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
559 DEFAULT_PINMUX(GMI_AD9, PWM1, NORMAL, NORMAL, OUTPUT),
560 DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
561 DEFAULT_PINMUX(GMI_AD11, NAND, NORMAL, NORMAL, OUTPUT),
562 DEFAULT_PINMUX(GMI_AD13, NAND, PULL_UP, TRISTATE, OUTPUT),
563 DEFAULT_PINMUX(GMI_AD15, NAND, PULL_UP, TRISTATE, INPUT),
564 DEFAULT_PINMUX(GMI_A16, SPI4, NORMAL, NORMAL, INPUT),
565 DEFAULT_PINMUX(GMI_A17, SPI4, NORMAL, NORMAL, INPUT),
566 DEFAULT_PINMUX(GMI_A18, SPI4, PULL_UP, NORMAL, INPUT),
567 DEFAULT_PINMUX(GMI_A19, SPI4, NORMAL, NORMAL, INPUT),
568 DEFAULT_PINMUX(GMI_RST_N, NAND, PULL_UP, NORMAL, INPUT),
569 DEFAULT_PINMUX(GMI_WP_N, NAND, NORMAL, NORMAL, INPUT),
570};
571
572
573#define GPIO_INIT_PIN_MODE(_gpio, _is_input, _value) \
574 { \
575 .gpio_nr = _gpio, \
576 .is_input = _is_input, \
577 .value = _value, \
578 }
579
580
581/* E1198-A01/E1291 specific fab < A03 */
582static struct gpio_init_pin_info init_gpio_mode_e1291_a02[] = {
583 GPIO_INIT_PIN_MODE(TEGRA_GPIO_PH7, false, 0),
584 GPIO_INIT_PIN_MODE(TEGRA_GPIO_PI4, false, 0),
585};
586
587/* E1198-A02/E1291 specific fab >= A03 */
588static struct gpio_init_pin_info init_gpio_mode_e1291_a03[] = {
589 //GPIO_INIT_PIN_MODE(TEGRA_GPIO_PDD6, false, 0),
590 //GPIO_INIT_PIN_MODE(TEGRA_GPIO_PDD4, false, 0),
591};
592
593static void __init cardhu_gpio_init_configure(void)
594{
595 struct board_info board_info;
596 int len;
597 int i;
598 struct gpio_init_pin_info *pins_info;
599
600 tegra_get_board_info(&board_info);
601
602 switch (board_info.board_id) {
603 case BOARD_E1198:
604 if (board_info.fab < BOARD_FAB_A02) {
605 len = ARRAY_SIZE(init_gpio_mode_e1291_a02);
606 pins_info = init_gpio_mode_e1291_a02;
607 } else {
608 len = ARRAY_SIZE(init_gpio_mode_e1291_a03);
609 pins_info = init_gpio_mode_e1291_a03;
610 }
611 break;
612 case BOARD_E1291:
613 if (board_info.fab < BOARD_FAB_A03) {
614 len = ARRAY_SIZE(init_gpio_mode_e1291_a02);
615 pins_info = init_gpio_mode_e1291_a02;
616 } else {
617 len = ARRAY_SIZE(init_gpio_mode_e1291_a03);
618 pins_info = init_gpio_mode_e1291_a03;
619 }
620 break;
621 default:
622 return;
623 }
624
625 for (i = 0; i < len; ++i) {
626 tegra_gpio_init_configure(pins_info->gpio_nr,
627 pins_info->is_input, pins_info->value);
628 pins_info++;
629 }
630}
631
632int __init cardhu_pinmux_init(void)
633{
634 struct board_info board_info;
635
636 cardhu_gpio_init_configure();
637
638 tegra_pinmux_config_table(cardhu_pinmux_common, ARRAY_SIZE(cardhu_pinmux_common));
639 tegra_drive_pinmux_config_table(cardhu_drive_pinmux,
640 ARRAY_SIZE(cardhu_drive_pinmux));
641
642 tegra_get_board_info(&board_info);
643 switch (board_info.board_id) {
644 case BOARD_E1198:
645 tegra_pinmux_config_table(cardhu_pinmux_e1198,
646 ARRAY_SIZE(cardhu_pinmux_e1198));
647 tegra_pinmux_config_table(unused_pins_lowpower,
648 ARRAY_SIZE(unused_pins_lowpower));
649 if (board_info.fab >= BOARD_FAB_A02)
650 tegra_pinmux_config_table(cardhu_pinmux_cardhu_a03,
651 ARRAY_SIZE(cardhu_pinmux_cardhu_a03));
652 break;
653 case BOARD_E1291:
654 if (board_info.fab < BOARD_FAB_A03) {
655 tegra_pinmux_config_table(cardhu_pinmux_cardhu,
656 ARRAY_SIZE(cardhu_pinmux_cardhu));
657 tegra_pinmux_config_table(unused_pins_lowpower,
658 ARRAY_SIZE(unused_pins_lowpower));
659 } else {
660 tegra_pinmux_config_table(cardhu_pinmux_cardhu_a03,
661 ARRAY_SIZE(cardhu_pinmux_cardhu_a03));
662 }
663 if (board_info.fab >= BOARD_FAB_A04)
664 tegra_pinmux_config_table(cardhu_pinmux_e1291_a04,
665 ARRAY_SIZE(cardhu_pinmux_e1291_a04));
666 break;
667
668 case BOARD_PM269:
669 case BOARD_PM305:
670 case BOARD_PM311:
671 case BOARD_E1257:
672 tegra_pinmux_config_table(cardhu_pinmux_e118x,
673 ARRAY_SIZE(cardhu_pinmux_e118x));
674 tegra_pinmux_config_table(unused_pins_lowpower,
675 ARRAY_SIZE(unused_pins_lowpower));
676 tegra_pinmux_config_table(gmi_pins_269,
677 ARRAY_SIZE(gmi_pins_269));
678 break;
679 default:
680 tegra_pinmux_config_table(cardhu_pinmux_e118x,
681 ARRAY_SIZE(cardhu_pinmux_e118x));
682 break;
683 }
684 return 0;
685}
686
687#define PIN_GPIO_LPM(_name, _gpio, _is_input, _value) \
688 { \
689 .name = _name, \
690 .gpio_nr = _gpio, \
691 .is_gpio = true, \
692 .is_input = _is_input, \
693 .value = _value, \
694 }
695
696struct gpio_init_pin_info pin_lpm_cardhu_common[] = {
697 PIN_GPIO_LPM("GMI_CS3_N", TEGRA_GPIO_PK4, 0, 0),
698 PIN_GPIO_LPM("GMI_CS4_N", TEGRA_GPIO_PK2, 1, 0),
699 PIN_GPIO_LPM("GMI_AD9", TEGRA_GPIO_PH1, 0, 0),
700 PIN_GPIO_LPM("GMI_AD11", TEGRA_GPIO_PH3, 0, 0),
701 PIN_GPIO_LPM("GMI_CS7", TEGRA_GPIO_PI6, 1, 0),
702 PIN_GPIO_LPM("GMI_CS0", TEGRA_GPIO_PJ0, 1, 0),
703 PIN_GPIO_LPM("GMI_CS1", TEGRA_GPIO_PJ2, 1, 0),
704 PIN_GPIO_LPM("GMI_WP_N", TEGRA_GPIO_PC7, 1, 0),
705};
706
707struct gpio_init_pin_info vddio_gmi_pins_pm269[] = {
708 PIN_GPIO_LPM("GMI_CS2", TEGRA_GPIO_PK3, 1, 0),
709 PIN_GPIO_LPM("GMI_CS3_N", TEGRA_GPIO_PK4, 0, 0),
710 PIN_GPIO_LPM("GMI_CS4_N", TEGRA_GPIO_PK2, 1, 0),
711 PIN_GPIO_LPM("GMI_AD9", TEGRA_GPIO_PH1, 0, 0),
712 PIN_GPIO_LPM("GMI_CS7", TEGRA_GPIO_PI6, 1, 0),
713 PIN_GPIO_LPM("GMI_CS0", TEGRA_GPIO_PJ0, 1, 0),
714 PIN_GPIO_LPM("GMI_CS1", TEGRA_GPIO_PJ2, 1, 0),
715 PIN_GPIO_LPM("GMI_WP_N", TEGRA_GPIO_PC7, 1, 0),
716 PIN_GPIO_LPM("GMI_A16", TEGRA_GPIO_PJ7, 0, 0),
717 PIN_GPIO_LPM("GMI_A17", TEGRA_GPIO_PB0, 0, 0),
718 PIN_GPIO_LPM("GMI_A18", TEGRA_GPIO_PB1, 1, 0),
719 PIN_GPIO_LPM("GMI_A19", TEGRA_GPIO_PK7, 0, 0),
720};
721
722struct gpio_init_pin_info vddio_gmi_pins_pm269_pm313[] = {
723 PIN_GPIO_LPM("GMI_CS3_N", TEGRA_GPIO_PK4, 0, 0),
724 PIN_GPIO_LPM("GMI_CS4_N", TEGRA_GPIO_PK2, 1, 0),
725 PIN_GPIO_LPM("GMI_CS7", TEGRA_GPIO_PI6, 1, 0),
726 PIN_GPIO_LPM("GMI_CS0", TEGRA_GPIO_PJ0, 1, 0),
727 PIN_GPIO_LPM("GMI_CS1", TEGRA_GPIO_PJ2, 1, 0),
728 PIN_GPIO_LPM("GMI_WP_N", TEGRA_GPIO_PC7, 1, 0),
729 PIN_GPIO_LPM("GMI_A16", TEGRA_GPIO_PJ7, 0, 0),
730 PIN_GPIO_LPM("GMI_A17", TEGRA_GPIO_PB0, 0, 0),
731 PIN_GPIO_LPM("GMI_A18", TEGRA_GPIO_PB1, 1, 0),
732 PIN_GPIO_LPM("GMI_A19", TEGRA_GPIO_PK7, 0, 0),
733};
734
735static void set_unused_pin_gpio(struct gpio_init_pin_info *lpm_pin_info,
736 int list_count)
737{
738 int i;
739 struct gpio_init_pin_info *pin_info;
740 int ret;
741
742 for (i = 0; i < list_count; ++i) {
743 pin_info = (struct gpio_init_pin_info *)(lpm_pin_info + i);
744 if (!pin_info->is_gpio)
745 continue;
746
747 ret = gpio_request(pin_info->gpio_nr, pin_info->name);
748 if (ret < 0) {
749 pr_err("%s() Error in gpio_request() for gpio %d\n",
750 __func__, pin_info->gpio_nr);
751 continue;
752 }
753 if (pin_info->is_input)
754 ret = gpio_direction_input(pin_info->gpio_nr);
755 else
756 ret = gpio_direction_output(pin_info->gpio_nr,
757 pin_info->value);
758 if (ret < 0) {
759 pr_err("%s() Error in setting gpio %d to in/out\n",
760 __func__, pin_info->gpio_nr);
761 gpio_free(pin_info->gpio_nr);
762 continue;
763 }
764 tegra_gpio_enable(pin_info->gpio_nr);
765 }
766}
767
768/* Initialize the pins to desired state as per power/asic/system-eng
769 * recomendation */
770int __init cardhu_pins_state_init(void)
771{
772 struct board_info board_info;
773 struct board_info display_board_info;
774
775 tegra_get_board_info(&board_info);
776 tegra_get_display_board_info(&display_board_info);
777 if ((board_info.board_id == BOARD_E1291) ||
778 (board_info.board_id == BOARD_E1198))
779 set_unused_pin_gpio(&pin_lpm_cardhu_common[0],
780 ARRAY_SIZE(pin_lpm_cardhu_common));
781
782 if ((board_info.board_id == BOARD_PM269) ||
783 (board_info.board_id == BOARD_E1257) ||
784 (board_info.board_id == BOARD_PM305) ||
785 (board_info.board_id == BOARD_PM311)) {
786 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
787 set_unused_pin_gpio(&vddio_gmi_pins_pm269_pm313[0],
788 ARRAY_SIZE(vddio_gmi_pins_pm269_pm313));
789 } else {
790 set_unused_pin_gpio(&vddio_gmi_pins_pm269[0],
791 ARRAY_SIZE(vddio_gmi_pins_pm269));
792 }
793 }
794
795 return 0;
796}
diff --git a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
new file mode 100644
index 00000000000..8a862270e89
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
@@ -0,0 +1,803 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
3 *
4 * Copyright (C) 2011 NVIDIA, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20#include <linux/i2c.h>
21#include <linux/pda_power.h>
22#include <linux/platform_device.h>
23#include <linux/resource.h>
24#include <linux/regulator/machine.h>
25#include <linux/gpio.h>
26#include <linux/io.h>
27#include <linux/regulator/gpio-switch-regulator.h>
28#include <linux/regulator/fixed.h>
29#include <linux/mfd/max77663-core.h>
30#include <linux/regulator/max77663-regulator.h>
31
32#include <mach/iomap.h>
33#include <mach/irqs.h>
34#include <mach/pinmux.h>
35#include <mach/edp.h>
36
37#include "gpio-names.h"
38#include "board.h"
39#include "board-cardhu.h"
40#include "pm.h"
41#include "wakeups-t3.h"
42
43#define PMC_CTRL 0x0
44#define PMC_CTRL_INTR_LOW BIT(17)
45
46static struct regulator_consumer_supply max77663_sd0_supply[] = {
47 REGULATOR_SUPPLY("vdd_cpu_pmu", NULL),
48 REGULATOR_SUPPLY("vdd_cpu", NULL),
49 REGULATOR_SUPPLY("vdd_sys", NULL),
50};
51
52static struct regulator_consumer_supply max77663_sd1_supply[] = {
53 REGULATOR_SUPPLY("vdd_core", NULL),
54 REGULATOR_SUPPLY("en_vddio_ddr_1v2", NULL),
55};
56
57static struct regulator_consumer_supply max77663_sd2_supply[] = {
58 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
59 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
60 REGULATOR_SUPPLY("avdd_osc", NULL),
61 REGULATOR_SUPPLY("vdd1v8_satelite", NULL),
62 REGULATOR_SUPPLY("vddio_uart", NULL),
63 REGULATOR_SUPPLY("pwrdet_uart", NULL),
64 REGULATOR_SUPPLY("vddio_audio", NULL),
65 REGULATOR_SUPPLY("pwrdet_audio", NULL),
66 REGULATOR_SUPPLY("vddio_bb", NULL),
67 REGULATOR_SUPPLY("pwrdet_bb", NULL),
68 REGULATOR_SUPPLY("vddio_lcd_pmu", NULL),
69 REGULATOR_SUPPLY("pwrdet_lcd", NULL),
70 REGULATOR_SUPPLY("vddio_cam", NULL),
71 REGULATOR_SUPPLY("pwrdet_cam", NULL),
72 REGULATOR_SUPPLY("vddio_vi", NULL),
73 REGULATOR_SUPPLY("pwrdet_vi", NULL),
74 REGULATOR_SUPPLY("ldo6", NULL),
75 REGULATOR_SUPPLY("ldo7", NULL),
76 REGULATOR_SUPPLY("ldo8", NULL),
77 REGULATOR_SUPPLY("vcore_audio", NULL),
78 REGULATOR_SUPPLY("avcore_audio", NULL),
79 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.2"),
80 REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
81 REGULATOR_SUPPLY("vcore1_lpddr2", NULL),
82 REGULATOR_SUPPLY("vcom_1v8", NULL),
83 REGULATOR_SUPPLY("pmuio_1v8", NULL),
84 REGULATOR_SUPPLY("avdd_ic_usb", NULL),
85 REGULATOR_SUPPLY("vdd_gen1v8", NULL),
86};
87
88static struct regulator_consumer_supply max77663_sd3_supply[] = {
89 REGULATOR_SUPPLY("vdd_gen1v5", NULL),
90 REGULATOR_SUPPLY("vcore_lcd", NULL),
91 REGULATOR_SUPPLY("track_ldo1", NULL),
92 REGULATOR_SUPPLY("external_ldo_1v2", NULL),
93 REGULATOR_SUPPLY("vcore_cam1", NULL),
94 REGULATOR_SUPPLY("vcore_cam2", NULL),
95 REGULATOR_SUPPLY("avdd_pexb", NULL),
96 REGULATOR_SUPPLY("vdd_pexb", NULL),
97 REGULATOR_SUPPLY("avdd_pex_pll", NULL),
98 REGULATOR_SUPPLY("avdd_pexa", NULL),
99 REGULATOR_SUPPLY("vdd_pexa", NULL),
100 REGULATOR_SUPPLY("vcom_1v2", NULL),
101 REGULATOR_SUPPLY("vdio_hsic", NULL),
102};
103
104static struct regulator_consumer_supply max77663_ldo0_supply[] = {
105 REGULATOR_SUPPLY("vdd_ddr_hs", NULL),
106};
107
108static struct regulator_consumer_supply max77663_ldo1_supply[] = {
109 REGULATOR_SUPPLY("avdd_plla_p_c_s", NULL),
110 REGULATOR_SUPPLY("avdd_pllm", NULL),
111 REGULATOR_SUPPLY("avdd_pllu_d", NULL),
112 REGULATOR_SUPPLY("avdd_pllu_d2", NULL),
113 REGULATOR_SUPPLY("avdd_pllx", NULL),
114};
115
116static struct regulator_consumer_supply max77663_ldo2_supply[] = {
117 REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
118 REGULATOR_SUPPLY("pwrdet_mipi", NULL),
119};
120
121static struct regulator_consumer_supply max77663_ldo3_supply[] = {
122 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.3"),
123 REGULATOR_SUPPLY("pwrdet_sdmmc4", NULL),
124};
125
126static struct regulator_consumer_supply max77663_ldo4_supply[] = {
127 REGULATOR_SUPPLY("vdd_rtc", NULL),
128};
129
130static struct regulator_consumer_supply max77663_ldo5_supply[] = {
131 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.0"),
132 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
133};
134
135static struct regulator_consumer_supply max77663_ldo6_supply[] = {
136 REGULATOR_SUPPLY("vddio_sys", NULL),
137};
138
139static struct regulator_consumer_supply max77663_ldo7_supply[] = {
140 REGULATOR_SUPPLY("unused_ldo7", NULL),
141};
142
143static struct regulator_consumer_supply max77663_ldo8_supply[] = {
144 REGULATOR_SUPPLY("vcore_mmc", NULL),
145};
146
147static struct max77663_regulator_fps_cfg max77663_fps_cfgs[] = {
148 {
149 .src = FPS_SRC_0,
150 .en_src = FPS_EN_SRC_EN0,
151 .time_period = FPS_TIME_PERIOD_DEF,
152 },
153 {
154 .src = FPS_SRC_1,
155 .en_src = FPS_EN_SRC_EN1,
156 .time_period = FPS_TIME_PERIOD_DEF,
157 },
158 {
159 .src = FPS_SRC_2,
160 .en_src = FPS_EN_SRC_EN0,
161 .time_period = FPS_TIME_PERIOD_DEF,
162 },
163};
164
165#define MAX77663_PDATA_INIT(_id, _min_uV, _max_uV, _supply_reg, \
166 _always_on, _boot_on, _apply_uV, \
167 _init_apply, _init_enable, _init_uV, \
168 _fps_src, _fps_pu_period, _fps_pd_period, _flags) \
169 static struct max77663_regulator_platform_data max77663_regulator_pdata_##_id = \
170 { \
171 .init_data = { \
172 .constraints = { \
173 .min_uV = _min_uV, \
174 .max_uV = _max_uV, \
175 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
176 REGULATOR_MODE_STANDBY), \
177 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
178 REGULATOR_CHANGE_STATUS | \
179 REGULATOR_CHANGE_VOLTAGE), \
180 .always_on = _always_on, \
181 .boot_on = _boot_on, \
182 .apply_uV = _apply_uV, \
183 }, \
184 .num_consumer_supplies = \
185 ARRAY_SIZE(max77663_##_id##_supply), \
186 .consumer_supplies = max77663_##_id##_supply, \
187 .supply_regulator = _supply_reg, \
188 }, \
189 .init_apply = _init_apply, \
190 .init_enable = _init_enable, \
191 .init_uV = _init_uV, \
192 .fps_src = _fps_src, \
193 .fps_pu_period = _fps_pu_period, \
194 .fps_pd_period = _fps_pd_period, \
195 .fps_cfgs = max77663_fps_cfgs, \
196 .flags = _flags, \
197 }
198
199MAX77663_PDATA_INIT(sd0, 600000, 3387500, NULL, 1, 0, 0,
200 0, 0, -1, FPS_SRC_NONE, -1, -1, EN2_CTRL_SD0 | SD_FSRADE_DISABLE);
201
202MAX77663_PDATA_INIT(sd1, 800000, 1587500, NULL, 1, 0, 0,
203 1, 1, -1, FPS_SRC_1, -1, -1, SD_FSRADE_DISABLE);
204
205MAX77663_PDATA_INIT(sd2, 600000, 3387500, NULL, 1, 0, 0,
206 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
207
208MAX77663_PDATA_INIT(sd3, 600000, 3387500, NULL, 0, 0, 0,
209 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
210
211MAX77663_PDATA_INIT(ldo0, 800000, 2350000, max77663_rails(sd2), 0, 0, 0,
212 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
213
214MAX77663_PDATA_INIT(ldo1, 800000, 2350000, max77663_rails(sd2), 0, 0, 0,
215 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
216
217MAX77663_PDATA_INIT(ldo2, 800000, 3950000, max77663_rails(sd2), 0, 0, 0,
218 0, 0, -1, FPS_SRC_NONE, -1, -1, 0);
219
220MAX77663_PDATA_INIT(ldo3, 800000, 3950000, NULL, 0, 0, 0,
221 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
222
223MAX77663_PDATA_INIT(ldo4, 800000, 1587500, NULL, 0, 0, 0,
224 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
225
226MAX77663_PDATA_INIT(ldo5, 800000, 3950000, NULL, 0, 0, 0,
227 0, 0, -1, FPS_SRC_NONE, -1, -1, 0);
228
229MAX77663_PDATA_INIT(ldo6, 800000, 3950000, NULL, 1, 0, 0,
230 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
231
232MAX77663_PDATA_INIT(ldo7, 800000, 3950000, NULL, 0, 0, 0,
233 0, 0, -1, FPS_SRC_NONE, -1, -1, 0);
234
235MAX77663_PDATA_INIT(ldo8, 800000, 3950000, NULL, 0, 0, 0,
236 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
237
238#define MAX77663_REG(_id, _data) \
239 { \
240 .name = "max77663-regulator", \
241 .id = MAX77663_REGULATOR_ID_##_id, \
242 .platform_data = &max77663_regulator_pdata_##_data, \
243 .pdata_size = sizeof(max77663_regulator_pdata_##_data), \
244 }
245
246#define MAX77663_RTC() \
247 { \
248 .name = "max77663-rtc", \
249 .id = 0, \
250 }
251
252static struct mfd_cell max77663_subdevs[] = {
253 MAX77663_REG(SD0, sd0),
254 MAX77663_REG(SD1, sd1),
255 MAX77663_REG(SD2, sd2),
256 MAX77663_REG(SD3, sd3),
257 MAX77663_REG(LDO0, ldo0),
258 MAX77663_REG(LDO1, ldo1),
259 MAX77663_REG(LDO2, ldo2),
260 MAX77663_REG(LDO3, ldo3),
261 MAX77663_REG(LDO4, ldo4),
262 MAX77663_REG(LDO5, ldo5),
263 MAX77663_REG(LDO6, ldo6),
264 MAX77663_REG(LDO7, ldo7),
265 MAX77663_REG(LDO8, ldo8),
266 MAX77663_RTC(),
267};
268
269struct max77663_gpio_config max77663_gpio_cfgs[] = {
270 {
271 .gpio = MAX77663_GPIO0,
272 .dir = GPIO_DIR_OUT,
273 .dout = GPIO_DOUT_LOW,
274 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
275 .alternate = GPIO_ALT_DISABLE,
276 },
277 {
278 .gpio = MAX77663_GPIO1,
279 .dir = GPIO_DIR_OUT,
280 .dout = GPIO_DOUT_HIGH,
281 .out_drv = GPIO_OUT_DRV_OPEN_DRAIN,
282 .alternate = GPIO_ALT_DISABLE,
283 },
284 {
285 .gpio = MAX77663_GPIO2,
286 .dir = GPIO_DIR_OUT,
287 .dout = GPIO_DOUT_HIGH,
288 .out_drv = GPIO_OUT_DRV_OPEN_DRAIN,
289 .alternate = GPIO_ALT_DISABLE,
290 },
291 {
292 .gpio = MAX77663_GPIO3,
293 .dir = GPIO_DIR_OUT,
294 .dout = GPIO_DOUT_HIGH,
295 .out_drv = GPIO_OUT_DRV_OPEN_DRAIN,
296 .alternate = GPIO_ALT_DISABLE,
297 },
298 {
299 .gpio = MAX77663_GPIO4,
300 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
301 .alternate = GPIO_ALT_ENABLE,
302 },
303 {
304 .gpio = MAX77663_GPIO5,
305 .dir = GPIO_DIR_OUT,
306 .dout = GPIO_DOUT_LOW,
307 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
308 .alternate = GPIO_ALT_DISABLE,
309 },
310 {
311 .gpio = MAX77663_GPIO6,
312 .dir = GPIO_DIR_OUT,
313 .dout = GPIO_DOUT_LOW,
314 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
315 .alternate = GPIO_ALT_DISABLE,
316 },
317 {
318 .gpio = MAX77663_GPIO7,
319 .dir = GPIO_DIR_OUT,
320 .dout = GPIO_DOUT_LOW,
321 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
322 .alternate = GPIO_ALT_DISABLE,
323 },
324};
325
326static struct max77663_platform_data max7763_pdata = {
327 .irq_base = MAX77663_IRQ_BASE,
328 .gpio_base = MAX77663_GPIO_BASE,
329
330 .num_gpio_cfgs = ARRAY_SIZE(max77663_gpio_cfgs),
331 .gpio_cfgs = max77663_gpio_cfgs,
332
333 .num_subdevs = ARRAY_SIZE(max77663_subdevs),
334 .sub_devices = max77663_subdevs,
335
336 .use_power_off = true,
337};
338
339static struct i2c_board_info __initdata max77663_regulators[] = {
340 {
341 /* The I2C address was determined by OTP factory setting */
342 I2C_BOARD_INFO("max77663", 0x1C),
343 .irq = INT_EXTERNAL_PMU,
344 .platform_data = &max7763_pdata,
345 },
346};
347
348int __init cardhu_pm298_regulator_init(void)
349{
350 struct board_info board_info;
351 struct board_info pmu_board_info;
352 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
353 u32 pmc_ctrl;
354
355 /* configure the power management controller to trigger PMU
356 * interrupts when low */
357 pmc_ctrl = readl(pmc + PMC_CTRL);
358 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
359
360 /* The regulator details have complete constraints */
361 tegra_get_board_info(&board_info);
362 tegra_get_pmu_board_info(&pmu_board_info);
363 if (pmu_board_info.board_id != BOARD_PMU_PM298) {
364 pr_err("%s(): Board ID is not proper\n", __func__);
365 return -ENODEV;
366 }
367
368 i2c_register_board_info(4, max77663_regulators,
369 ARRAY_SIZE(max77663_regulators));
370
371 return 0;
372}
373
374static struct regulator_consumer_supply fixed_reg_en_track_ldo2_supply[] = {
375 REGULATOR_SUPPLY("avdd_sata", NULL),
376 REGULATOR_SUPPLY("vdd_sata", NULL),
377 REGULATOR_SUPPLY("avdd_sata_pll", NULL),
378 REGULATOR_SUPPLY("avdd_plle", NULL),
379};
380
381static struct regulator_consumer_supply fixed_reg_en_5v0_supply[] = {
382 REGULATOR_SUPPLY("vdd_5v0_sys", NULL),
383 REGULATOR_SUPPLY("vdd_5v0_sby", NULL),
384 REGULATOR_SUPPLY("vdd_hall", NULL),
385 REGULATOR_SUPPLY("vterm_ddr", NULL),
386 REGULATOR_SUPPLY("v2ref_ddr", NULL),
387};
388
389static struct regulator_consumer_supply fixed_reg_en_ddr_supply[] = {
390 REGULATOR_SUPPLY("mem_vddio_ddr", NULL),
391 REGULATOR_SUPPLY("t30_vddio_ddr", NULL),
392};
393
394static struct regulator_consumer_supply fixed_reg_en_3v3_sys_supply[] = {
395 REGULATOR_SUPPLY("avdd_vdac", NULL),
396 REGULATOR_SUPPLY("vdd_lvds", NULL),
397 REGULATOR_SUPPLY("vdd_pnl", NULL),
398 REGULATOR_SUPPLY("vcom_3v3", NULL),
399 REGULATOR_SUPPLY("vdd_3v3", NULL),
400 REGULATOR_SUPPLY("vddio_pex_ctl", NULL),
401 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
402 REGULATOR_SUPPLY("hvdd_pex_pmu", NULL),
403 REGULATOR_SUPPLY("avdd_hdmi", NULL),
404 REGULATOR_SUPPLY("vpp_fuse", NULL),
405 REGULATOR_SUPPLY("avdd_usb", NULL),
406 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
407 REGULATOR_SUPPLY("vcore_nand", NULL),
408 REGULATOR_SUPPLY("hvdd_sata", NULL),
409 REGULATOR_SUPPLY("vddio_gmi_pmu", NULL),
410 REGULATOR_SUPPLY("pwrdet_nand", NULL),
411 REGULATOR_SUPPLY("avdd_cam1", NULL),
412 REGULATOR_SUPPLY("vdd_af", NULL),
413 REGULATOR_SUPPLY("avdd_cam2", NULL),
414 REGULATOR_SUPPLY("vdd_acc", NULL),
415 REGULATOR_SUPPLY("vdd_phtl", NULL),
416 REGULATOR_SUPPLY("vddio_tp", NULL),
417 REGULATOR_SUPPLY("vdd_led", NULL),
418 REGULATOR_SUPPLY("vddio_cec", NULL),
419 REGULATOR_SUPPLY("vdd_cmps", NULL),
420 REGULATOR_SUPPLY("vdd_temp", NULL),
421 REGULATOR_SUPPLY("vpp_kfuse", NULL),
422 REGULATOR_SUPPLY("vddio_ts", NULL),
423 REGULATOR_SUPPLY("vdd_ir_led", NULL),
424 REGULATOR_SUPPLY("vddio_1wire", NULL),
425 REGULATOR_SUPPLY("avddio_audio", NULL),
426 REGULATOR_SUPPLY("vdd_ec", NULL),
427 REGULATOR_SUPPLY("vcom_pa", NULL),
428 REGULATOR_SUPPLY("vdd_3v3_devices", NULL),
429 REGULATOR_SUPPLY("vdd_3v3_dock", NULL),
430 REGULATOR_SUPPLY("vdd_3v3_edid", NULL),
431 REGULATOR_SUPPLY("vdd_3v3_hdmi_cec", NULL),
432 REGULATOR_SUPPLY("vdd_3v3_gmi", NULL),
433 REGULATOR_SUPPLY("vdd_3v3_spk_amp", NULL),
434 REGULATOR_SUPPLY("vdd_3v3_sensor", NULL),
435 REGULATOR_SUPPLY("vdd_3v3_cam", NULL),
436 REGULATOR_SUPPLY("vdd_3v3_als", NULL),
437 REGULATOR_SUPPLY("debug_cons", NULL),
438 REGULATOR_SUPPLY("vdd", "4-004c"),
439};
440
441/* DIS_5V_SWITCH from AP SPI2_SCK X02 */
442static struct regulator_consumer_supply fixed_reg_dis_5v_switch_supply[] = {
443 REGULATOR_SUPPLY("master_5v_switch", NULL),
444};
445
446/* EN_VDD_BL */
447static struct regulator_consumer_supply fixed_reg_en_vdd_bl_supply[] = {
448 REGULATOR_SUPPLY("vdd_backlight", NULL),
449 REGULATOR_SUPPLY("vdd_backlight1", NULL),
450};
451
452/* EN_3V3_MODEM from AP GPIO VI_VSYNCH D06*/
453static struct regulator_consumer_supply fixed_reg_en_3v3_modem_supply[] = {
454 REGULATOR_SUPPLY("vdd_3v3_mini_card", NULL),
455 REGULATOR_SUPPLY("vdd_mini_card", NULL),
456};
457/* EN_VDD_PNL1 from AP GPIO VI_D6 L04*/
458static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = {
459 REGULATOR_SUPPLY("vdd_lcd_panel", NULL),
460};
461
462/* CAM1_LDO_EN from AP GPIO KB_ROW6 R06*/
463static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = {
464 REGULATOR_SUPPLY("vdd_2v8_cam1", NULL),
465 REGULATOR_SUPPLY("vdd", "6-0072"),
466};
467
468/* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/
469static struct regulator_consumer_supply fixed_reg_cam2_ldo_en_supply[] = {
470 REGULATOR_SUPPLY("vdd_2v8_cam2", NULL),
471 REGULATOR_SUPPLY("vdd", "7-0072"),
472};
473
474/* CAM3_LDO_EN from AP GPIO KB_ROW8 S00*/
475static struct regulator_consumer_supply fixed_reg_cam3_ldo_en_supply[] = {
476 REGULATOR_SUPPLY("vdd_cam3", NULL),
477};
478
479/* EN_VDD_COM from AP GPIO SDMMC3_DAT5 D00*/
480static struct regulator_consumer_supply fixed_reg_en_vdd_com_supply[] = {
481 REGULATOR_SUPPLY("vdd_com_bd", NULL),
482};
483
484/* EN_VDD_SDMMC1 from AP GPIO VI_HSYNC D07*/
485static struct regulator_consumer_supply fixed_reg_en_vdd_sdmmc1_supply[] = {
486 REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.0"),
487};
488
489/* EN_3V3_EMMC from AP GPIO SDMMC3_DAT4 D01*/
490static struct regulator_consumer_supply fixed_reg_en_3v3_emmc_supply[] = {
491 REGULATOR_SUPPLY("vdd_emmc_core", NULL),
492};
493
494/* EN_3V3_PEX_HVDD from AP GPIO VI_D09 L07*/
495static struct regulator_consumer_supply fixed_reg_en_3v3_pex_hvdd_supply[] = {
496 REGULATOR_SUPPLY("hvdd_pex", NULL),
497};
498
499/* EN_3v3_FUSE from AP GPIO VI_D08 L06*/
500static struct regulator_consumer_supply fixed_reg_en_3v3_fuse_supply[] = {
501 REGULATOR_SUPPLY("vdd_fuse", NULL),
502};
503
504/* EN_1V8_CAM from AP GPIO GPIO_PBB4 PBB04*/
505static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
506 REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
507 REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
508 REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
509 REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
510 REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
511 REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
512};
513
514static struct regulator_consumer_supply fixed_reg_en_vbrtr_supply[] = {
515 REGULATOR_SUPPLY("vdd_vbrtr", NULL),
516};
517
518
519/* EN_USB1_VBUS_OC*/
520static struct regulator_consumer_supply gpio_switch_en_usb1_vbus_oc_supply[] = {
521 REGULATOR_SUPPLY("vdd_vbus_micro_usb", NULL),
522};
523static int gpio_switch_en_usb1_vbus_oc_voltages[] = { 5000};
524
525/*EN_USB3_VBUS_OC*/
526static struct regulator_consumer_supply gpio_switch_en_usb3_vbus_oc_supply[] = {
527 REGULATOR_SUPPLY("vdd_vbus_typea_usb", NULL),
528};
529static int gpio_switch_en_usb3_vbus_oc_voltages[] = { 5000};
530
531/* EN_VDDIO_VID_OC from AP GPIO VI_PCLK T00*/
532static struct regulator_consumer_supply gpio_switch_en_vddio_vid_oc_supply[] = {
533 REGULATOR_SUPPLY("vdd_hdmi_con", NULL),
534};
535static int gpio_switch_en_vddio_vid_oc_voltages[] = { 5000};
536
537
538static int enable_load_switch_rail(
539 struct gpio_switch_regulator_subdev_data *psubdev_data)
540{
541 int ret;
542
543 if (psubdev_data->pin_group <= 0)
544 return -EINVAL;
545
546 /* Tristate and make pin as input*/
547 ret = tegra_pinmux_set_tristate(psubdev_data->pin_group,
548 TEGRA_TRI_TRISTATE);
549 if (ret < 0)
550 return ret;
551 return gpio_direction_input(psubdev_data->gpio_nr);
552}
553
554static int disable_load_switch_rail(
555 struct gpio_switch_regulator_subdev_data *psubdev_data)
556{
557 int ret;
558
559 if (psubdev_data->pin_group <= 0)
560 return -EINVAL;
561
562 /* Un-tristate and driver low */
563 ret = tegra_pinmux_set_tristate(psubdev_data->pin_group,
564 TEGRA_TRI_NORMAL);
565 if (ret < 0)
566 return ret;
567 return gpio_direction_output(psubdev_data->gpio_nr, 0);
568}
569
570/* Macro for defining gpio switch regulator sub device data */
571#define GREG_INIT(_id, _var, _name, _input_supply, _always_on, _boot_on, \
572 _gpio_nr, _active_low, _init_state, _pg, _enable, _disable) \
573 static struct gpio_switch_regulator_subdev_data gpio_pdata_##_var = \
574 { \
575 .regulator_name = "gpio-switch-"#_name, \
576 .input_supply = _input_supply, \
577 .id = _id, \
578 .gpio_nr = _gpio_nr, \
579 .pin_group = _pg, \
580 .active_low = _active_low, \
581 .init_state = _init_state, \
582 .voltages = gpio_switch_##_name##_voltages, \
583 .n_voltages = ARRAY_SIZE(gpio_switch_##_name##_voltages), \
584 .num_consumer_supplies = \
585 ARRAY_SIZE(gpio_switch_##_name##_supply), \
586 .consumer_supplies = gpio_switch_##_name##_supply, \
587 .constraints = { \
588 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
589 REGULATOR_MODE_STANDBY), \
590 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
591 REGULATOR_CHANGE_STATUS | \
592 REGULATOR_CHANGE_VOLTAGE), \
593 .always_on = _always_on, \
594 .boot_on = _boot_on, \
595 }, \
596 .enable_rail = _enable, \
597 .disable_rail = _disable, \
598 }; \
599 static struct gpio_switch_regulator_subdev_data \
600 *gpio_pdata_##_var##_list[] = { \
601 &gpio_pdata_##_var, \
602 }; \
603 static struct gpio_switch_regulator_platform_data gs_##_var##_pdata = \
604 { \
605 .num_subdevs = 1, \
606 .subdevs = gpio_pdata_##_var##_list, \
607 }; \
608 static struct platform_device gswitch_reg_##_var##_dev = { \
609 .name = "gpio-switch-regulator", \
610 .id = _id, \
611 .dev = { \
612 .platform_data = &gs_##_var##_pdata, \
613 }, \
614 }
615
616/* Macro for defining fixed regulator sub device data */
617#define FIXED_SUPPLY(_name) "fixed_reg_"#_name
618#define FIXED_REG(_id, _var, _name, _in_supply, _always_on, _boot_on, \
619 _gpio_nr, _active_high, _boot_state, _millivolts) \
620 static struct regulator_init_data ri_data_##_var = \
621 { \
622 .supply_regulator = _in_supply, \
623 .num_consumer_supplies = \
624 ARRAY_SIZE(fixed_reg_##_name##_supply), \
625 .consumer_supplies = fixed_reg_##_name##_supply, \
626 .constraints = { \
627 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
628 REGULATOR_MODE_STANDBY), \
629 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
630 REGULATOR_CHANGE_STATUS | \
631 REGULATOR_CHANGE_VOLTAGE), \
632 .always_on = _always_on, \
633 .boot_on = _boot_on, \
634 }, \
635 }; \
636 static struct fixed_voltage_config fixed_reg_##_var##_pdata = \
637 { \
638 .supply_name = FIXED_SUPPLY(_name), \
639 .microvolts = _millivolts * 1000, \
640 .gpio = _gpio_nr, \
641 .enable_high = _active_high, \
642 .enabled_at_boot = _boot_state, \
643 .init_data = &ri_data_##_var, \
644 }; \
645 static struct platform_device fixed_reg_##_var##_dev = { \
646 .name = "reg-fixed-voltage", \
647 .id = _id, \
648 .dev = { \
649 .platform_data = &fixed_reg_##_var##_pdata, \
650 }, \
651 }
652
653/* common to most of boards*/
654FIXED_REG(0, en_track_ldo2, en_track_ldo2, NULL, 0, 0, MAX77663_GPIO_BASE + MAX77663_GPIO0, true, 0, 3300);
655FIXED_REG(1, en_5v0, en_5v0, NULL, 1, 0, MAX77663_GPIO_BASE + MAX77663_GPIO2, true, 1, 5000);
656FIXED_REG(2, en_ddr, en_ddr, NULL, 1, 0, MAX77663_GPIO_BASE + MAX77663_GPIO3, true, 1, 1500);
657FIXED_REG(3, en_3v3_sys, en_3v3_sys, NULL, 1, 0, MAX77663_GPIO_BASE + MAX77663_GPIO1, true, 1, 3300);
658FIXED_REG(4, en_vdd_bl, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PK3, true, 1, 5000);
659FIXED_REG(5, en_3v3_modem, en_3v3_modem, NULL, 1, 0, TEGRA_GPIO_PD6, true, 1, 3300);
660FIXED_REG(6, en_vdd_pnl1, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL4, true, 1, 3300);
661FIXED_REG(7, cam3_ldo_en, cam3_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PS0, true, 0, 3300);
662FIXED_REG(8, en_vdd_com, en_vdd_com, FIXED_SUPPLY(en_3v3_sys), 1, 0, TEGRA_GPIO_PD0, true, 1, 3300);
663FIXED_REG(9, en_3v3_fuse, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL6, true, 0, 3300);
664FIXED_REG(10, en_3v3_emmc, en_3v3_emmc, FIXED_SUPPLY(en_3v3_sys), 1, 0, TEGRA_GPIO_PD1, true, 1, 3300);
665FIXED_REG(11, en_vdd_sdmmc1, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PD7, true, 1, 3300);
666FIXED_REG(12, en_3v3_pex_hvdd, en_3v3_pex_hvdd, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL7, true, 0, 3300);
667FIXED_REG(13, en_1v8_cam, en_1v8_cam, max77663_rails(sd2), 0, 0, TEGRA_GPIO_PBB4, true, 0, 1800);
668
669/*Specific to pm269*/
670FIXED_REG(4, en_vdd_bl_pm269, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PH3, true, 1, 5000);
671FIXED_REG(6, en_vdd_pnl1_pm269, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PW1, true, 0, 3300);
672FIXED_REG(9, en_3v3_fuse_pm269, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PC1, true, 0, 3300);
673FIXED_REG(12, en_3v3_pex_hvdd_pm269, en_3v3_pex_hvdd, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PC6, true, 0, 3300);
674
675/* Specific to E1187/E1186/E1256 */
676FIXED_REG(14, dis_5v_switch_e118x, dis_5v_switch, FIXED_SUPPLY(en_5v0), 0, 0, TEGRA_GPIO_PX2, false, 0, 5000);
677
678/* E1198/E1291 specific*/
679FIXED_REG(18, cam1_ldo_en, cam1_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PR6, true, 0, 2800);
680FIXED_REG(19, cam2_ldo_en, cam2_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PR7, true, 0, 2800);
681FIXED_REG(22, en_vbrtr, en_vbrtr, FIXED_SUPPLY(en_3v3_sys), 0, 0, PMU_TCA6416_GPIO_PORT12, true, 0, 3300);
682
683/**** Open collector Load switches ****/
684/*Specific to pm269*/
685GREG_INIT(17, en_vddio_vid_oc_pm269, en_vddio_vid_oc, "master_5v_switch",
686 0, 0, TEGRA_GPIO_PP2, false, 0, TEGRA_PINGROUP_DAP3_DOUT,
687 enable_load_switch_rail, disable_load_switch_rail);
688
689/* Specific to E1187/E1186/E1256 */
690GREG_INIT(15, en_usb1_vbus_oc_e118x, en_usb1_vbus_oc, "master_5v_switch",
691 0, 0, TEGRA_GPIO_PI4, false, 0, TEGRA_PINGROUP_GMI_RST_N,
692 enable_load_switch_rail, disable_load_switch_rail);
693GREG_INIT(16, en_usb3_vbus_oc_e118x, en_usb3_vbus_oc, "master_5v_switch",
694 0, 0, TEGRA_GPIO_PH7, false, 0, TEGRA_PINGROUP_GMI_AD15,
695 enable_load_switch_rail, disable_load_switch_rail);
696GREG_INIT(17, en_vddio_vid_oc_e118x, en_vddio_vid_oc, "master_5v_switch",
697 0, 0, TEGRA_GPIO_PT0, false, 0, TEGRA_PINGROUP_VI_PCLK,
698 enable_load_switch_rail, disable_load_switch_rail);
699
700/*
701 * Creating the fixed/gpio-switch regulator device tables for different boards
702 */
703#define ADD_FIXED_REG(_name) (&fixed_reg_##_name##_dev)
704#define ADD_GPIO_REG(_name) (&gswitch_reg_##_name##_dev)
705
706#define COMMON_FIXED_REG \
707 ADD_FIXED_REG(en_track_ldo2), \
708 ADD_FIXED_REG(en_5v0), \
709 ADD_FIXED_REG(en_ddr), \
710 ADD_FIXED_REG(en_3v3_sys), \
711 ADD_FIXED_REG(en_3v3_modem), \
712 ADD_FIXED_REG(en_vdd_pnl1), \
713 ADD_FIXED_REG(cam1_ldo_en), \
714 ADD_FIXED_REG(cam2_ldo_en), \
715 ADD_FIXED_REG(cam3_ldo_en), \
716 ADD_FIXED_REG(en_vdd_com), \
717 ADD_FIXED_REG(en_3v3_fuse), \
718 ADD_FIXED_REG(en_3v3_emmc), \
719 ADD_FIXED_REG(en_vdd_sdmmc1), \
720 ADD_FIXED_REG(en_3v3_pex_hvdd), \
721 ADD_FIXED_REG(en_1v8_cam),
722
723#define PM269_FIXED_REG \
724 ADD_FIXED_REG(en_track_ldo2), \
725 ADD_FIXED_REG(en_5v0), \
726 ADD_FIXED_REG(en_ddr), \
727 ADD_FIXED_REG(en_vdd_bl_pm269), \
728 ADD_FIXED_REG(en_3v3_sys), \
729 ADD_FIXED_REG(en_3v3_modem), \
730 ADD_FIXED_REG(en_vdd_pnl1_pm269), \
731 ADD_FIXED_REG(cam1_ldo_en), \
732 ADD_FIXED_REG(cam2_ldo_en), \
733 ADD_FIXED_REG(cam3_ldo_en), \
734 ADD_FIXED_REG(en_vdd_com), \
735 ADD_FIXED_REG(en_3v3_fuse_pm269), \
736 ADD_FIXED_REG(en_3v3_emmc), \
737 ADD_FIXED_REG(en_3v3_pex_hvdd_pm269), \
738 ADD_FIXED_REG(en_1v8_cam), \
739 ADD_FIXED_REG(dis_5v_switch_e118x), \
740 ADD_GPIO_REG(en_usb1_vbus_oc_e118x), \
741 ADD_GPIO_REG(en_usb3_vbus_oc_e118x), \
742 ADD_GPIO_REG(en_vddio_vid_oc_pm269),
743
744#define E118x_FIXED_REG \
745 ADD_FIXED_REG(en_vdd_bl), \
746 ADD_FIXED_REG(dis_5v_switch_e118x), \
747 ADD_FIXED_REG(en_vbrtr), \
748 ADD_GPIO_REG(en_usb1_vbus_oc_e118x), \
749 ADD_GPIO_REG(en_usb3_vbus_oc_e118x), \
750 ADD_GPIO_REG(en_vddio_vid_oc_e118x), \
751
752/* Gpio switch regulator platform data for E1186/E1187/E1256*/
753static struct platform_device *fixed_reg_devs_e118x[] = {
754 COMMON_FIXED_REG
755 E118x_FIXED_REG
756};
757
758/* Gpio switch regulator platform data for PM269*/
759static struct platform_device *fixed_reg_devs_pm269[] = {
760 PM269_FIXED_REG
761};
762
763int __init cardhu_pm298_gpio_switch_regulator_init(void)
764{
765 int i;
766 struct board_info board_info;
767 struct platform_device **fixed_reg_devs;
768 int nfixreg_devs;
769
770 tegra_get_board_info(&board_info);
771
772 switch (board_info.board_id) {
773 case BOARD_PM269:
774 case BOARD_PM305:
775 case BOARD_PM311:
776 case BOARD_E1257:
777 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm269);
778 fixed_reg_devs = fixed_reg_devs_pm269;
779 break;
780
781 default:
782 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e118x);
783 fixed_reg_devs = fixed_reg_devs_e118x;
784 break;
785 }
786
787 for (i = 0; i < nfixreg_devs; ++i) {
788 int gpio_nr;
789 if (!strncmp(fixed_reg_devs[i]->name, "gpio", 4)) {
790 struct gpio_switch_regulator_platform_data *gs_pdata =
791 fixed_reg_devs[i]->dev.platform_data;
792 gpio_nr = gs_pdata->subdevs[0]->gpio_nr;
793 } else {
794 struct fixed_voltage_config *fixed_reg_pdata =
795 fixed_reg_devs[i]->dev.platform_data;
796 gpio_nr = fixed_reg_pdata->gpio;
797 }
798
799 if (gpio_nr < TEGRA_NR_GPIOS)
800 tegra_gpio_enable(gpio_nr);
801 }
802 return platform_add_devices(fixed_reg_devs, nfixreg_devs);
803}
diff --git a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
new file mode 100644
index 00000000000..798904c1809
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
@@ -0,0 +1,791 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
3 *
4 * Copyright (C) 2011 NVIDIA, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20#include <linux/i2c.h>
21#include <linux/pda_power.h>
22#include <linux/platform_device.h>
23#include <linux/resource.h>
24#include <linux/regulator/machine.h>
25#include <linux/mfd/ricoh583.h>
26#include <linux/gpio.h>
27#include <linux/io.h>
28#include <linux/regulator/gpio-switch-regulator.h>
29#include <linux/regulator/fixed.h>
30#include <linux/regulator/ricoh583-regulator.h>
31#include <linux/regulator/tps62360.h>
32
33#include <mach/iomap.h>
34#include <mach/irqs.h>
35#include <mach/pinmux.h>
36#include <mach/edp.h>
37
38#include "gpio-names.h"
39#include "board.h"
40#include "board-cardhu.h"
41#include "wakeups-t3.h"
42
43#define PMC_CTRL 0x0
44#define PMC_CTRL_INTR_LOW (1 << 17)
45
46static struct regulator_consumer_supply ricoh583_dc1_supply_skubit0_0[] = {
47 REGULATOR_SUPPLY("vdd_core", NULL),
48 REGULATOR_SUPPLY("en_vddio_ddr_1v2", NULL),
49};
50
51static struct regulator_consumer_supply ricoh583_dc1_supply_skubit0_1[] = {
52 REGULATOR_SUPPLY("en_vddio_ddr_1v2", NULL),
53};
54
55static struct regulator_consumer_supply ricoh583_dc3_supply_0[] = {
56 REGULATOR_SUPPLY("vdd_gen1v5", NULL),
57 REGULATOR_SUPPLY("vcore_lcd", NULL),
58 REGULATOR_SUPPLY("track_ldo1", NULL),
59 REGULATOR_SUPPLY("external_ldo_1v2", NULL),
60 REGULATOR_SUPPLY("vcore_cam1", NULL),
61 REGULATOR_SUPPLY("vcore_cam2", NULL),
62};
63
64static struct regulator_consumer_supply ricoh583_dc0_supply_0[] = {
65 REGULATOR_SUPPLY("vdd_cpu_pmu", NULL),
66 REGULATOR_SUPPLY("vdd_cpu", NULL),
67 REGULATOR_SUPPLY("vdd_sys", NULL),
68};
69
70static struct regulator_consumer_supply ricoh583_dc2_supply_0[] = {
71 REGULATOR_SUPPLY("vdd_gen1v8", NULL),
72 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
73 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
74 REGULATOR_SUPPLY("avdd_osc", NULL),
75 REGULATOR_SUPPLY("vddio_sys", NULL),
76 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.3"),
77 REGULATOR_SUPPLY("pwrdet_sdmmc4", NULL),
78 REGULATOR_SUPPLY("vdd1v8_satelite", NULL),
79 REGULATOR_SUPPLY("vddio_uart", NULL),
80 REGULATOR_SUPPLY("pwrdet_uart", NULL),
81 REGULATOR_SUPPLY("vddio_audio", NULL),
82 REGULATOR_SUPPLY("pwrdet_audio", NULL),
83 REGULATOR_SUPPLY("vddio_bb", NULL),
84 REGULATOR_SUPPLY("pwrdet_bb", NULL),
85 REGULATOR_SUPPLY("vddio_lcd_pmu", NULL),
86 REGULATOR_SUPPLY("pwrdet_lcd", NULL),
87 REGULATOR_SUPPLY("vddio_cam", NULL),
88 REGULATOR_SUPPLY("pwrdet_cam", NULL),
89 REGULATOR_SUPPLY("vddio_vi", NULL),
90 REGULATOR_SUPPLY("pwrdet_vi", NULL),
91 REGULATOR_SUPPLY("ldo6", NULL),
92 REGULATOR_SUPPLY("ldo7", NULL),
93 REGULATOR_SUPPLY("ldo8", NULL),
94 REGULATOR_SUPPLY("vcore_audio", NULL),
95 REGULATOR_SUPPLY("avcore_audio", NULL),
96 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.2"),
97 REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
98 REGULATOR_SUPPLY("vcore1_lpddr2", NULL),
99 REGULATOR_SUPPLY("vcom_1v8", NULL),
100 REGULATOR_SUPPLY("pmuio_1v8", NULL),
101 REGULATOR_SUPPLY("avdd_ic_usb", NULL),
102};
103
104static struct regulator_consumer_supply ricoh583_ldo0_supply_0[] = {
105 REGULATOR_SUPPLY("unused_ldo0", NULL),
106};
107
108static struct regulator_consumer_supply ricoh583_ldo1_supply_0[] = {
109 REGULATOR_SUPPLY("avdd_pexb", NULL),
110 REGULATOR_SUPPLY("vdd_pexb", NULL),
111 REGULATOR_SUPPLY("avdd_pex_pll", NULL),
112 REGULATOR_SUPPLY("avdd_pexa", NULL),
113 REGULATOR_SUPPLY("vdd_pexa", NULL),
114};
115
116static struct regulator_consumer_supply ricoh583_ldo2_supply_0[] = {
117 REGULATOR_SUPPLY("avdd_sata", NULL),
118 REGULATOR_SUPPLY("vdd_sata", NULL),
119 REGULATOR_SUPPLY("avdd_sata_pll", NULL),
120 REGULATOR_SUPPLY("avdd_plle", NULL),
121};
122
123static struct regulator_consumer_supply ricoh583_ldo3_supply_0[] = {
124 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.0"),
125 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
126};
127
128static struct regulator_consumer_supply ricoh583_ldo4_supply_0[] = {
129 REGULATOR_SUPPLY("vdd_rtc", NULL),
130};
131
132static struct regulator_consumer_supply ricoh583_ldo5_supply_0[] = {
133 REGULATOR_SUPPLY("avdd_vdac", NULL),
134};
135
136static struct regulator_consumer_supply ricoh583_ldo6_supply_0[] = {
137 REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
138 REGULATOR_SUPPLY("pwrdet_mipi", NULL),
139};
140static struct regulator_consumer_supply ricoh583_ldo7_supply_0[] = {
141 REGULATOR_SUPPLY("avdd_plla_p_c_s", NULL),
142 REGULATOR_SUPPLY("avdd_pllm", NULL),
143 REGULATOR_SUPPLY("avdd_pllu_d", NULL),
144 REGULATOR_SUPPLY("avdd_pllu_d2", NULL),
145 REGULATOR_SUPPLY("avdd_pllx", NULL),
146};
147
148static struct regulator_consumer_supply ricoh583_ldo8_supply_0[] = {
149 REGULATOR_SUPPLY("vdd_ddr_hs", NULL),
150};
151
152#define RICOH_PDATA_INIT(_name, _sname, _minmv, _maxmv, _supply_reg, _always_on, \
153 _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, _flags, \
154 _ext_contol, _ds_slots) \
155 static struct ricoh583_regulator_platform_data pdata_##_name##_##_sname = \
156 { \
157 .regulator = { \
158 .constraints = { \
159 .min_uV = (_minmv)*1000, \
160 .max_uV = (_maxmv)*1000, \
161 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
162 REGULATOR_MODE_STANDBY), \
163 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
164 REGULATOR_CHANGE_STATUS | \
165 REGULATOR_CHANGE_VOLTAGE), \
166 .always_on = _always_on, \
167 .boot_on = _boot_on, \
168 .apply_uV = _apply_uv, \
169 }, \
170 .num_consumer_supplies = \
171 ARRAY_SIZE(ricoh583_##_name##_supply_##_sname), \
172 .consumer_supplies = ricoh583_##_name##_supply_##_sname, \
173 .supply_regulator = _supply_reg, \
174 }, \
175 .init_uV = _init_uV * 1000, \
176 .init_enable = _init_enable, \
177 .init_apply = _init_apply, \
178 .deepsleep_slots = _ds_slots, \
179 .flags = _flags, \
180 .ext_pwr_req = _ext_contol, \
181 }
182
183RICOH_PDATA_INIT(dc0, 0, 700, 1500, 0, 1, 1, 0, -1, 0, 0, 0,
184 RICOH583_EXT_PWRREQ2_CONTROL, 0);
185RICOH_PDATA_INIT(dc1, skubit0_0, 700, 1500, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0);
186RICOH_PDATA_INIT(dc2, 0, 900, 2400, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0);
187RICOH_PDATA_INIT(dc3, 0, 900, 2400, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0);
188
189RICOH_PDATA_INIT(ldo0, 0, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
190RICOH_PDATA_INIT(ldo1, 0, 1000, 3300, ricoh583_rails(DC1), 0, 0, 0, -1, 0, 0, 0, 0, 0);
191RICOH_PDATA_INIT(ldo2, 0, 1050, 1050, ricoh583_rails(DC1), 0, 0, 1, -1, 0, 0, 0, 0, 0);
192
193RICOH_PDATA_INIT(ldo3, 0, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
194RICOH_PDATA_INIT(ldo4, 0, 750, 1500, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
195RICOH_PDATA_INIT(ldo5, 0, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
196
197RICOH_PDATA_INIT(ldo6, 0, 1200, 1200, ricoh583_rails(DC2), 0, 0, 1, -1, 0, 0, 0, 0, 0);
198RICOH_PDATA_INIT(ldo7, 0, 1200, 1200, ricoh583_rails(DC2), 1, 1, 1, -1, 0, 0, 0, 0, 0);
199RICOH_PDATA_INIT(ldo8, 0, 900, 3400, ricoh583_rails(DC2), 1, 0, 0, -1, 0, 0, 0, 0, 0);
200
201static struct ricoh583_rtc_platform_data rtc_data = {
202 .irq = TEGRA_NR_IRQS + RICOH583_IRQ_YALE,
203 .time = {
204 .tm_year = 2011,
205 .tm_mon = 0,
206 .tm_mday = 1,
207 .tm_hour = 0,
208 .tm_min = 0,
209 .tm_sec = 0,
210 },
211};
212
213#define RICOH_RTC_REG() \
214{ \
215 .id = 0, \
216 .name = "rtc_ricoh583", \
217 .platform_data = &rtc_data, \
218}
219
220#define RICOH_REG(_id, _name, _sname) \
221{ \
222 .id = RICOH583_ID_##_id, \
223 .name = "ricoh583-regulator", \
224 .platform_data = &pdata_##_name##_##_sname, \
225}
226
227#define RICOH583_DEV_COMMON_E118X \
228 RICOH_REG(DC0, dc0, 0), \
229 RICOH_REG(DC1, dc1, skubit0_0), \
230 RICOH_REG(DC2, dc2, 0), \
231 RICOH_REG(DC3, dc3, 0), \
232 RICOH_REG(LDO0, ldo8, 0), \
233 RICOH_REG(LDO1, ldo7, 0), \
234 RICOH_REG(LDO2, ldo6, 0), \
235 RICOH_REG(LDO3, ldo5, 0), \
236 RICOH_REG(LDO4, ldo4, 0), \
237 RICOH_REG(LDO5, ldo3, 0), \
238 RICOH_REG(LDO6, ldo0, 0), \
239 RICOH_REG(LDO7, ldo1, 0), \
240 RICOH_REG(LDO8, ldo2, 0), \
241 RICOH_RTC_REG()
242
243static struct ricoh583_subdev_info ricoh_devs_e118x_dcdc[] = {
244 RICOH583_DEV_COMMON_E118X,
245};
246
247#define RICOH_GPIO_INIT(_init_apply, _pulldn, _output_mode, _output_val) \
248 { \
249 .pulldn_en = _pulldn, \
250 .output_mode_en = _output_mode, \
251 .output_val = _output_val, \
252 .init_apply = _init_apply, \
253 }
254struct ricoh583_gpio_init_data ricoh_gpio_data[] = {
255 RICOH_GPIO_INIT(false, false, false, 0),
256 RICOH_GPIO_INIT(false, false, false, 0),
257 RICOH_GPIO_INIT(false, false, false, 0),
258 RICOH_GPIO_INIT(true, false, true, 1),
259 RICOH_GPIO_INIT(true, false, true, 1),
260 RICOH_GPIO_INIT(false, false, false, 0),
261 RICOH_GPIO_INIT(false, false, false, 0),
262 RICOH_GPIO_INIT(false, false, false, 0),
263};
264
265static struct ricoh583_platform_data ricoh_platform = {
266 .irq_base = RICOH583_IRQ_BASE,
267 .gpio_base = RICOH583_GPIO_BASE,
268 .gpio_init_data = ricoh_gpio_data,
269 .num_gpioinit_data = ARRAY_SIZE(ricoh_gpio_data),
270 .enable_shutdown_pin = true,
271};
272
273static struct i2c_board_info __initdata ricoh583_regulators[] = {
274 {
275 I2C_BOARD_INFO("ricoh583", 0x34),
276 .irq = INT_EXTERNAL_PMU,
277 .platform_data = &ricoh_platform,
278 },
279};
280
281/* TPS62361B DC-DC converter */
282static struct regulator_consumer_supply tps62361_dcdc_supply[] = {
283 REGULATOR_SUPPLY("vdd_core", NULL),
284};
285
286static struct tps62360_regulator_platform_data tps62361_pdata = {
287 .reg_init_data = { \
288 .constraints = { \
289 .min_uV = 500000, \
290 .max_uV = 1770000, \
291 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
292 REGULATOR_MODE_STANDBY), \
293 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
294 REGULATOR_CHANGE_STATUS | \
295 REGULATOR_CHANGE_VOLTAGE), \
296 .always_on = 1, \
297 .boot_on = 1, \
298 .apply_uV = 0, \
299 }, \
300 .num_consumer_supplies = ARRAY_SIZE(tps62361_dcdc_supply), \
301 .consumer_supplies = tps62361_dcdc_supply, \
302 }, \
303 .en_discharge = true, \
304 .vsel0_gpio = -1, \
305 .vsel1_gpio = -1, \
306 .vsel0_def_state = 1, \
307 .vsel1_def_state = 1, \
308};
309
310static struct i2c_board_info __initdata tps62361_boardinfo[] = {
311 {
312 I2C_BOARD_INFO("tps62361", 0x60),
313 .platform_data = &tps62361_pdata,
314 },
315};
316
317int __init cardhu_pm299_regulator_init(void)
318{
319 struct board_info board_info;
320 struct board_info pmu_board_info;
321 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
322 u32 pmc_ctrl;
323
324 /* configure the power management controller to trigger PMU
325 * interrupts when low */
326 pmc_ctrl = readl(pmc + PMC_CTRL);
327 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
328
329 /* The regulator details have complete constraints */
330 tegra_get_board_info(&board_info);
331 tegra_get_pmu_board_info(&pmu_board_info);
332 if (pmu_board_info.board_id != BOARD_PMU_PM299) {
333 pr_err("%s(): Board ID is not proper\n", __func__);
334 return -ENODEV;
335 }
336
337 /* If TPS6236x DCDC is there then consumer for dc1 should
338 * not have vdd_core */
339 if ((board_info.sku & SKU_DCDC_TPS62361_SUPPORT) ||
340 (pmu_board_info.sku & SKU_DCDC_TPS62361_SUPPORT)) {
341 pdata_dc1_skubit0_0.regulator.consumer_supplies =
342 ricoh583_dc1_supply_skubit0_1;
343 pdata_dc1_skubit0_0.regulator.num_consumer_supplies =
344 ARRAY_SIZE(ricoh583_dc1_supply_skubit0_1);
345 }
346
347 ricoh_platform.num_subdevs = ARRAY_SIZE(ricoh_devs_e118x_dcdc);
348 ricoh_platform.subdevs = ricoh_devs_e118x_dcdc;
349
350 i2c_register_board_info(4, ricoh583_regulators, 1);
351
352 /* Register the TPS6236x for all boards whose sku bit 0 is set. */
353 if ((board_info.sku & SKU_DCDC_TPS62361_SUPPORT) ||
354 (pmu_board_info.sku & SKU_DCDC_TPS62361_SUPPORT)) {
355 pr_info("Registering the device TPS62361\n");
356 i2c_register_board_info(4, tps62361_boardinfo, 1);
357 }
358 return 0;
359}
360
361/* EN_5V_CP from PMU GP0 */
362static struct regulator_consumer_supply fixed_reg_en_5v_cp_supply[] = {
363 REGULATOR_SUPPLY("vdd_5v0_sby", NULL),
364 REGULATOR_SUPPLY("vdd_hall", NULL),
365 REGULATOR_SUPPLY("vterm_ddr", NULL),
366 REGULATOR_SUPPLY("v2ref_ddr", NULL),
367};
368
369/* EN_5V0 From PMU GP2 */
370static struct regulator_consumer_supply fixed_reg_en_5v0_supply[] = {
371 REGULATOR_SUPPLY("vdd_5v0_sys", NULL),
372};
373
374/* EN_DDR From PMU GP6 */
375static struct regulator_consumer_supply fixed_reg_en_ddr_supply[] = {
376 REGULATOR_SUPPLY("mem_vddio_ddr", NULL),
377 REGULATOR_SUPPLY("t30_vddio_ddr", NULL),
378};
379
380/* EN_3V3_SYS From PMU GP7 */
381static struct regulator_consumer_supply fixed_reg_en_3v3_sys_supply[] = {
382 REGULATOR_SUPPLY("vdd_lvds", NULL),
383 REGULATOR_SUPPLY("vdd_pnl", NULL),
384 REGULATOR_SUPPLY("vcom_3v3", NULL),
385 REGULATOR_SUPPLY("vdd_3v3", NULL),
386 REGULATOR_SUPPLY("vcore_mmc", NULL),
387 REGULATOR_SUPPLY("vddio_pex_ctl", NULL),
388 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
389 REGULATOR_SUPPLY("hvdd_pex_pmu", NULL),
390 REGULATOR_SUPPLY("avdd_hdmi", NULL),
391 REGULATOR_SUPPLY("vpp_fuse", NULL),
392 REGULATOR_SUPPLY("avdd_usb", NULL),
393 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
394 REGULATOR_SUPPLY("vcore_nand", NULL),
395 REGULATOR_SUPPLY("hvdd_sata", NULL),
396 REGULATOR_SUPPLY("vddio_gmi_pmu", NULL),
397 REGULATOR_SUPPLY("pwrdet_nand", NULL),
398 REGULATOR_SUPPLY("avdd_cam1", NULL),
399 REGULATOR_SUPPLY("vdd_af", NULL),
400 REGULATOR_SUPPLY("avdd_cam2", NULL),
401 REGULATOR_SUPPLY("vdd_acc", NULL),
402 REGULATOR_SUPPLY("vdd_phtl", NULL),
403 REGULATOR_SUPPLY("vddio_tp", NULL),
404 REGULATOR_SUPPLY("vdd_led", NULL),
405 REGULATOR_SUPPLY("vddio_cec", NULL),
406 REGULATOR_SUPPLY("vdd_cmps", NULL),
407 REGULATOR_SUPPLY("vdd_temp", NULL),
408 REGULATOR_SUPPLY("vpp_kfuse", NULL),
409 REGULATOR_SUPPLY("vddio_ts", NULL),
410 REGULATOR_SUPPLY("vdd_ir_led", NULL),
411 REGULATOR_SUPPLY("vddio_1wire", NULL),
412 REGULATOR_SUPPLY("avddio_audio", NULL),
413 REGULATOR_SUPPLY("vdd_ec", NULL),
414 REGULATOR_SUPPLY("vcom_pa", NULL),
415 REGULATOR_SUPPLY("vdd_3v3_devices", NULL),
416 REGULATOR_SUPPLY("vdd_3v3_dock", NULL),
417 REGULATOR_SUPPLY("vdd_3v3_edid", NULL),
418 REGULATOR_SUPPLY("vdd_3v3_hdmi_cec", NULL),
419 REGULATOR_SUPPLY("vdd_3v3_gmi", NULL),
420 REGULATOR_SUPPLY("vdd_3v3_spk_amp", NULL),
421 REGULATOR_SUPPLY("vdd_3v3_sensor", NULL),
422 REGULATOR_SUPPLY("vdd_3v3_cam", NULL),
423 REGULATOR_SUPPLY("vdd_3v3_als", NULL),
424 REGULATOR_SUPPLY("debug_cons", NULL),
425};
426
427/* DIS_5V_SWITCH from AP SPI2_SCK X02 */
428static struct regulator_consumer_supply fixed_reg_dis_5v_switch_supply[] = {
429 REGULATOR_SUPPLY("master_5v_switch", NULL),
430};
431
432/* EN_VDD_BL */
433static struct regulator_consumer_supply fixed_reg_en_vdd_bl_supply[] = {
434 REGULATOR_SUPPLY("vdd_backlight", NULL),
435 REGULATOR_SUPPLY("vdd_backlight1", NULL),
436};
437
438/* EN_3V3_MODEM from AP GPIO VI_VSYNCH D06*/
439static struct regulator_consumer_supply fixed_reg_en_3v3_modem_supply[] = {
440 REGULATOR_SUPPLY("vdd_3v3_mini_card", NULL),
441 REGULATOR_SUPPLY("vdd_mini_card", NULL),
442};
443
444/* EN_VDD_PNL1 from AP GPIO VI_D6 L04*/
445static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = {
446 REGULATOR_SUPPLY("vdd_lcd_panel", NULL),
447};
448
449/* CAM1_LDO_EN from AP GPIO KB_ROW6 R06*/
450static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = {
451 REGULATOR_SUPPLY("vdd_2v8_cam1", NULL),
452 REGULATOR_SUPPLY("vdd", "6-0072"),
453};
454
455/* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/
456static struct regulator_consumer_supply fixed_reg_cam2_ldo_en_supply[] = {
457 REGULATOR_SUPPLY("vdd_2v8_cam2", NULL),
458 REGULATOR_SUPPLY("vdd", "7-0072"),
459};
460
461/* CAM3_LDO_EN from AP GPIO KB_ROW8 S00*/
462static struct regulator_consumer_supply fixed_reg_cam3_ldo_en_supply[] = {
463 REGULATOR_SUPPLY("vdd_cam3", NULL),
464};
465
466/* EN_VDD_COM from AP GPIO SDMMC3_DAT5 D00*/
467static struct regulator_consumer_supply fixed_reg_en_vdd_com_supply[] = {
468 REGULATOR_SUPPLY("vdd_com_bd", NULL),
469};
470
471/* EN_VDD_SDMMC1 from AP GPIO VI_HSYNC D07*/
472static struct regulator_consumer_supply fixed_reg_en_vdd_sdmmc1_supply[] = {
473 REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.0"),
474};
475
476/* EN_3V3_EMMC from AP GPIO SDMMC3_DAT4 D01*/
477static struct regulator_consumer_supply fixed_reg_en_3v3_emmc_supply[] = {
478 REGULATOR_SUPPLY("vdd_emmc_core", NULL),
479};
480
481/* EN_3V3_PEX_HVDD from AP GPIO VI_D09 L07*/
482static struct regulator_consumer_supply fixed_reg_en_3v3_pex_hvdd_supply[] = {
483 REGULATOR_SUPPLY("hvdd_pex", NULL),
484};
485
486/* EN_3v3_FUSE from AP GPIO VI_D08 L06*/
487static struct regulator_consumer_supply fixed_reg_en_3v3_fuse_supply[] = {
488 REGULATOR_SUPPLY("vdd_fuse", NULL),
489};
490
491/* EN_1V8_CAM from AP GPIO GPIO_PBB4 PBB04*/
492static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
493 REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
494 REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
495 REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
496 REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
497 REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
498 REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
499};
500
501static struct regulator_consumer_supply fixed_reg_en_vbrtr_supply[] = {
502 REGULATOR_SUPPLY("vdd_vbrtr", NULL),
503};
504
505
506/* EN_USB1_VBUS_OC*/
507static struct regulator_consumer_supply gpio_switch_en_usb1_vbus_oc_supply[] = {
508 REGULATOR_SUPPLY("vdd_vbus_micro_usb", NULL),
509};
510static int gpio_switch_en_usb1_vbus_oc_voltages[] = { 5000};
511
512/*EN_USB3_VBUS_OC*/
513static struct regulator_consumer_supply gpio_switch_en_usb3_vbus_oc_supply[] = {
514 REGULATOR_SUPPLY("vdd_vbus_typea_usb", NULL),
515};
516static int gpio_switch_en_usb3_vbus_oc_voltages[] = { 5000};
517
518/* EN_VDDIO_VID_OC from AP GPIO VI_PCLK T00*/
519static struct regulator_consumer_supply gpio_switch_en_vddio_vid_oc_supply[] = {
520 REGULATOR_SUPPLY("vdd_hdmi_con", NULL),
521};
522static int gpio_switch_en_vddio_vid_oc_voltages[] = { 5000};
523
524static int enable_load_switch_rail(
525 struct gpio_switch_regulator_subdev_data *psubdev_data)
526{
527 int ret;
528
529 if (psubdev_data->pin_group <= 0)
530 return -EINVAL;
531
532 /* Tristate and make pin as input*/
533 ret = tegra_pinmux_set_tristate(psubdev_data->pin_group,
534 TEGRA_TRI_TRISTATE);
535 if (ret < 0)
536 return ret;
537 return gpio_direction_input(psubdev_data->gpio_nr);
538}
539
540static int disable_load_switch_rail(
541 struct gpio_switch_regulator_subdev_data *psubdev_data)
542{
543 int ret;
544
545 if (psubdev_data->pin_group <= 0)
546 return -EINVAL;
547
548 /* Un-tristate and driver low */
549 ret = tegra_pinmux_set_tristate(psubdev_data->pin_group,
550 TEGRA_TRI_NORMAL);
551 if (ret < 0)
552 return ret;
553 return gpio_direction_output(psubdev_data->gpio_nr, 0);
554}
555
556/* Macro for defining gpio switch regulator sub device data */
557#define GREG_INIT(_id, _var, _name, _input_supply, _always_on, _boot_on, \
558 _gpio_nr, _active_low, _init_state, _pg, _enable, _disable) \
559 static struct gpio_switch_regulator_subdev_data gpio_pdata_##_var = \
560 { \
561 .regulator_name = "gpio-switch-"#_name, \
562 .input_supply = _input_supply, \
563 .id = _id, \
564 .gpio_nr = _gpio_nr, \
565 .pin_group = _pg, \
566 .active_low = _active_low, \
567 .init_state = _init_state, \
568 .voltages = gpio_switch_##_name##_voltages, \
569 .n_voltages = ARRAY_SIZE(gpio_switch_##_name##_voltages), \
570 .num_consumer_supplies = \
571 ARRAY_SIZE(gpio_switch_##_name##_supply), \
572 .consumer_supplies = gpio_switch_##_name##_supply, \
573 .constraints = { \
574 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
575 REGULATOR_MODE_STANDBY), \
576 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
577 REGULATOR_CHANGE_STATUS | \
578 REGULATOR_CHANGE_VOLTAGE), \
579 .always_on = _always_on, \
580 .boot_on = _boot_on, \
581 }, \
582 .enable_rail = _enable, \
583 .disable_rail = _disable, \
584 }; \
585 static struct gpio_switch_regulator_subdev_data \
586 *gpio_pdata_##_var##_list[] = { \
587 &gpio_pdata_##_var, \
588 }; \
589 static struct gpio_switch_regulator_platform_data gs_##_var##_pdata = \
590 { \
591 .num_subdevs = 1, \
592 .subdevs = gpio_pdata_##_var##_list, \
593 }; \
594 static struct platform_device gswitch_reg_##_var##_dev = { \
595 .name = "gpio-switch-regulator", \
596 .id = _id, \
597 .dev = { \
598 .platform_data = &gs_##_var##_pdata, \
599 }, \
600 }
601
602/* Macro for defining fixed regulator sub device data */
603#define FIXED_SUPPLY(_name) "fixed_reg_"#_name
604#define FIXED_REG(_id, _var, _name, _in_supply, _always_on, _boot_on, \
605 _gpio_nr, _active_high, _boot_state, _millivolts) \
606 static struct regulator_init_data ri_data_##_var = \
607 { \
608 .supply_regulator = _in_supply, \
609 .num_consumer_supplies = \
610 ARRAY_SIZE(fixed_reg_##_name##_supply), \
611 .consumer_supplies = fixed_reg_##_name##_supply, \
612 .constraints = { \
613 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
614 REGULATOR_MODE_STANDBY), \
615 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
616 REGULATOR_CHANGE_STATUS | \
617 REGULATOR_CHANGE_VOLTAGE), \
618 .always_on = _always_on, \
619 .boot_on = _boot_on, \
620 }, \
621 }; \
622 static struct fixed_voltage_config fixed_reg_##_var##_pdata = \
623 { \
624 .supply_name = FIXED_SUPPLY(_name), \
625 .microvolts = _millivolts * 1000, \
626 .gpio = _gpio_nr, \
627 .enable_high = _active_high, \
628 .enabled_at_boot = _boot_state, \
629 .init_data = &ri_data_##_var, \
630 }; \
631 static struct platform_device fixed_reg_##_var##_dev = { \
632 .name = "reg-fixed-voltage", \
633 .id = _id, \
634 .dev = { \
635 .platform_data = &fixed_reg_##_var##_pdata, \
636 }, \
637 }
638
639/* common to most of boards*/
640FIXED_REG(0, en_5v_cp, en_5v_cp, NULL, 1, 0, TPS6591X_GPIO_0, true, 1, 5000);
641FIXED_REG(1, en_5v0, en_5v0, NULL, 0, 0, TPS6591X_GPIO_4, true, 0, 5000);
642FIXED_REG(2, en_ddr, en_ddr, NULL, 0, 0, TPS6591X_GPIO_3, true, 1, 1500);
643FIXED_REG(3, en_3v3_sys, en_3v3_sys, NULL, 0, 0, TPS6591X_GPIO_1, true, 0, 3300);
644FIXED_REG(4, en_vdd_bl, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PK3, true, 1, 5000);
645FIXED_REG(5, en_3v3_modem, en_3v3_modem, NULL, 1, 0, TEGRA_GPIO_PD6, true, 1, 3300);
646FIXED_REG(6, en_vdd_pnl1, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL4, true, 1, 3300);
647FIXED_REG(7, cam3_ldo_en, cam3_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PS0, true, 0, 3300);
648FIXED_REG(8, en_vdd_com, en_vdd_com, FIXED_SUPPLY(en_3v3_sys), 1, 0, TEGRA_GPIO_PD0, true, 1, 3300);
649FIXED_REG(9, en_3v3_fuse, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL6, true, 0, 3300);
650FIXED_REG(10, en_3v3_emmc, en_3v3_emmc, FIXED_SUPPLY(en_3v3_sys), 1, 0, TEGRA_GPIO_PD1, true, 1, 3300);
651FIXED_REG(11, en_vdd_sdmmc1, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PD7, true, 1, 3300);
652FIXED_REG(12, en_3v3_pex_hvdd, en_3v3_pex_hvdd, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL7, true, 0, 3300);
653FIXED_REG(13, en_1v8_cam, en_1v8_cam, ricoh583_rails(DC2), 0, 0, TEGRA_GPIO_PBB4, true, 0, 1800);
654
655/* E1198/E1291 specific*/
656FIXED_REG(18, cam1_ldo_en, cam1_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PR6, true, 0, 2800);
657FIXED_REG(19, cam2_ldo_en, cam2_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PR7, true, 0, 2800);
658FIXED_REG(22, en_vbrtr, en_vbrtr, FIXED_SUPPLY(en_3v3_sys), 0, 0, PMU_TCA6416_GPIO_PORT12,true, 0, 3300);
659
660/*Specific to pm269*/
661FIXED_REG(4, en_vdd_bl_pm269, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PH3, true, 1, 5000);
662FIXED_REG(6, en_vdd_pnl1_pm269, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PW1, true, 1, 3300);
663FIXED_REG(9, en_3v3_fuse_pm269, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PC1, true, 0, 3300);
664FIXED_REG(11, en_vdd_sdmmc1_pm269, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PP1, true, 1, 3300);
665FIXED_REG(12, en_3v3_pex_hvdd_pm269, en_3v3_pex_hvdd, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PC6, true, 0, 3300);
666
667/* Specific to E1187/E1186/E1256 */
668FIXED_REG(14, dis_5v_switch_e118x, dis_5v_switch, FIXED_SUPPLY(en_5v0), 0, 0, TEGRA_GPIO_PX2, false, 0, 5000);
669
670/*** Open collector load switches ************/
671/*Specific to pm269*/
672GREG_INIT(17, en_vddio_vid_oc_pm269, en_vddio_vid_oc, "master_5v_switch",
673 0, 0, TEGRA_GPIO_PP2, false, 0, TEGRA_PINGROUP_DAP3_DOUT,
674 enable_load_switch_rail, disable_load_switch_rail);
675
676/* Specific to E1187/E1186/E1256 */
677GREG_INIT(15, en_usb1_vbus_oc_e118x, en_usb1_vbus_oc, "master_5v_switch",
678 0, 0, TEGRA_GPIO_PI4, false, 0, TEGRA_PINGROUP_GMI_RST_N,
679 enable_load_switch_rail, disable_load_switch_rail);
680GREG_INIT(16, en_usb3_vbus_oc_e118x, en_usb3_vbus_oc, "master_5v_switch",
681 0, 0, TEGRA_GPIO_PH7, false, 0, TEGRA_PINGROUP_GMI_AD15,
682 enable_load_switch_rail, disable_load_switch_rail);
683GREG_INIT(17, en_vddio_vid_oc_e118x, en_vddio_vid_oc, "master_5v_switch",
684 0, 0, TEGRA_GPIO_PT0, false, 0, TEGRA_PINGROUP_VI_PCLK,
685 enable_load_switch_rail, disable_load_switch_rail);
686
687/*
688 * Creating the fixed/gpio-switch regulator device tables for different boards
689 */
690#define ADD_FIXED_REG(_name) (&fixed_reg_##_name##_dev)
691#define ADD_GPIO_REG(_name) (&gswitch_reg_##_name##_dev)
692
693#define COMMON_FIXED_REG \
694 ADD_FIXED_REG(en_5v_cp), \
695 ADD_FIXED_REG(en_5v0), \
696 ADD_FIXED_REG(en_ddr), \
697 ADD_FIXED_REG(en_3v3_sys), \
698 ADD_FIXED_REG(en_3v3_modem), \
699 ADD_FIXED_REG(en_vdd_pnl1), \
700 ADD_FIXED_REG(cam1_ldo_en), \
701 ADD_FIXED_REG(cam2_ldo_en), \
702 ADD_FIXED_REG(cam3_ldo_en), \
703 ADD_FIXED_REG(en_vdd_com), \
704 ADD_FIXED_REG(en_3v3_fuse), \
705 ADD_FIXED_REG(en_3v3_emmc), \
706 ADD_FIXED_REG(en_vdd_sdmmc1), \
707 ADD_FIXED_REG(en_3v3_pex_hvdd), \
708 ADD_FIXED_REG(en_1v8_cam),
709
710#define PM269_FIXED_REG \
711 ADD_FIXED_REG(en_5v_cp), \
712 ADD_FIXED_REG(en_5v0), \
713 ADD_FIXED_REG(en_ddr), \
714 ADD_FIXED_REG(en_vdd_bl_pm269), \
715 ADD_FIXED_REG(en_3v3_sys), \
716 ADD_FIXED_REG(en_3v3_modem), \
717 ADD_FIXED_REG(en_vdd_pnl1_pm269), \
718 ADD_FIXED_REG(cam1_ldo_en), \
719 ADD_FIXED_REG(cam2_ldo_en), \
720 ADD_FIXED_REG(cam3_ldo_en), \
721 ADD_FIXED_REG(en_vdd_com), \
722 ADD_FIXED_REG(en_3v3_fuse_pm269), \
723 ADD_FIXED_REG(en_3v3_emmc), \
724 ADD_FIXED_REG(en_vdd_sdmmc1_pm269), \
725 ADD_FIXED_REG(en_3v3_pex_hvdd_pm269), \
726 ADD_FIXED_REG(en_1v8_cam), \
727 ADD_FIXED_REG(dis_5v_switch_e118x), \
728 ADD_GPIO_REG(en_usb1_vbus_oc_e118x), \
729 ADD_GPIO_REG(en_usb3_vbus_oc_e118x), \
730 ADD_GPIO_REG(en_vddio_vid_oc_pm269),
731
732#define E118x_FIXED_REG \
733 ADD_FIXED_REG(en_vdd_bl), \
734 ADD_FIXED_REG(dis_5v_switch_e118x), \
735 ADD_FIXED_REG(en_vbrtr), \
736 ADD_GPIO_REG(en_usb1_vbus_oc_e118x), \
737 ADD_GPIO_REG(en_usb3_vbus_oc_e118x), \
738 ADD_GPIO_REG(en_vddio_vid_oc_e118x), \
739
740/* Gpio switch regulator platform data for E1186/E1187/E1256*/
741static struct platform_device *fixed_reg_devs_e118x[] = {
742 COMMON_FIXED_REG
743 E118x_FIXED_REG
744};
745
746/* Gpio switch regulator platform data for PM269*/
747static struct platform_device *fixed_reg_devs_pm269[] = {
748 PM269_FIXED_REG
749};
750
751int __init cardhu_pm299_gpio_switch_regulator_init(void)
752{
753 int i;
754 struct board_info board_info;
755 struct platform_device **fixed_reg_devs;
756 int nfixreg_devs;
757
758 tegra_get_board_info(&board_info);
759
760 switch (board_info.board_id) {
761 case BOARD_PM269:
762 case BOARD_PM305:
763 case BOARD_PM311:
764 case BOARD_E1257:
765 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm269);
766 fixed_reg_devs = fixed_reg_devs_pm269;
767 break;
768
769 default:
770 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e118x);
771 fixed_reg_devs = fixed_reg_devs_e118x;
772 break;
773 }
774
775 for (i = 0; i < nfixreg_devs; ++i) {
776 int gpio_nr;
777 if (!strncmp(fixed_reg_devs[i]->name, "gpio", 4)) {
778 struct gpio_switch_regulator_platform_data *gs_pdata =
779 fixed_reg_devs[i]->dev.platform_data;
780 gpio_nr = gs_pdata->subdevs[0]->gpio_nr;
781 } else {
782 struct fixed_voltage_config *fixed_reg_pdata =
783 fixed_reg_devs[i]->dev.platform_data;
784 gpio_nr = fixed_reg_pdata->gpio;
785 }
786
787 if (gpio_nr < TEGRA_NR_GPIOS)
788 tegra_gpio_enable(gpio_nr);
789 }
790 return platform_add_devices(fixed_reg_devs, nfixreg_devs);
791}
diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c
new file mode 100644
index 00000000000..a39c43a590e
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-power.c
@@ -0,0 +1,1321 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-power.c
3 *
4 * Copyright (C) 2011 NVIDIA, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20#include <linux/i2c.h>
21#include <linux/pda_power.h>
22#include <linux/platform_device.h>
23#include <linux/resource.h>
24#include <linux/regulator/machine.h>
25#include <linux/mfd/tps6591x.h>
26#include <linux/mfd/max77663-core.h>
27#include <linux/gpio.h>
28#include <linux/io.h>
29#include <linux/regulator/gpio-switch-regulator.h>
30#include <linux/regulator/fixed.h>
31#include <linux/regulator/tps6591x-regulator.h>
32#include <linux/regulator/tps62360.h>
33#include <linux/power/gpio-charger.h>
34
35#include <asm/mach-types.h>
36
37#include <mach/iomap.h>
38#include <mach/irqs.h>
39#include <mach/pinmux.h>
40#include <mach/edp.h>
41
42#include "gpio-names.h"
43#include "board.h"
44#include "board-cardhu.h"
45#include "pm.h"
46#include "wakeups-t3.h"
47#include "tegra3_tsensor.h"
48
49#define PMC_CTRL 0x0
50#define PMC_CTRL_INTR_LOW (1 << 17)
51
52static struct regulator_consumer_supply tps6591x_vdd1_supply_skubit0_0[] = {
53 REGULATOR_SUPPLY("vdd_core", NULL),
54 REGULATOR_SUPPLY("en_vddio_ddr_1v2", NULL),
55};
56
57static struct regulator_consumer_supply tps6591x_vdd1_supply_skubit0_1[] = {
58 REGULATOR_SUPPLY("en_vddio_ddr_1v2", NULL),
59};
60
61static struct regulator_consumer_supply tps6591x_vdd2_supply_0[] = {
62 REGULATOR_SUPPLY("vdd_gen1v5", NULL),
63 REGULATOR_SUPPLY("vcore_lcd", NULL),
64 REGULATOR_SUPPLY("track_ldo1", NULL),
65 REGULATOR_SUPPLY("external_ldo_1v2", NULL),
66 REGULATOR_SUPPLY("vcore_cam1", NULL),
67 REGULATOR_SUPPLY("vcore_cam2", NULL),
68};
69
70static struct regulator_consumer_supply tps6591x_vddctrl_supply_0[] = {
71 REGULATOR_SUPPLY("vdd_cpu_pmu", NULL),
72 REGULATOR_SUPPLY("vdd_cpu", NULL),
73 REGULATOR_SUPPLY("vdd_sys", NULL),
74};
75
76static struct regulator_consumer_supply tps6591x_vio_supply_0[] = {
77 REGULATOR_SUPPLY("vdd_gen1v8", NULL),
78 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
79 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
80 REGULATOR_SUPPLY("avdd_osc", NULL),
81 REGULATOR_SUPPLY("vddio_sys", NULL),
82 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.3"),
83 REGULATOR_SUPPLY("pwrdet_sdmmc4", NULL),
84 REGULATOR_SUPPLY("vdd1v8_satelite", NULL),
85 REGULATOR_SUPPLY("vddio_uart", NULL),
86 REGULATOR_SUPPLY("pwrdet_uart", NULL),
87 REGULATOR_SUPPLY("vddio_audio", NULL),
88 REGULATOR_SUPPLY("pwrdet_audio", NULL),
89 REGULATOR_SUPPLY("vddio_bb", NULL),
90 REGULATOR_SUPPLY("pwrdet_bb", NULL),
91 REGULATOR_SUPPLY("vddio_lcd_pmu", NULL),
92 REGULATOR_SUPPLY("pwrdet_lcd", NULL),
93 REGULATOR_SUPPLY("vddio_cam", NULL),
94 REGULATOR_SUPPLY("pwrdet_cam", NULL),
95 REGULATOR_SUPPLY("vddio_vi", NULL),
96 REGULATOR_SUPPLY("pwrdet_vi", NULL),
97 REGULATOR_SUPPLY("ldo6", NULL),
98 REGULATOR_SUPPLY("ldo7", NULL),
99 REGULATOR_SUPPLY("ldo8", NULL),
100 REGULATOR_SUPPLY("vcore_audio", NULL),
101 REGULATOR_SUPPLY("avcore_audio", NULL),
102 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.2"),
103 REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
104 REGULATOR_SUPPLY("vcore1_lpddr2", NULL),
105 REGULATOR_SUPPLY("vcom_1v8", NULL),
106 REGULATOR_SUPPLY("pmuio_1v8", NULL),
107 REGULATOR_SUPPLY("avdd_ic_usb", NULL),
108};
109
110static struct regulator_consumer_supply tps6591x_ldo1_supply_0[] = {
111 REGULATOR_SUPPLY("avdd_pexb", NULL),
112 REGULATOR_SUPPLY("vdd_pexb", NULL),
113 REGULATOR_SUPPLY("avdd_pex_pll", NULL),
114 REGULATOR_SUPPLY("avdd_pexa", NULL),
115 REGULATOR_SUPPLY("vdd_pexa", NULL),
116};
117
118static struct regulator_consumer_supply tps6591x_ldo2_supply_0[] = {
119 REGULATOR_SUPPLY("avdd_sata", NULL),
120 REGULATOR_SUPPLY("vdd_sata", NULL),
121 REGULATOR_SUPPLY("avdd_sata_pll", NULL),
122 REGULATOR_SUPPLY("avdd_plle", NULL),
123};
124
125static struct regulator_consumer_supply tps6591x_ldo3_supply_e118x[] = {
126 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.0"),
127 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
128};
129
130static struct regulator_consumer_supply tps6591x_ldo3_supply_e1198[] = {
131 REGULATOR_SUPPLY("unused_rail_ldo3", NULL),
132};
133
134static struct regulator_consumer_supply tps6591x_ldo4_supply_0[] = {
135 REGULATOR_SUPPLY("vdd_rtc", NULL),
136};
137
138static struct regulator_consumer_supply tps6591x_ldo5_supply_e118x[] = {
139 REGULATOR_SUPPLY("avdd_vdac", NULL),
140};
141
142static struct regulator_consumer_supply tps6591x_ldo5_supply_e1198[] = {
143 REGULATOR_SUPPLY("avdd_vdac", NULL),
144 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.0"),
145 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
146};
147
148static struct regulator_consumer_supply tps6591x_ldo6_supply_0[] = {
149 REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
150 REGULATOR_SUPPLY("pwrdet_mipi", NULL),
151};
152static struct regulator_consumer_supply tps6591x_ldo7_supply_0[] = {
153 REGULATOR_SUPPLY("avdd_plla_p_c_s", NULL),
154 REGULATOR_SUPPLY("avdd_pllm", NULL),
155 REGULATOR_SUPPLY("avdd_pllu_d", NULL),
156 REGULATOR_SUPPLY("avdd_pllu_d2", NULL),
157 REGULATOR_SUPPLY("avdd_pllx", NULL),
158};
159
160static struct regulator_consumer_supply tps6591x_ldo8_supply_0[] = {
161 REGULATOR_SUPPLY("vdd_ddr_hs", NULL),
162};
163
164#define TPS_PDATA_INIT(_name, _sname, _minmv, _maxmv, _supply_reg, _always_on, \
165 _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, _ectrl, _flags) \
166 static struct tps6591x_regulator_platform_data pdata_##_name##_##_sname = \
167 { \
168 .regulator = { \
169 .constraints = { \
170 .min_uV = (_minmv)*1000, \
171 .max_uV = (_maxmv)*1000, \
172 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
173 REGULATOR_MODE_STANDBY), \
174 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
175 REGULATOR_CHANGE_STATUS | \
176 REGULATOR_CHANGE_VOLTAGE), \
177 .always_on = _always_on, \
178 .boot_on = _boot_on, \
179 .apply_uV = _apply_uv, \
180 }, \
181 .num_consumer_supplies = \
182 ARRAY_SIZE(tps6591x_##_name##_supply_##_sname), \
183 .consumer_supplies = tps6591x_##_name##_supply_##_sname, \
184 .supply_regulator = _supply_reg, \
185 }, \
186 .init_uV = _init_uV * 1000, \
187 .init_enable = _init_enable, \
188 .init_apply = _init_apply, \
189 .ectrl = _ectrl, \
190 .flags = _flags, \
191 }
192
193TPS_PDATA_INIT(vdd1, skubit0_0, 600, 1500, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_SLEEP_OFF, 0);
194TPS_PDATA_INIT(vdd1, skubit0_1, 600, 1500, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_SLEEP_OFF, 0);
195TPS_PDATA_INIT(vdd2, 0, 600, 1500, 0, 1, 1, 0, -1, 0, 0, 0, 0);
196TPS_PDATA_INIT(vddctrl, 0, 600, 1400, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_EN1, 0);
197TPS_PDATA_INIT(vio, 0, 1500, 3300, 0, 1, 1, 0, -1, 0, 0, 0, 0);
198
199TPS_PDATA_INIT(ldo1, 0, 1000, 3300, tps6591x_rails(VDD_2), 0, 0, 0, -1, 0, 1, 0, 0);
200TPS_PDATA_INIT(ldo2, 0, 1050, 1050, tps6591x_rails(VDD_2), 0, 0, 1, -1, 0, 1, 0, 0);
201
202TPS_PDATA_INIT(ldo3, e118x, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0);
203TPS_PDATA_INIT(ldo3, e1198, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0);
204TPS_PDATA_INIT(ldo4, 0, 1000, 3300, 0, 1, 0, 0, -1, 0, 0, 0, 0);
205TPS_PDATA_INIT(ldo5, e118x, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0);
206TPS_PDATA_INIT(ldo5, e1198, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0);
207
208TPS_PDATA_INIT(ldo6, 0, 1200, 1200, tps6591x_rails(VIO), 0, 0, 1, -1, 0, 0, 0, 0);
209TPS_PDATA_INIT(ldo7, 0, 1200, 1200, tps6591x_rails(VIO), 1, 1, 1, -1, 0, 0, EXT_CTRL_SLEEP_OFF, LDO_LOW_POWER_ON_SUSPEND);
210TPS_PDATA_INIT(ldo8, 0, 1000, 3300, tps6591x_rails(VIO), 1, 0, 0, -1, 0, 0, EXT_CTRL_SLEEP_OFF, LDO_LOW_POWER_ON_SUSPEND);
211
212#if defined(CONFIG_RTC_DRV_TPS6591x)
213static struct tps6591x_rtc_platform_data rtc_data = {
214 .irq = TEGRA_NR_IRQS + TPS6591X_INT_RTC_ALARM,
215 .time = {
216 .tm_year = 2000,
217 .tm_mon = 0,
218 .tm_mday = 1,
219 .tm_hour = 0,
220 .tm_min = 0,
221 .tm_sec = 0,
222 },
223};
224
225#define TPS_RTC_REG() \
226 { \
227 .id = 0, \
228 .name = "rtc_tps6591x", \
229 .platform_data = &rtc_data, \
230 }
231#endif
232
233#define TPS_REG(_id, _name, _sname) \
234 { \
235 .id = TPS6591X_ID_##_id, \
236 .name = "tps6591x-regulator", \
237 .platform_data = &pdata_##_name##_##_sname, \
238 }
239
240#define TPS6591X_DEV_COMMON_E118X \
241 TPS_REG(VDD_2, vdd2, 0), \
242 TPS_REG(VDDCTRL, vddctrl, 0), \
243 TPS_REG(LDO_1, ldo1, 0), \
244 TPS_REG(LDO_2, ldo2, 0), \
245 TPS_REG(LDO_3, ldo3, e118x), \
246 TPS_REG(LDO_4, ldo4, 0), \
247 TPS_REG(LDO_5, ldo5, e118x), \
248 TPS_REG(LDO_6, ldo6, 0), \
249 TPS_REG(LDO_7, ldo7, 0), \
250 TPS_REG(LDO_8, ldo8, 0)
251
252static struct tps6591x_subdev_info tps_devs_e118x_skubit0_0[] = {
253 TPS_REG(VIO, vio, 0),
254 TPS_REG(VDD_1, vdd1, skubit0_0),
255 TPS6591X_DEV_COMMON_E118X,
256#if defined(CONFIG_RTC_DRV_TPS6591x)
257 TPS_RTC_REG(),
258#endif
259};
260
261static struct tps6591x_subdev_info tps_devs_e118x_skubit0_1[] = {
262 TPS_REG(VIO, vio, 0),
263 TPS_REG(VDD_1, vdd1, skubit0_1),
264 TPS6591X_DEV_COMMON_E118X,
265#if defined(CONFIG_RTC_DRV_TPS6591x)
266 TPS_RTC_REG(),
267#endif
268};
269
270#define TPS6591X_DEV_COMMON_CARDHU \
271 TPS_REG(VDD_2, vdd2, 0), \
272 TPS_REG(VDDCTRL, vddctrl, 0), \
273 TPS_REG(LDO_1, ldo1, 0), \
274 TPS_REG(LDO_2, ldo2, 0), \
275 TPS_REG(LDO_3, ldo3, e1198), \
276 TPS_REG(LDO_4, ldo4, 0), \
277 TPS_REG(LDO_5, ldo5, e1198), \
278 TPS_REG(LDO_6, ldo6, 0), \
279 TPS_REG(LDO_7, ldo7, 0), \
280 TPS_REG(LDO_8, ldo8, 0)
281
282static struct tps6591x_subdev_info tps_devs_e1198_skubit0_0[] = {
283 TPS_REG(VIO, vio, 0),
284 TPS_REG(VDD_1, vdd1, skubit0_0),
285 TPS6591X_DEV_COMMON_CARDHU,
286#if defined(CONFIG_RTC_DRV_TPS6591x)
287 TPS_RTC_REG(),
288#endif
289};
290
291static struct tps6591x_subdev_info tps_devs_e1198_skubit0_1[] = {
292 TPS_REG(VIO, vio, 0),
293 TPS_REG(VDD_1, vdd1, skubit0_1),
294 TPS6591X_DEV_COMMON_CARDHU,
295#if defined(CONFIG_RTC_DRV_TPS6591x)
296 TPS_RTC_REG(),
297#endif
298};
299
300#define TPS_GPIO_INIT_PDATA(gpio_nr, _init_apply, _sleep_en, _pulldn_en, _output_en, _output_val) \
301 [gpio_nr] = { \
302 .sleep_en = _sleep_en, \
303 .pulldn_en = _pulldn_en, \
304 .output_mode_en = _output_en, \
305 .output_val = _output_val, \
306 .init_apply = _init_apply, \
307 }
308static struct tps6591x_gpio_init_data tps_gpio_pdata_e1291_a04[] = {
309 TPS_GPIO_INIT_PDATA(0, 0, 0, 0, 0, 0),
310 TPS_GPIO_INIT_PDATA(1, 0, 0, 0, 0, 0),
311 TPS_GPIO_INIT_PDATA(2, 1, 1, 0, 1, 1),
312 TPS_GPIO_INIT_PDATA(3, 0, 0, 0, 0, 0),
313 TPS_GPIO_INIT_PDATA(4, 0, 0, 0, 0, 0),
314 TPS_GPIO_INIT_PDATA(5, 0, 0, 0, 0, 0),
315 TPS_GPIO_INIT_PDATA(6, 0, 0, 0, 0, 0),
316 TPS_GPIO_INIT_PDATA(7, 0, 0, 0, 0, 0),
317 TPS_GPIO_INIT_PDATA(8, 0, 0, 0, 0, 0),
318};
319
320static struct tps6591x_sleep_keepon_data tps_slp_keepon = {
321 .clkout32k_keepon = 1,
322};
323
324static struct tps6591x_platform_data tps_platform = {
325 .irq_base = TPS6591X_IRQ_BASE,
326 .gpio_base = TPS6591X_GPIO_BASE,
327 .dev_slp_en = true,
328 .slp_keepon = &tps_slp_keepon,
329 .use_power_off = true,
330};
331
332static struct i2c_board_info __initdata cardhu_regulators[] = {
333 {
334 I2C_BOARD_INFO("tps6591x", 0x2D),
335 .irq = INT_EXTERNAL_PMU,
336 .platform_data = &tps_platform,
337 },
338};
339
340/* TPS62361B DC-DC converter */
341static struct regulator_consumer_supply tps62361_dcdc_supply[] = {
342 REGULATOR_SUPPLY("vdd_core", NULL),
343};
344
345static struct tps62360_regulator_platform_data tps62361_pdata = {
346 .reg_init_data = { \
347 .constraints = { \
348 .min_uV = 500000, \
349 .max_uV = 1770000, \
350 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
351 REGULATOR_MODE_STANDBY), \
352 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
353 REGULATOR_CHANGE_STATUS | \
354 REGULATOR_CHANGE_VOLTAGE), \
355 .always_on = 1, \
356 .boot_on = 1, \
357 .apply_uV = 0, \
358 }, \
359 .num_consumer_supplies = ARRAY_SIZE(tps62361_dcdc_supply), \
360 .consumer_supplies = tps62361_dcdc_supply, \
361 }, \
362 .en_discharge = true, \
363 .vsel0_gpio = -1, \
364 .vsel1_gpio = -1, \
365 .vsel0_def_state = 1, \
366 .vsel1_def_state = 1, \
367};
368
369static struct i2c_board_info __initdata tps62361_boardinfo[] = {
370 {
371 I2C_BOARD_INFO("tps62361", 0x60),
372 .platform_data = &tps62361_pdata,
373 },
374};
375
376int __init cardhu_regulator_init(void)
377{
378 struct board_info board_info;
379 struct board_info pmu_board_info;
380 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
381 u32 pmc_ctrl;
382 bool ext_core_regulator = false;
383
384 /* configure the power management controller to trigger PMU
385 * interrupts when low */
386
387 pmc_ctrl = readl(pmc + PMC_CTRL);
388 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
389
390 tegra_get_board_info(&board_info);
391 tegra_get_pmu_board_info(&pmu_board_info);
392
393 if (pmu_board_info.board_id == BOARD_PMU_PM298)
394 return cardhu_pm298_regulator_init();
395
396 if (pmu_board_info.board_id == BOARD_PMU_PM299)
397 return cardhu_pm299_regulator_init();
398
399 /* The regulator details have complete constraints */
400 regulator_has_full_constraints();
401
402 /* PMU-E1208, the ldo2 should be set to 1200mV */
403 if (pmu_board_info.board_id == BOARD_E1208) {
404 pdata_ldo2_0.regulator.constraints.min_uV = 1200000;
405 pdata_ldo2_0.regulator.constraints.max_uV = 1200000;
406 }
407
408 /*
409 * E1198 will have different core regulator decoding.
410 * A01/A02: Based on sku bit 0.
411 * A03: Based on bit 2 and bit 0
412 * 2,0: 00 no core regulator,
413 * 01:TPS62365
414 * 10:TPS62366
415 * 11:TPS623850
416 */
417 if (board_info.board_id == BOARD_E1198) {
418 int vsels;
419 switch(board_info.fab) {
420 case BOARD_FAB_A00:
421 case BOARD_FAB_A01:
422 case BOARD_FAB_A02:
423 if (board_info.sku & SKU_DCDC_TPS62361_SUPPORT)
424 ext_core_regulator = true;
425 break;
426
427 case BOARD_FAB_A03:
428 vsels = ((board_info.sku >> 1) & 0x2) | (board_info.sku & 1);
429 switch(vsels) {
430 case 1:
431 ext_core_regulator = true;
432 tps62361_pdata.vsel0_def_state = 1;
433 tps62361_pdata.vsel1_def_state = 1;
434 break;
435 case 2:
436 ext_core_regulator = true;
437 tps62361_pdata.vsel0_def_state = 0;
438 tps62361_pdata.vsel1_def_state = 0;
439 break;
440 case 3:
441 ext_core_regulator = true;
442 tps62361_pdata.vsel0_def_state = 1;
443 tps62361_pdata.vsel1_def_state = 0;
444 break;
445 }
446 break;
447 }
448
449 pr_info("BoardId:SKU:Fab 0x%04x:0x%04x:0x%02x\n",
450 board_info.board_id, board_info.sku , board_info.fab);
451 pr_info("Core regulator %s\n",
452 (ext_core_regulator)? "true": "false");
453 pr_info("VSEL 1:0 %d%d\n",
454 tps62361_pdata.vsel1_def_state,
455 tps62361_pdata.vsel0_def_state);
456 }
457
458 if ((board_info.board_id == BOARD_E1291) &&
459 (board_info.sku & SKU_DCDC_TPS62361_SUPPORT))
460 ext_core_regulator = true;
461
462 if ((board_info.board_id == BOARD_E1198) ||
463 (board_info.board_id == BOARD_E1291)) {
464 if (ext_core_regulator) {
465 tps_platform.num_subdevs =
466 ARRAY_SIZE(tps_devs_e1198_skubit0_1);
467 tps_platform.subdevs = tps_devs_e1198_skubit0_1;
468 } else {
469 tps_platform.num_subdevs =
470 ARRAY_SIZE(tps_devs_e1198_skubit0_0);
471 tps_platform.subdevs = tps_devs_e1198_skubit0_0;
472 }
473 } else {
474 if (board_info.board_id == BOARD_PM269)
475 pdata_ldo3_e118x.slew_rate_uV_per_us = 250;
476
477 if (pmu_board_info.sku & SKU_DCDC_TPS62361_SUPPORT) {
478 tps_platform.num_subdevs = ARRAY_SIZE(tps_devs_e118x_skubit0_1);
479 tps_platform.subdevs = tps_devs_e118x_skubit0_1;
480 ext_core_regulator = true;
481 } else {
482 tps_platform.num_subdevs = ARRAY_SIZE(tps_devs_e118x_skubit0_0);
483 tps_platform.subdevs = tps_devs_e118x_skubit0_0;
484 }
485 }
486
487 /* E1291-A04/A05: Enable DEV_SLP and enable sleep on GPIO2 */
488 if ((board_info.board_id == BOARD_E1291) &&
489 ((board_info.fab == BOARD_FAB_A04) ||
490 (board_info.fab == BOARD_FAB_A05))) {
491 tps_platform.dev_slp_en = true;
492 tps_platform.gpio_init_data = tps_gpio_pdata_e1291_a04;
493 tps_platform.num_gpioinit_data =
494 ARRAY_SIZE(tps_gpio_pdata_e1291_a04);
495 }
496
497 i2c_register_board_info(4, cardhu_regulators, 1);
498
499 /* Register the external core regulator if it is require */
500 if (ext_core_regulator) {
501 pr_info("Registering the core regulator\n");
502 i2c_register_board_info(4, tps62361_boardinfo, 1);
503 }
504 return 0;
505}
506
507
508/**************** GPIO based fixed regulator *****************/
509/* EN_5V_CP from PMU GP0 */
510static struct regulator_consumer_supply fixed_reg_en_5v_cp_supply[] = {
511 REGULATOR_SUPPLY("vdd_5v0_sby", NULL),
512 REGULATOR_SUPPLY("vdd_hall", NULL),
513 REGULATOR_SUPPLY("vterm_ddr", NULL),
514 REGULATOR_SUPPLY("v2ref_ddr", NULL),
515};
516
517/* EN_5V0 From PMU GP2 */
518static struct regulator_consumer_supply fixed_reg_en_5v0_supply[] = {
519 REGULATOR_SUPPLY("vdd_5v0_sys", NULL),
520};
521
522/* EN_DDR From PMU GP6 */
523static struct regulator_consumer_supply fixed_reg_en_ddr_supply[] = {
524 REGULATOR_SUPPLY("mem_vddio_ddr", NULL),
525 REGULATOR_SUPPLY("t30_vddio_ddr", NULL),
526};
527
528/* EN_3V3_SYS From PMU GP7 */
529static struct regulator_consumer_supply fixed_reg_en_3v3_sys_supply[] = {
530 REGULATOR_SUPPLY("vdd_lvds", NULL),
531 REGULATOR_SUPPLY("vdd_pnl", NULL),
532 REGULATOR_SUPPLY("vcom_3v3", NULL),
533 REGULATOR_SUPPLY("vdd_3v3", NULL),
534 REGULATOR_SUPPLY("vcore_mmc", NULL),
535 REGULATOR_SUPPLY("vddio_pex_ctl", NULL),
536 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
537 REGULATOR_SUPPLY("hvdd_pex_pmu", NULL),
538 REGULATOR_SUPPLY("avdd_hdmi", NULL),
539 REGULATOR_SUPPLY("vpp_fuse", NULL),
540// REGULATOR_SUPPLY("avdd_usb", NULL),
541 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
542 REGULATOR_SUPPLY("vcore_nand", NULL),
543 REGULATOR_SUPPLY("hvdd_sata", NULL),
544 REGULATOR_SUPPLY("vddio_gmi_pmu", NULL),
545 REGULATOR_SUPPLY("pwrdet_nand", NULL),
546 REGULATOR_SUPPLY("avdd_cam1", NULL),
547 REGULATOR_SUPPLY("vdd_af", NULL),
548 REGULATOR_SUPPLY("avdd_cam2", NULL),
549 REGULATOR_SUPPLY("vdd_acc", NULL),
550 REGULATOR_SUPPLY("vdd_phtl", NULL),
551 REGULATOR_SUPPLY("vddio_tp", NULL),
552 REGULATOR_SUPPLY("vdd_led", NULL),
553 REGULATOR_SUPPLY("vddio_cec", NULL),
554 REGULATOR_SUPPLY("vdd_cmps", NULL),
555 REGULATOR_SUPPLY("vdd_temp", NULL),
556 REGULATOR_SUPPLY("vpp_kfuse", NULL),
557 REGULATOR_SUPPLY("vddio_ts", NULL),
558 REGULATOR_SUPPLY("vdd_ir_led", NULL),
559 REGULATOR_SUPPLY("vddio_1wire", NULL),
560 REGULATOR_SUPPLY("avddio_audio", NULL),
561 REGULATOR_SUPPLY("vdd_ec", NULL),
562 REGULATOR_SUPPLY("vcom_pa", NULL),
563 REGULATOR_SUPPLY("vdd_3v3_devices", NULL),
564 REGULATOR_SUPPLY("vdd_3v3_dock", NULL),
565 REGULATOR_SUPPLY("vdd_3v3_edid", NULL),
566 REGULATOR_SUPPLY("vdd_3v3_hdmi_cec", NULL),
567 REGULATOR_SUPPLY("vdd_3v3_gmi", NULL),
568 REGULATOR_SUPPLY("vdd_spk_amp", "tegra-snd-wm8903.0"),
569 REGULATOR_SUPPLY("vdd_3v3_sensor", NULL),
570 REGULATOR_SUPPLY("vdd_3v3_cam", NULL),
571 REGULATOR_SUPPLY("vdd_3v3_als", NULL),
572 REGULATOR_SUPPLY("debug_cons", NULL),
573 REGULATOR_SUPPLY("vdd", "1-004c"),
574};
575
576/* DIS_5V_SWITCH from AP SPI2_SCK X02 */
577static struct regulator_consumer_supply fixed_reg_dis_5v_switch_supply[] = {
578 REGULATOR_SUPPLY("master_5v_switch", NULL),
579};
580
581/* EN_VDD_BL */
582static struct regulator_consumer_supply fixed_reg_en_vdd_bl_supply[] = {
583 REGULATOR_SUPPLY("vdd_backlight", NULL),
584 REGULATOR_SUPPLY("vdd_backlight1", NULL),
585};
586
587/* EN_VDD_BL2 (E1291-A03) from AP PEX_L0_PRSNT_N DD.00 */
588static struct regulator_consumer_supply fixed_reg_en_vdd_bl2_supply[] = {
589 REGULATOR_SUPPLY("vdd_backlight2", NULL),
590};
591
592/* EN_3V3_MODEM from AP GPIO VI_VSYNCH D06*/
593static struct regulator_consumer_supply fixed_reg_en_3v3_modem_supply[] = {
594 REGULATOR_SUPPLY("vdd_3v3_mini_card", NULL),
595 REGULATOR_SUPPLY("vdd_mini_card", NULL),
596};
597
598/* EN_VDD_PNL1 from AP GPIO VI_D6 L04*/
599static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = {
600 REGULATOR_SUPPLY("vdd_lcd_panel", NULL),
601};
602
603/* CAM1_LDO_EN from AP GPIO KB_ROW6 R06*/
604static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = {
605 REGULATOR_SUPPLY("vdd_2v8_cam1", NULL),
606 REGULATOR_SUPPLY("vdd", "6-0072"),
607};
608
609/* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/
610static struct regulator_consumer_supply fixed_reg_cam2_ldo_en_supply[] = {
611 REGULATOR_SUPPLY("vdd_2v8_cam2", NULL),
612 REGULATOR_SUPPLY("vdd", "7-0072"),
613};
614
615/* CAM3_LDO_EN from AP GPIO KB_ROW8 S00*/
616static struct regulator_consumer_supply fixed_reg_cam3_ldo_en_supply[] = {
617 REGULATOR_SUPPLY("vdd_cam3", NULL),
618};
619
620/* EN_VDD_COM from AP GPIO SDMMC3_DAT5 D00*/
621static struct regulator_consumer_supply fixed_reg_en_vdd_com_supply[] = {
622 REGULATOR_SUPPLY("vdd_com_bd", NULL),
623};
624
625/* EN_VDD_SDMMC1 from AP GPIO VI_HSYNC D07*/
626static struct regulator_consumer_supply fixed_reg_en_vdd_sdmmc1_supply[] = {
627 REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.0"),
628};
629
630/* EN_3V3_EMMC from AP GPIO SDMMC3_DAT4 D01*/
631static struct regulator_consumer_supply fixed_reg_en_3v3_emmc_supply[] = {
632 REGULATOR_SUPPLY("vdd_emmc_core", NULL),
633};
634
635/* EN_3V3_PEX_HVDD from AP GPIO VI_D09 L07*/
636static struct regulator_consumer_supply fixed_reg_en_3v3_pex_hvdd_supply[] = {
637 REGULATOR_SUPPLY("hvdd_pex", NULL),
638};
639
640/* EN_3v3_FUSE from AP GPIO VI_D08 L06*/
641static struct regulator_consumer_supply fixed_reg_en_3v3_fuse_supply[] = {
642 REGULATOR_SUPPLY("vdd_fuse", NULL),
643};
644
645/* EN_1V8_CAM from AP GPIO GPIO_PBB4 PBB04*/
646static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
647 REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
648 REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
649 REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
650 REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
651 REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
652 REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
653};
654
655static struct regulator_consumer_supply fixed_reg_en_vbrtr_supply[] = {
656 REGULATOR_SUPPLY("vdd_vbrtr", NULL),
657};
658
659/* EN_USB1_VBUS_OC*/
660static struct regulator_consumer_supply gpio_switch_en_usb1_vbus_oc_supply[] = {
661 REGULATOR_SUPPLY("vdd_vbus_micro_usb", NULL),
662};
663static int gpio_switch_en_usb1_vbus_oc_voltages[] = { 5000};
664
665/*EN_USB3_VBUS_OC*/
666static struct regulator_consumer_supply gpio_switch_en_usb3_vbus_oc_supply[] = {
667 REGULATOR_SUPPLY("vdd_vbus_typea_usb", NULL),
668};
669static int gpio_switch_en_usb3_vbus_oc_voltages[] = { 5000};
670
671/* EN_VDDIO_VID_OC from AP GPIO VI_PCLK T00*/
672static struct regulator_consumer_supply gpio_switch_en_vddio_vid_oc_supply[] = {
673 REGULATOR_SUPPLY("vdd_hdmi_con", NULL),
674};
675static int gpio_switch_en_vddio_vid_oc_voltages[] = { 5000};
676
677static int enable_load_switch_rail(
678 struct gpio_switch_regulator_subdev_data *psubdev_data)
679{
680 int ret;
681
682 if (psubdev_data->pin_group <= 0)
683 return -EINVAL;
684
685 /* Tristate and make pin as input*/
686 ret = tegra_pinmux_set_tristate(psubdev_data->pin_group,
687 TEGRA_TRI_TRISTATE);
688 if (ret < 0)
689 return ret;
690 return gpio_direction_input(psubdev_data->gpio_nr);
691}
692
693static int disable_load_switch_rail(
694 struct gpio_switch_regulator_subdev_data *psubdev_data)
695{
696 int ret;
697
698 if (psubdev_data->pin_group <= 0)
699 return -EINVAL;
700
701 /* Un-tristate and driver low */
702 ret = tegra_pinmux_set_tristate(psubdev_data->pin_group,
703 TEGRA_TRI_NORMAL);
704 if (ret < 0)
705 return ret;
706 return gpio_direction_output(psubdev_data->gpio_nr, 0);
707}
708
709/* Macro for defining gpio switch regulator sub device data */
710#define GREG_INIT(_id, _var, _name, _input_supply, _always_on, _boot_on, \
711 _gpio_nr, _active_low, _init_state, _pg, _enable, _disable) \
712 static struct gpio_switch_regulator_subdev_data gpio_pdata_##_var = \
713 { \
714 .regulator_name = "gpio-switch-"#_name, \
715 .input_supply = _input_supply, \
716 .id = _id, \
717 .gpio_nr = _gpio_nr, \
718 .pin_group = _pg, \
719 .active_low = _active_low, \
720 .init_state = _init_state, \
721 .voltages = gpio_switch_##_name##_voltages, \
722 .n_voltages = ARRAY_SIZE(gpio_switch_##_name##_voltages), \
723 .num_consumer_supplies = \
724 ARRAY_SIZE(gpio_switch_##_name##_supply), \
725 .consumer_supplies = gpio_switch_##_name##_supply, \
726 .constraints = { \
727 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
728 REGULATOR_MODE_STANDBY), \
729 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
730 REGULATOR_CHANGE_STATUS | \
731 REGULATOR_CHANGE_VOLTAGE), \
732 .always_on = _always_on, \
733 .boot_on = _boot_on, \
734 }, \
735 .enable_rail = _enable, \
736 .disable_rail = _disable, \
737 }; \
738 static struct gpio_switch_regulator_subdev_data \
739 *gpio_pdata_##_var##_list[] = { \
740 &gpio_pdata_##_var, \
741 }; \
742 static struct gpio_switch_regulator_platform_data gs_##_var##_pdata = \
743 { \
744 .num_subdevs = 1, \
745 .subdevs = gpio_pdata_##_var##_list, \
746 }; \
747 static struct platform_device gswitch_reg_##_var##_dev = { \
748 .name = "gpio-switch-regulator", \
749 .id = _id, \
750 .dev = { \
751 .platform_data = &gs_##_var##_pdata, \
752 }, \
753 }
754
755/* Macro for defining fixed regulator sub device data */
756#define FIXED_SUPPLY(_name) "fixed_reg_"#_name
757#define FIXED_REG(_id, _var, _name, _in_supply, _always_on, _boot_on, \
758 _gpio_nr, _active_high, _boot_state, _millivolts) \
759 static struct regulator_init_data ri_data_##_var = \
760 { \
761 .supply_regulator = _in_supply, \
762 .num_consumer_supplies = \
763 ARRAY_SIZE(fixed_reg_##_name##_supply), \
764 .consumer_supplies = fixed_reg_##_name##_supply, \
765 .constraints = { \
766 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
767 REGULATOR_MODE_STANDBY), \
768 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
769 REGULATOR_CHANGE_STATUS | \
770 REGULATOR_CHANGE_VOLTAGE), \
771 .always_on = _always_on, \
772 .boot_on = _boot_on, \
773 }, \
774 }; \
775 static struct fixed_voltage_config fixed_reg_##_var##_pdata = \
776 { \
777 .supply_name = FIXED_SUPPLY(_name), \
778 .microvolts = _millivolts * 1000, \
779 .gpio = _gpio_nr, \
780 .enable_high = _active_high, \
781 .enabled_at_boot = _boot_state, \
782 .init_data = &ri_data_##_var, \
783 }; \
784 static struct platform_device fixed_reg_##_var##_dev = { \
785 .name = "reg-fixed-voltage", \
786 .id = _id, \
787 .dev = { \
788 .platform_data = &fixed_reg_##_var##_pdata, \
789 }, \
790 }
791
792/* common to most of boards*/
793FIXED_REG(0, en_5v_cp, en_5v_cp, NULL, 1, 0, TPS6591X_GPIO_0, true, 1, 5000);
794FIXED_REG(1, en_5v0, en_5v0, NULL, 0, 0, TPS6591X_GPIO_2, true, 0, 5000);
795FIXED_REG(2, en_ddr, en_ddr, NULL, 1, 0, TPS6591X_GPIO_6, true, 1, 1500);
796FIXED_REG(3, en_3v3_sys, en_3v3_sys, NULL, 0, 0, TPS6591X_GPIO_7, true, 1, 3300);
797//FIXED_REG(4, en_vdd_bl, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PK3, true, 1, 5000);
798FIXED_REG(4, en_vdd_bl, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PQ7, true, 1, 5000);
799FIXED_REG(5, en_3v3_modem, en_3v3_modem, NULL, 1, 0, TEGRA_GPIO_PD6, true, 1, 3300);
800//FIXED_REG(6, en_vdd_pnl1, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL4, true, 1, 3300);
801FIXED_REG(6, en_vdd_pnl1, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PQ5, true, 1, 3300);
802FIXED_REG(7, cam3_ldo_en, cam3_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PS0, true, 0, 3300);
803FIXED_REG(8, en_vdd_com, en_vdd_com, FIXED_SUPPLY(en_3v3_sys), 1, 0, TEGRA_GPIO_PD0, true, 1, 3300);
804//FIXED_REG(9, en_3v3_fuse, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL6, true, 0, 3300);
805FIXED_REG(9, en_3v3_fuse, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PP7, true, 0, 3300);
806FIXED_REG(10, en_3v3_emmc, en_3v3_emmc, FIXED_SUPPLY(en_3v3_sys), 1, 0, TEGRA_GPIO_PD1, true, 1, 3300);
807//FIXED_REG(11, en_vdd_sdmmc1, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PD7, true, 1, 3300);
808FIXED_REG(11, en_vdd_sdmmc1, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PD4, false, 1, 3300);
809FIXED_REG(12, en_3v3_pex_hvdd, en_3v3_pex_hvdd, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PD3, true, 0, 3300);
810FIXED_REG(13, en_1v8_cam, en_1v8_cam, tps6591x_rails(VIO), 0, 0, TEGRA_GPIO_PBB4, true, 0, 1800);
811
812/* Specific to E1187/E1186/E1256 */
813FIXED_REG(14, dis_5v_switch_e118x, dis_5v_switch, FIXED_SUPPLY(en_5v0), 0, 0, TEGRA_GPIO_PX2, false, 0, 5000);
814
815/* E1291-A04/A05 specific */
816FIXED_REG(1, en_5v0_a04, en_5v0, NULL, 0, 0, TPS6591X_GPIO_8, true, 0, 5000);
817FIXED_REG(2, en_ddr_a04, en_ddr, NULL, 1, 0, TPS6591X_GPIO_7, true, 1, 1500);
818FIXED_REG(3, en_3v3_sys_a04, en_3v3_sys, NULL, 0, 0, TPS6591X_GPIO_6, true, 1, 3300);
819
820/* Specific to pm269 */
821FIXED_REG(4, en_vdd_bl_pm269, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PH3, true, 1, 5000);
822#ifndef CONFIG_TEGRA_CARDHU_DSI
823FIXED_REG(6, en_vdd_pnl1_pm269, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PW1, true, 1, 3300);
824#endif
825FIXED_REG(9, en_3v3_fuse_pm269, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PC1, true, 0, 3300);
826FIXED_REG(12, en_3v3_pex_hvdd_pm269, en_3v3_pex_hvdd, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PC6, true, 0, 3300);
827
828/* E1198/E1291 specific*/
829FIXED_REG(18, cam1_ldo_en, cam1_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PR6, true, 0, 2800);
830FIXED_REG(19, cam2_ldo_en, cam2_ldo_en, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PR7, true, 0, 2800);
831
832/* E1291 A03 specific */
833FIXED_REG(20, en_vdd_bl1_a03, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PDD2, true, 1, 5000);
834FIXED_REG(21, en_vdd_bl2_a03, en_vdd_bl2, NULL, 0, 0, TEGRA_GPIO_PDD0, true, 1, 5000);
835FIXED_REG(22, en_vbrtr, en_vbrtr, FIXED_SUPPLY(en_3v3_sys), 0, 0, PMU_TCA6416_GPIO_PORT12,true, 0, 3300);
836
837/* PM313 display board specific */
838FIXED_REG(4, en_vdd_bl_pm313, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PK3, true, 1, 5000);
839FIXED_REG(6, en_vdd_pnl1_pm313, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PH3, true, 1, 3300);
840
841
842/****************** Open collector Load switches *******/
843/*Specific to pm269*/
844GREG_INIT(17, en_vddio_vid_oc_pm269, en_vddio_vid_oc, "master_5v_switch", 0, 0, TEGRA_GPIO_PP2, false, 0, TEGRA_PINGROUP_DAP3_DOUT,
845 enable_load_switch_rail, disable_load_switch_rail);
846
847/* Specific to pm311 */
848GREG_INIT(15, en_usb1_vbus_oc_pm311, en_usb1_vbus_oc, "master_5v_switch", 0, 0, TEGRA_GPIO_PCC7, false, 0, TEGRA_PINGROUP_GMI_RST_N,
849 enable_load_switch_rail, disable_load_switch_rail);
850GREG_INIT(16, en_usb3_vbus_oc_pm311, en_usb3_vbus_oc, "master_5v_switch", 0, 0, TEGRA_GPIO_PCC6, false, 0, TEGRA_PINGROUP_GMI_AD15,
851 enable_load_switch_rail, disable_load_switch_rail);
852
853/* Specific to E1187/E1186/E1256 */
854GREG_INIT(15, en_usb1_vbus_oc_e118x, en_usb1_vbus_oc, "master_5v_switch", 0, 0, TEGRA_GPIO_PI4, false, 0, TEGRA_PINGROUP_GMI_RST_N,
855 enable_load_switch_rail, disable_load_switch_rail);
856GREG_INIT(16, en_usb3_vbus_oc_e118x, en_usb3_vbus_oc, "master_5v_switch", 0, 0, TEGRA_GPIO_PH7, false, 0, TEGRA_PINGROUP_GMI_AD15,
857 enable_load_switch_rail, disable_load_switch_rail);
858GREG_INIT(17, en_vddio_vid_oc_e118x, en_vddio_vid_oc, "master_5v_switch", 0, 0, TEGRA_GPIO_PT0, false, 0, TEGRA_PINGROUP_VI_PCLK,
859 enable_load_switch_rail, disable_load_switch_rail);
860
861/* E1198/E1291 specific fab < A03 */
862GREG_INIT(15, en_usb1_vbus_oc, en_usb1_vbus_oc, "vdd_5v0_sys", 0, 0, TEGRA_GPIO_PI4, false, 0, TEGRA_PINGROUP_GMI_RST_N,
863 enable_load_switch_rail, disable_load_switch_rail);
864GREG_INIT(16, en_usb3_vbus_oc, en_usb3_vbus_oc, "vdd_5v0_sys", 0, 0, TEGRA_GPIO_PH7, false, 0, TEGRA_PINGROUP_GMI_AD15,
865 enable_load_switch_rail, disable_load_switch_rail);
866
867/* E1198/E1291 specific fab >= A03 */
868GREG_INIT(15, en_usb1_vbus_oc_a03, en_usb1_vbus_oc, "vdd_5v0_sys", 0, 0, TEGRA_GPIO_PDD6, false, 0, TEGRA_PINGROUP_PEX_L1_CLKREQ_N,
869 enable_load_switch_rail, disable_load_switch_rail);
870GREG_INIT(16, en_usb3_vbus_oc_a03, en_usb3_vbus_oc, "vdd_5v0_sys", 0, 0, TEGRA_GPIO_PDD4, false, 0, TEGRA_PINGROUP_PEX_L1_PRSNT_N,
871 enable_load_switch_rail, disable_load_switch_rail);
872
873/* E1198/E1291 specific */
874//GREG_INIT(17, en_vddio_vid_oc, en_vddio_vid_oc, "vdd_5v0_sys", 0, 0, TEGRA_GPIO_PT0, false, 0, TEGRA_PINGROUP_VI_PCLK,
875// enable_load_switch_rail, disable_load_switch_rail);
876
877GREG_INIT(17, en_vddio_vid_oc, en_vddio_vid_oc, "vdd_5v0_sys", 0, 0, TEGRA_GPIO_PQ6, false, 0, TEGRA_PINGROUP_VI_PCLK,
878 enable_load_switch_rail, disable_load_switch_rail);
879
880/*
881 * Creating the fixed/gpio-switch regulator device tables for different boards
882 */
883#define ADD_FIXED_REG(_name) (&fixed_reg_##_name##_dev)
884#define ADD_GPIO_REG(_name) (&gswitch_reg_##_name##_dev)
885
886#define COMMON_FIXED_REG \
887 ADD_FIXED_REG(en_5v_cp), \
888 ADD_FIXED_REG(en_5v0), \
889 ADD_FIXED_REG(en_ddr), \
890 ADD_FIXED_REG(en_3v3_sys), \
891 ADD_FIXED_REG(en_3v3_modem), \
892 ADD_FIXED_REG(en_vdd_pnl1), \
893 ADD_FIXED_REG(cam3_ldo_en), \
894 ADD_FIXED_REG(en_vdd_com), \
895 ADD_FIXED_REG(en_3v3_fuse), \
896 ADD_FIXED_REG(en_3v3_emmc), \
897 ADD_FIXED_REG(en_vdd_sdmmc1), \
898 ADD_FIXED_REG(en_3v3_pex_hvdd), \
899 ADD_FIXED_REG(en_1v8_cam),
900
901#define COMMON_FIXED_REG_E1291_A04 \
902 ADD_FIXED_REG(en_5v_cp), \
903 ADD_FIXED_REG(en_5v0_a04), \
904 ADD_FIXED_REG(en_ddr_a04), \
905 ADD_FIXED_REG(en_3v3_sys_a04), \
906 ADD_FIXED_REG(en_vdd_pnl1), \
907 ADD_FIXED_REG(en_3v3_fuse), \
908 ADD_FIXED_REG(en_3v3_emmc), \
909 ADD_FIXED_REG(en_vdd_sdmmc1), \
910 ADD_FIXED_REG(en_3v3_pex_hvdd),
911
912/*
913#define COMMON_FIXED_REG_E1291_A04 \
914 ADD_FIXED_REG(en_5v_cp), \
915 ADD_FIXED_REG(en_5v0_a04), \
916 ADD_FIXED_REG(en_ddr_a04), \
917 ADD_FIXED_REG(en_3v3_sys_a04), \
918 ADD_FIXED_REG(en_3v3_modem), \ //not used Carma
919 ADD_FIXED_REG(en_vdd_pnl1), \ //not used Carma
920 ADD_FIXED_REG(cam3_ldo_en), \ //not used Carma
921 ADD_FIXED_REG(en_vdd_com), \ //not used Carma
922 ADD_FIXED_REG(en_3v3_fuse), \
923 ADD_FIXED_REG(en_3v3_emmc), \
924 ADD_FIXED_REG(en_vdd_sdmmc1), \
925 ADD_FIXED_REG(en_3v3_pex_hvdd), \
926 ADD_FIXED_REG(en_1v8_cam), //not used Carma
927*/
928
929#define PM269_FIXED_REG \
930 ADD_FIXED_REG(en_5v_cp), \
931 ADD_FIXED_REG(en_5v0), \
932 ADD_FIXED_REG(en_ddr), \
933 ADD_FIXED_REG(en_3v3_sys), \
934 ADD_FIXED_REG(en_3v3_modem), \
935 ADD_FIXED_REG(cam1_ldo_en), \
936 ADD_FIXED_REG(cam2_ldo_en), \
937 ADD_FIXED_REG(cam3_ldo_en), \
938 ADD_FIXED_REG(en_vdd_com), \
939 ADD_FIXED_REG(en_3v3_fuse_pm269), \
940 ADD_FIXED_REG(en_3v3_emmc), \
941 ADD_FIXED_REG(en_3v3_pex_hvdd_pm269), \
942 ADD_FIXED_REG(en_1v8_cam), \
943 ADD_FIXED_REG(dis_5v_switch_e118x), \
944 ADD_GPIO_REG(en_usb1_vbus_oc_e118x), \
945 ADD_GPIO_REG(en_usb3_vbus_oc_e118x), \
946 ADD_GPIO_REG(en_vddio_vid_oc_pm269),
947
948#define PM311_FIXED_REG \
949 ADD_FIXED_REG(en_5v_cp), \
950 ADD_FIXED_REG(en_5v0), \
951 ADD_FIXED_REG(en_ddr), \
952 ADD_FIXED_REG(en_3v3_sys), \
953 ADD_FIXED_REG(en_3v3_modem), \
954 ADD_FIXED_REG(cam1_ldo_en), \
955 ADD_FIXED_REG(cam2_ldo_en), \
956 ADD_FIXED_REG(cam3_ldo_en), \
957 ADD_FIXED_REG(en_vdd_com), \
958 ADD_FIXED_REG(en_3v3_fuse_pm269), \
959 ADD_FIXED_REG(en_3v3_emmc), \
960 ADD_FIXED_REG(en_3v3_pex_hvdd_pm269), \
961 ADD_FIXED_REG(en_1v8_cam), \
962 ADD_FIXED_REG(dis_5v_switch_e118x), \
963 ADD_GPIO_REG(en_usb1_vbus_oc_pm311), \
964 ADD_GPIO_REG(en_usb3_vbus_oc_pm311), \
965 ADD_GPIO_REG(en_vddio_vid_oc_pm269),
966
967
968#ifndef CONFIG_TEGRA_CARDHU_DSI
969#define E1247_DISPLAY_FIXED_REG \
970 ADD_FIXED_REG(en_vdd_bl_pm269), \
971 ADD_FIXED_REG(en_vdd_pnl1_pm269),
972#else
973#define E1247_DISPLAY_FIXED_REG \
974 ADD_FIXED_REG(en_vdd_bl_pm269),
975#endif
976
977#define PM313_DISPLAY_FIXED_REG \
978 ADD_FIXED_REG(en_vdd_bl_pm313), \
979 ADD_FIXED_REG(en_vdd_pnl1_pm313),
980
981#define E118x_FIXED_REG \
982 ADD_FIXED_REG(en_5v_cp), \
983 ADD_FIXED_REG(en_5v0), \
984 ADD_FIXED_REG(en_ddr), \
985 ADD_FIXED_REG(en_3v3_sys), \
986 ADD_FIXED_REG(en_3v3_modem), \
987 ADD_FIXED_REG(cam3_ldo_en), \
988 ADD_FIXED_REG(en_vdd_com), \
989 ADD_FIXED_REG(en_3v3_fuse), \
990 ADD_FIXED_REG(en_3v3_emmc), \
991 ADD_FIXED_REG(en_vdd_sdmmc1), \
992 ADD_FIXED_REG(en_3v3_pex_hvdd), \
993 ADD_FIXED_REG(en_1v8_cam), \
994 ADD_FIXED_REG(dis_5v_switch_e118x), \
995 ADD_FIXED_REG(en_vbrtr), \
996 ADD_GPIO_REG(en_usb1_vbus_oc_e118x), \
997 ADD_GPIO_REG(en_usb3_vbus_oc_e118x), \
998 ADD_GPIO_REG(en_vddio_vid_oc_e118x),
999
1000#define E1198_FIXED_REG \
1001 ADD_GPIO_REG(en_vddio_vid_oc),
1002
1003#define E1291_1198_A00_FIXED_REG \
1004 ADD_FIXED_REG(en_vdd_bl), \
1005 ADD_GPIO_REG(en_usb1_vbus_oc), \
1006 ADD_GPIO_REG(en_usb3_vbus_oc),
1007
1008#define E1291_A03_FIXED_REG \
1009 ADD_FIXED_REG(en_vdd_bl1_a03), \
1010 ADD_FIXED_REG(en_vdd_bl2_a03), \
1011 ADD_GPIO_REG(en_usb1_vbus_oc_a03), \
1012 ADD_GPIO_REG(en_usb3_vbus_oc_a03),
1013
1014/* Fixed regulator devices for E1186/E1187/E1256 */
1015static struct platform_device *fixed_reg_devs_e118x[] = {
1016 E118x_FIXED_REG
1017 E1247_DISPLAY_FIXED_REG
1018};
1019
1020/* Fixed regulator devices for E1186/E1187/E1256 */
1021static struct platform_device *fixed_reg_devs_e118x_pm313[] = {
1022 E118x_FIXED_REG
1023 PM313_DISPLAY_FIXED_REG
1024};
1025
1026/* Fixed regulator devices for E1198 and E1291 */
1027static struct platform_device *fixed_reg_devs_e1198_base[] = {
1028 COMMON_FIXED_REG
1029 E1291_1198_A00_FIXED_REG
1030 E1198_FIXED_REG
1031};
1032
1033static struct platform_device *fixed_reg_devs_e1198_a02[] = {
1034 ADD_FIXED_REG(en_5v_cp),
1035 ADD_FIXED_REG(en_5v0),
1036 ADD_FIXED_REG(en_ddr_a04),
1037 ADD_FIXED_REG(en_3v3_sys_a04),
1038 ADD_FIXED_REG(en_3v3_modem),
1039 ADD_FIXED_REG(en_vdd_pnl1),
1040 ADD_FIXED_REG(cam3_ldo_en),
1041 ADD_FIXED_REG(en_vdd_com),
1042 ADD_FIXED_REG(en_3v3_fuse),
1043 ADD_FIXED_REG(en_3v3_emmc),
1044 ADD_FIXED_REG(en_vdd_sdmmc1),
1045 ADD_FIXED_REG(en_3v3_pex_hvdd),
1046 ADD_FIXED_REG(en_1v8_cam),
1047 ADD_FIXED_REG(en_vdd_bl1_a03),
1048 ADD_FIXED_REG(en_vdd_bl2_a03),
1049 ADD_FIXED_REG(cam1_ldo_en),
1050 ADD_FIXED_REG(cam2_ldo_en),
1051 ADD_GPIO_REG(en_usb1_vbus_oc_a03),
1052 ADD_GPIO_REG(en_usb3_vbus_oc_a03),
1053 ADD_GPIO_REG(en_vddio_vid_oc),
1054};
1055
1056/* Fixed regulator devices for PM269 */
1057static struct platform_device *fixed_reg_devs_pm269[] = {
1058 PM269_FIXED_REG
1059 E1247_DISPLAY_FIXED_REG
1060};
1061
1062/* Fixed regulator devices for PM269 */
1063static struct platform_device *fixed_reg_devs_pm269_pm313[] = {
1064 PM269_FIXED_REG
1065 PM313_DISPLAY_FIXED_REG
1066};
1067
1068/* Fixed regulator devices for PM311 */
1069static struct platform_device *fixed_reg_devs_pm311[] = {
1070 PM311_FIXED_REG
1071 E1247_DISPLAY_FIXED_REG
1072};
1073
1074/* Fixed regulator devices for PM11 */
1075static struct platform_device *fixed_reg_devs_pm311_pm313[] = {
1076 PM311_FIXED_REG
1077 PM313_DISPLAY_FIXED_REG
1078};
1079
1080/* Fixed regulator devices for E1291 A03 */
1081static struct platform_device *fixed_reg_devs_e1291_a03[] = {
1082 COMMON_FIXED_REG
1083 E1291_A03_FIXED_REG
1084 E1198_FIXED_REG
1085};
1086
1087/* Fixed regulator devices for E1291 A04/A05 */
1088static struct platform_device *fixed_reg_devs_e1291_a04[] = {
1089 COMMON_FIXED_REG_E1291_A04
1090 E1291_A03_FIXED_REG
1091 E1198_FIXED_REG
1092};
1093
1094int __init cardhu_fixed_regulator_init(void)
1095{
1096 int i;
1097 struct board_info board_info;
1098 struct board_info pmu_board_info;
1099 struct board_info display_board_info;
1100 struct platform_device **fixed_reg_devs;
1101 int nfixreg_devs;
1102
1103 if (!machine_is_cardhu())
1104 return 0;
1105
1106 tegra_get_board_info(&board_info);
1107 tegra_get_pmu_board_info(&pmu_board_info);
1108 tegra_get_display_board_info(&display_board_info);
1109
1110 if (pmu_board_info.board_id == BOARD_PMU_PM298)
1111 return cardhu_pm298_gpio_switch_regulator_init();
1112
1113 if (pmu_board_info.board_id == BOARD_PMU_PM299)
1114 return cardhu_pm299_gpio_switch_regulator_init();
1115
1116 switch (board_info.board_id) {
1117 case BOARD_E1198:
1118 if (board_info.fab <= BOARD_FAB_A01) {
1119 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1198_base);
1120 fixed_reg_devs = fixed_reg_devs_e1198_base;
1121 } else {
1122 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1198_a02);
1123 fixed_reg_devs = fixed_reg_devs_e1198_a02;
1124 }
1125 break;
1126
1127 case BOARD_E1291:
1128 if (board_info.fab == BOARD_FAB_A03) {
1129 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1291_a03);
1130 fixed_reg_devs = fixed_reg_devs_e1291_a03;
1131 } else if ((board_info.fab == BOARD_FAB_A04) ||
1132 (board_info.fab == BOARD_FAB_A05)) {
1133 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1291_a04);
1134 fixed_reg_devs = fixed_reg_devs_e1291_a04;
1135 } else {
1136 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1198_base);
1137 fixed_reg_devs = fixed_reg_devs_e1198_base;
1138 }
1139 break;
1140
1141 case BOARD_PM311:
1142 case BOARD_PM305:
1143 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm311);
1144 fixed_reg_devs = fixed_reg_devs_pm311;
1145 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
1146 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm311_pm313);
1147 fixed_reg_devs = fixed_reg_devs_pm311_pm313;
1148 }
1149 break;
1150
1151 case BOARD_PM269:
1152 case BOARD_E1257:
1153 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm269);
1154 fixed_reg_devs = fixed_reg_devs_pm269;
1155 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
1156 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm269_pm313);
1157 fixed_reg_devs = fixed_reg_devs_pm269_pm313;
1158 } else {
1159 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_pm269);
1160 fixed_reg_devs = fixed_reg_devs_pm269;
1161 }
1162 break;
1163
1164 default:
1165 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
1166 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e118x_pm313);
1167 fixed_reg_devs = fixed_reg_devs_e118x_pm313;
1168 } else {
1169 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e118x);
1170 fixed_reg_devs = fixed_reg_devs_e118x;
1171 }
1172 break;
1173 }
1174
1175 for (i = 0; i < nfixreg_devs; ++i) {
1176 int gpio_nr;
1177 if (!strncmp(fixed_reg_devs[i]->name, "gpio", 4)) {
1178 struct gpio_switch_regulator_platform_data *gs_pdata =
1179 fixed_reg_devs[i]->dev.platform_data;
1180 gpio_nr = gs_pdata->subdevs[0]->gpio_nr;
1181 } else {
1182 struct fixed_voltage_config *fixed_reg_pdata =
1183 fixed_reg_devs[i]->dev.platform_data;
1184 gpio_nr = fixed_reg_pdata->gpio;
1185 }
1186
1187 if (gpio_nr < TEGRA_NR_GPIOS)
1188 tegra_gpio_enable(gpio_nr);
1189 }
1190 return platform_add_devices(fixed_reg_devs, nfixreg_devs);
1191}
1192subsys_initcall_sync(cardhu_fixed_regulator_init);
1193
1194static void cardhu_board_suspend(int lp_state, enum suspend_stage stg)
1195{
1196 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
1197 tegra_console_uart_suspend();
1198}
1199
1200static void cardhu_board_resume(int lp_state, enum resume_stage stg)
1201{
1202 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
1203 tegra_console_uart_resume();
1204}
1205
1206static struct tegra_suspend_platform_data cardhu_suspend_data = {
1207 .cpu_timer = 2000,
1208 .cpu_off_timer = 200,
1209 .suspend_mode = TEGRA_SUSPEND_LP0,
1210 .core_timer = 0x7e7e,
1211 .core_off_timer = 0,
1212 .corereq_high = true,
1213 .sysclkreq_high = true,
1214 .cpu_lp2_min_residency = 2000,
1215 .board_suspend = cardhu_board_suspend,
1216 .board_resume = cardhu_board_resume,
1217};
1218
1219int __init cardhu_suspend_init(void)
1220{
1221 struct board_info board_info;
1222 struct board_info pmu_board_info;
1223
1224 tegra_get_board_info(&board_info);
1225 tegra_get_pmu_board_info(&pmu_board_info);
1226
1227 /* For PMU Fab A03, A04 and A05 make core_pwr_req to high */
1228 if ((pmu_board_info.fab == BOARD_FAB_A03) ||
1229 (pmu_board_info.fab == BOARD_FAB_A04) ||
1230 (pmu_board_info.fab == BOARD_FAB_A05))
1231 cardhu_suspend_data.corereq_high = true;
1232
1233 /* CORE_PWR_REQ to be high for all processor/pmu board whose sku bit 0
1234 * is set. This is require to enable the dc-dc converter tps62361x */
1235 if ((board_info.sku & SKU_DCDC_TPS62361_SUPPORT) || (pmu_board_info.sku & SKU_DCDC_TPS62361_SUPPORT))
1236 cardhu_suspend_data.corereq_high = true;
1237
1238 switch (board_info.board_id) {
1239 case BOARD_E1291:
1240 /* CORE_PWR_REQ to be high for E1291-A03 */
1241 if (board_info.fab == BOARD_FAB_A03)
1242 cardhu_suspend_data.corereq_high = true;
1243 break;
1244 case BOARD_E1198:
1245 case BOARD_PM269:
1246 case BOARD_PM305:
1247 case BOARD_PM311:
1248 break;
1249 case BOARD_E1187:
1250 case BOARD_E1186:
1251 case BOARD_E1256:
1252 case BOARD_E1257:
1253 cardhu_suspend_data.cpu_timer = 5000;
1254 cardhu_suspend_data.cpu_off_timer = 5000;
1255 break;
1256 default:
1257 break;
1258 }
1259
1260 tegra_init_suspend(&cardhu_suspend_data);
1261 return 0;
1262}
1263
1264static struct tegra_tsensor_pmu_data tpdata = {
1265 .poweroff_reg_addr = 0x3F,
1266 .poweroff_reg_data = 0x80,
1267 .reset_tegra = 1,
1268 .controller_type = 0,
1269 .i2c_controller_id = 1,
1270 .pinmux = 0,
1271 .pmu_16bit_ops = 0,
1272 .pmu_i2c_addr = 0x2D,
1273};
1274
1275#ifdef CONFIG_TEGRA_EDP_LIMITS
1276
1277int __init cardhu_edp_init(void)
1278{
1279 unsigned int regulator_mA;
1280
1281 regulator_mA = get_maximum_cpu_current_supported();
1282 if (!regulator_mA) {
1283 regulator_mA = 6000; /* regular T30/s */
1284 }
1285 pr_info("%s: CPU regulator %d mA\n", __func__, regulator_mA);
1286
1287 tegra_init_cpu_edp_limits(regulator_mA);
1288 return 0;
1289}
1290#endif
1291
1292static char *cardhu_battery[] = {
1293 "bq27510-0",
1294};
1295
1296static struct gpio_charger_platform_data cardhu_charger_pdata = {
1297 .name = "ac",
1298 .type = POWER_SUPPLY_TYPE_MAINS,
1299 .gpio = AC_PRESENT_GPIO,
1300 .gpio_active_low = 0,
1301 .supplied_to = cardhu_battery,
1302 .num_supplicants = ARRAY_SIZE(cardhu_battery),
1303};
1304
1305static struct platform_device cardhu_charger_device = {
1306 .name = "gpio-charger",
1307 .dev = {
1308 .platform_data = &cardhu_charger_pdata,
1309 },
1310};
1311
1312static int __init cardhu_charger_late_init(void)
1313{
1314 if (!machine_is_cardhu())
1315 return 0;
1316
1317 platform_device_register(&cardhu_charger_device);
1318 return 0;
1319}
1320
1321late_initcall(cardhu_charger_late_init);
diff --git a/arch/arm/mach-tegra/board-cardhu-powermon.c b/arch/arm/mach-tegra/board-cardhu-powermon.c
new file mode 100644
index 00000000000..823cddbabeb
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-powermon.c
@@ -0,0 +1,259 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-powermon.c
3 *
4 * Copyright (c) 2011, NVIDIA, All Rights Reserved.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
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, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <linux/i2c.h>
22#include <linux/ina219.h>
23
24#include "board.h"
25#include "board-cardhu.h"
26
27enum {
28 VDD_AC_BAT,
29 VDD_DRAM_IN,
30 VDD_BACKLIGHT_IN,
31 VDD_CPU_IN,
32 VDD_CORE_IN,
33 VDD_DISPLAY_IN,
34 VDD_3V3_TEGRA,
35 VDD_OTHER_PMU_IN,
36 VDD_1V8_TEGRA,
37 VDD_1V8_OTHER,
38 UNUSED_RAIL,
39};
40
41static struct ina219_platform_data power_mon_info[] = {
42 [VDD_AC_BAT] = {
43 .calibration_data = 0xa000,
44 .power_lsb = 2,
45 .rail_name = "VDD_AC_BAT",
46 .divisor = 20,
47 },
48
49 [VDD_DRAM_IN] = {
50 .calibration_data = 0xa000,
51 .power_lsb = 2,
52 .rail_name = "VDD_DRAM_IN",
53 .divisor = 20,
54 },
55
56 [VDD_BACKLIGHT_IN] = {
57 .calibration_data = 0x6aaa,
58 .power_lsb = 1,
59 .rail_name = "VDD_BACKLIGHT_IN",
60 .divisor = 20,
61 },
62
63 [VDD_CPU_IN] = {
64 .calibration_data = 0xa000,
65 .power_lsb = 1,
66 .rail_name = "VDD_CPU_IN",
67 .divisor = 20,
68 },
69
70 [VDD_CORE_IN] = {
71 .calibration_data = 0x6aaa,
72 .power_lsb = 1,
73 .rail_name = "VDD_CORE_IN",
74 .divisor = 20,
75 },
76
77 [VDD_DISPLAY_IN] = {
78 .calibration_data = 0x4000,
79 .power_lsb = 1,
80 .rail_name = "VDD_DISPLAY_IN",
81 .divisor = 20,
82 },
83
84 [VDD_3V3_TEGRA] = {
85 .calibration_data = 0x6aaa,
86 .power_lsb = 1,
87 .rail_name = "VDD_3V3_TEGRA",
88 .divisor = 20,
89 },
90
91 [VDD_OTHER_PMU_IN] = {
92 .calibration_data = 0xa000,
93 .power_lsb = 1,
94 .rail_name = "VDD_OTHER_PMU_IN",
95 .divisor = 20,
96 },
97
98 [VDD_1V8_TEGRA] = {
99 .calibration_data = 0x4000,
100 .power_lsb = 1,
101 .rail_name = "VDD_1V8_TEGRA",
102 .divisor = 20,
103 },
104
105 [VDD_1V8_OTHER] = {
106 .calibration_data = 0xa000,
107 .power_lsb = 1,
108 .rail_name = "VDD_1V8_OTHER",
109 .divisor = 20,
110 },
111
112 /* All unused INA219 devices use below data*/
113 [UNUSED_RAIL] = {
114 .calibration_data = 0x4000,
115 .power_lsb = 1,
116 .rail_name = "unused_rail",
117 .divisor = 20,
118 },
119};
120
121enum {
122 INA_I2C_ADDR_40,
123 INA_I2C_ADDR_41,
124 INA_I2C_ADDR_42,
125 INA_I2C_ADDR_43,
126 INA_I2C_ADDR_44,
127 INA_I2C_ADDR_45,
128 INA_I2C_ADDR_46,
129 INA_I2C_ADDR_47,
130 INA_I2C_ADDR_48,
131 INA_I2C_ADDR_49,
132 INA_I2C_ADDR_4A,
133 INA_I2C_ADDR_4B,
134 INA_I2C_ADDR_4C,
135 INA_I2C_ADDR_4D,
136 INA_I2C_ADDR_4E,
137 INA_I2C_ADDR_4F,
138};
139
140static struct i2c_board_info cardhu_i2c0_ina219_board_info[] = {
141 [INA_I2C_ADDR_40] = {
142 I2C_BOARD_INFO("ina219", 0x40),
143 .platform_data = &power_mon_info[VDD_AC_BAT],
144 .irq = -1,
145 },
146
147 [INA_I2C_ADDR_41] = {
148 I2C_BOARD_INFO("ina219", 0x41),
149 .platform_data = &power_mon_info[VDD_DRAM_IN],
150 .irq = -1,
151 },
152
153 [INA_I2C_ADDR_42] = {
154 I2C_BOARD_INFO("ina219", 0x42),
155 .platform_data = &power_mon_info[VDD_BACKLIGHT_IN],
156 .irq = -1,
157 },
158
159 [INA_I2C_ADDR_43] = {
160 I2C_BOARD_INFO("ina219", 0x43),
161 .platform_data = &power_mon_info[VDD_CPU_IN],
162 .irq = -1,
163 },
164
165 [INA_I2C_ADDR_44] = {
166 I2C_BOARD_INFO("ina219", 0x44),
167 .platform_data = &power_mon_info[VDD_CORE_IN],
168 .irq = -1,
169 },
170
171 [INA_I2C_ADDR_45] = {
172 I2C_BOARD_INFO("ina219", 0x45),
173 .platform_data = &power_mon_info[VDD_DISPLAY_IN],
174 .irq = -1,
175 },
176
177 [INA_I2C_ADDR_46] = {
178 I2C_BOARD_INFO("ina219", 0x46),
179 .platform_data = &power_mon_info[VDD_3V3_TEGRA],
180 .irq = -1,
181 },
182
183 [INA_I2C_ADDR_47] = {
184 I2C_BOARD_INFO("ina219", 0x47),
185 .platform_data = &power_mon_info[VDD_OTHER_PMU_IN],
186 .irq = -1,
187 },
188
189 [INA_I2C_ADDR_48] = {
190 I2C_BOARD_INFO("ina219", 0x48),
191 .platform_data = &power_mon_info[VDD_1V8_TEGRA],
192 .irq = -1,
193 },
194
195 [INA_I2C_ADDR_49] = {
196 I2C_BOARD_INFO("ina219", 0x49),
197 .platform_data = &power_mon_info[VDD_1V8_OTHER],
198 .irq = -1,
199 },
200
201 [INA_I2C_ADDR_4A] = {
202 I2C_BOARD_INFO("ina219", 0x4A),
203 .platform_data = &power_mon_info[UNUSED_RAIL],
204 .irq = -1,
205 },
206
207 [INA_I2C_ADDR_4B] = {
208 I2C_BOARD_INFO("ina219", 0x4B),
209 .platform_data = &power_mon_info[UNUSED_RAIL],
210 .irq = -1,
211 },
212
213 [INA_I2C_ADDR_4C] = {
214 I2C_BOARD_INFO("ina219", 0x4C),
215 .platform_data = &power_mon_info[UNUSED_RAIL],
216 .irq = -1,
217 },
218
219 [INA_I2C_ADDR_4D] = {
220 I2C_BOARD_INFO("ina219", 0x4D),
221 .platform_data = &power_mon_info[UNUSED_RAIL],
222 .irq = -1,
223 },
224
225 [INA_I2C_ADDR_4E] = {
226 I2C_BOARD_INFO("ina219", 0x4E),
227 .platform_data = &power_mon_info[UNUSED_RAIL],
228 .irq = -1,
229 },
230
231 [INA_I2C_ADDR_4F] = {
232 I2C_BOARD_INFO("ina219", 0x4F),
233 .platform_data = &power_mon_info[UNUSED_RAIL],
234 .irq = -1,
235 },
236};
237
238int __init cardhu_pmon_init(void)
239{
240 struct board_info bi;
241
242 tegra_get_board_info(&bi);
243
244 /* for fab A04 VDD_CORE_IN changed from ina with addr 0x44 to 0x4A */
245 if (bi.fab == BOARD_FAB_A04) {
246 cardhu_i2c0_ina219_board_info[INA_I2C_ADDR_44].platform_data =
247 &power_mon_info[UNUSED_RAIL];
248 cardhu_i2c0_ina219_board_info[INA_I2C_ADDR_4A].platform_data =
249 &power_mon_info[VDD_CORE_IN];
250 }
251
252 if (bi.board_id != BOARD_PM269) {
253 i2c_register_board_info(0, cardhu_i2c0_ina219_board_info,
254 ARRAY_SIZE(cardhu_i2c0_ina219_board_info));
255 }
256
257 return 0;
258}
259
diff --git a/arch/arm/mach-tegra/board-cardhu-sdhci.c b/arch/arm/mach-tegra/board-cardhu-sdhci.c
new file mode 100644
index 00000000000..cbe948fa4a3
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-sdhci.c
@@ -0,0 +1,305 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-sdhci.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
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/resource.h>
19#include <linux/platform_device.h>
20#include <linux/wlan_plat.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/mmc/host.h>
26
27#include <asm/mach-types.h>
28#include <mach/irqs.h>
29#include <mach/iomap.h>
30#include <mach/sdhci.h>
31
32#include "gpio-names.h"
33#include "board.h"
34#include "board-cardhu.h"
35
36#define CARDHU_WLAN_PWR TEGRA_GPIO_PD4
37#define CARDHU_WLAN_RST TEGRA_GPIO_PD3
38#define CARDHU_WLAN_WOW TEGRA_GPIO_PO4
39#define CARDHU_SD_CD TEGRA_GPIO_PV3
40#ifndef CONFIG_TEGRA_SDMMC1_UNLOCK
41#define CARDHU_SD_WP TEGRA_GPIO_PV2
42#else
43#define CARDHU_SD_WP -1
44#endif
45//#define CARDHU_SD_PWR TEGRA_GPIO_PD4
46#define PM269_SD_WP -1
47
48static void (*wifi_status_cb)(int card_present, void *dev_id);
49static void *wifi_status_cb_devid;
50static int cardhu_wifi_status_register(void (*callback)(int , void *), void *);
51
52static int cardhu_wifi_reset(int on);
53static int cardhu_wifi_power(int on);
54static int cardhu_wifi_set_carddetect(int val);
55
56static struct wifi_platform_data cardhu_wifi_control = {
57 .set_power = cardhu_wifi_power,
58 .set_reset = cardhu_wifi_reset,
59 .set_carddetect = cardhu_wifi_set_carddetect,
60};
61
62static struct resource wifi_resource[] = {
63 [0] = {
64 .name = "bcm4329_wlan_irq",
65 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO4),
66 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO4),
67 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
68 },
69};
70
71static struct platform_device cardhu_wifi_device = {
72 .name = "bcm4329_wlan",
73 .id = 1,
74 .num_resources = 1,
75 .resource = wifi_resource,
76 .dev = {
77 .platform_data = &cardhu_wifi_control,
78 },
79};
80
81static struct resource sdhci_resource0[] = {
82 [0] = {
83 .start = INT_SDMMC1,
84 .end = INT_SDMMC1,
85 .flags = IORESOURCE_IRQ,
86 },
87 [1] = {
88 .start = TEGRA_SDMMC1_BASE,
89 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
90 .flags = IORESOURCE_MEM,
91 },
92};
93
94static struct resource sdhci_resource2[] = {
95 [0] = {
96 .start = INT_SDMMC3,
97 .end = INT_SDMMC3,
98 .flags = IORESOURCE_IRQ,
99 },
100 [1] = {
101 .start = TEGRA_SDMMC3_BASE,
102 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
103 .flags = IORESOURCE_MEM,
104 },
105};
106
107static struct resource sdhci_resource3[] = {
108 [0] = {
109 .start = INT_SDMMC4,
110 .end = INT_SDMMC4,
111 .flags = IORESOURCE_IRQ,
112 },
113 [1] = {
114 .start = TEGRA_SDMMC4_BASE,
115 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
116 .flags = IORESOURCE_MEM,
117 },
118};
119
120static struct embedded_sdio_data embedded_sdio_data2 = {
121 .cccr = {
122 .sdio_vsn = 2,
123 .multi_block = 1,
124 .low_speed = 0,
125 .wide_bus = 0,
126 .high_power = 1,
127 .high_speed = 1,
128 },
129 .cis = {
130 .vendor = 0x02d0,
131 .device = 0x4329,
132 },
133};
134
135static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
136 .mmc_data = {
137 .register_status_notify = cardhu_wifi_status_register,
138 .embedded_sdio = &embedded_sdio_data2,
139 .built_in = 1,
140 },
141 .cd_gpio = -1,
142 .wp_gpio = -1,
143 .power_gpio = -1,
144/* .tap_delay = 6,
145 .is_voltage_switch_supported = false,
146 .vdd_rail_name = NULL,
147 .slot_rail_name = NULL,
148 .vdd_max_uv = -1,
149 .vdd_min_uv = -1,
150 .max_clk = 0,
151 .is_8bit_supported = false, */
152};
153
154static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
155 .cd_gpio = CARDHU_SD_CD,
156 .wp_gpio = CARDHU_SD_WP,
157 .power_gpio = -1,
158/* .tap_delay = 6,
159 .is_voltage_switch_supported = true,
160 .vdd_rail_name = "vddio_sdmmc1",
161 .slot_rail_name = "vddio_sd_slot",
162 .vdd_max_uv = 3320000,
163 .vdd_min_uv = 3280000,
164 .max_clk = 208000000,
165 .is_8bit_supported = false, */
166};
167
168static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
169 .cd_gpio = -1,
170 .wp_gpio = -1,
171 .power_gpio = -1,
172 .is_8bit = 1,
173 .tap_delay = 0x0F,
174 .mmc_data = {
175 .built_in = 1,
176 }
177/* .tap_delay = 6,
178 .is_voltage_switch_supported = false,
179 .vdd_rail_name = NULL,
180 .slot_rail_name = NULL,
181 .vdd_max_uv = -1,
182 .vdd_min_uv = -1,
183 .max_clk = 48000000,
184 .is_8bit_supported = true, */
185};
186
187static struct platform_device tegra_sdhci_device0 = {
188 .name = "sdhci-tegra",
189 .id = 0,
190 .resource = sdhci_resource0,
191 .num_resources = ARRAY_SIZE(sdhci_resource0),
192 .dev = {
193 .platform_data = &tegra_sdhci_platform_data0,
194 },
195};
196
197static struct platform_device tegra_sdhci_device2 = {
198 .name = "sdhci-tegra",
199 .id = 2,
200 .resource = sdhci_resource2,
201 .num_resources = ARRAY_SIZE(sdhci_resource2),
202 .dev = {
203 .platform_data = &tegra_sdhci_platform_data2,
204 },
205};
206
207static struct platform_device tegra_sdhci_device3 = {
208 .name = "sdhci-tegra",
209 .id = 3,
210 .resource = sdhci_resource3,
211 .num_resources = ARRAY_SIZE(sdhci_resource3),
212 .dev = {
213 .platform_data = &tegra_sdhci_platform_data3,
214 },
215};
216
217static int cardhu_wifi_status_register(
218 void (*callback)(int card_present, void *dev_id),
219 void *dev_id)
220{
221 if (wifi_status_cb)
222 return -EAGAIN;
223 wifi_status_cb = callback;
224 wifi_status_cb_devid = dev_id;
225 return 0;
226}
227
228static int cardhu_wifi_set_carddetect(int val)
229{
230 pr_debug("%s: %d\n", __func__, val);
231 if (wifi_status_cb)
232 wifi_status_cb(val, wifi_status_cb_devid);
233 else
234 pr_warning("%s: Nobody to notify\n", __func__);
235 return 0;
236}
237
238static int cardhu_wifi_power(int on)
239{
240 pr_debug("%s: %d\n", __func__, on);
241 gpio_set_value(CARDHU_WLAN_PWR, on);
242 mdelay(100);
243 gpio_set_value(CARDHU_WLAN_RST, on);
244 mdelay(200);
245
246 return 0;
247}
248
249static int cardhu_wifi_reset(int on)
250{
251 pr_debug("%s: do nothing\n", __func__);
252 return 0;
253}
254
255static int __init cardhu_wifi_init(void)
256{
257 int rc;
258
259 rc = gpio_request(CARDHU_WLAN_PWR, "wlan_power");
260 if (rc)
261 pr_err("WLAN_PWR gpio request failed:%d\n", rc);
262 rc = gpio_request(CARDHU_WLAN_RST, "wlan_rst");
263 if (rc)
264 pr_err("WLAN_RST gpio request failed:%d\n", rc);
265 rc = gpio_request(CARDHU_WLAN_WOW, "bcmsdh_sdmmc");
266 if (rc)
267 pr_err("WLAN_WOW gpio request failed:%d\n", rc);
268
269 tegra_gpio_enable(CARDHU_WLAN_PWR);
270 tegra_gpio_enable(CARDHU_WLAN_RST);
271 tegra_gpio_enable(CARDHU_WLAN_WOW);
272
273 rc = gpio_direction_output(CARDHU_WLAN_PWR, 0);
274 if (rc)
275 pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
276 gpio_direction_output(CARDHU_WLAN_RST, 0);
277 if (rc)
278 pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
279 rc = gpio_direction_input(CARDHU_WLAN_WOW);
280 if (rc)
281 pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
282
283 platform_device_register(&cardhu_wifi_device);
284 return 0;
285}
286
287int __init cardhu_sdhci_init(void)
288{
289 struct board_info board_info;
290 tegra_get_board_info(&board_info);
291 if ((board_info.board_id == BOARD_PM269) ||
292 (board_info.board_id == BOARD_E1257) ||
293 (board_info.board_id == BOARD_PM305) ||
294 (board_info.board_id == BOARD_PM311)) {
295 tegra_sdhci_platform_data0.wp_gpio = PM269_SD_WP;
296 tegra_sdhci_platform_data2.max_clk_limit = 12000000;
297 }
298
299 platform_device_register(&tegra_sdhci_device3);
300 platform_device_register(&tegra_sdhci_device2);
301 platform_device_register(&tegra_sdhci_device0);
302
303 //cardhu_wifi_init();
304 return 0;
305}
diff --git a/arch/arm/mach-tegra/board-cardhu-sensors.c b/arch/arm/mach-tegra/board-cardhu-sensors.c
new file mode 100644
index 00000000000..5e39e347993
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-sensors.c
@@ -0,0 +1,1001 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-sensors.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/i2c.h>
35#include <linux/delay.h>
36#include <linux/regulator/consumer.h>
37#include <linux/i2c/pca954x.h>
38#include <linux/i2c/pca953x.h>
39#include <linux/nct1008.h>
40#include <mach/fb.h>
41#include <mach/gpio.h>
42#include <media/ov5650.h>
43#include <media/ov14810.h>
44#include <media/ov2710.h>
45#include <media/tps61050.h>
46#include <generated/mach-types.h>
47#include "gpio-names.h"
48#include "board.h"
49#include <linux/mpu.h>
50#include <media/sh532u.h>
51#include <linux/bq27x00.h>
52#include <mach/gpio.h>
53#include <mach/edp.h>
54#include <mach/thermal.h>
55
56#include "gpio-names.h"
57#include "board-cardhu.h"
58#include "cpu-tegra.h"
59
60static struct regulator *cardhu_1v8_cam1 = NULL;
61static struct regulator *cardhu_1v8_cam2 = NULL;
62static struct regulator *cardhu_1v8_cam3 = NULL;
63static struct regulator *cardhu_vdd_2v8_cam1 = NULL;
64static struct regulator *cardhu_vdd_2v8_cam2 = NULL;
65static struct regulator *cardhu_vdd_cam3 = NULL;
66
67static struct board_info board_info;
68
69static struct pca954x_platform_mode cardhu_pca954x_modes[] = {
70 { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = true, },
71 { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = true, },
72 { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = true, },
73 { .adap_id = PCA954x_I2C_BUS3, .deselect_on_exit = true, },
74};
75
76static struct pca954x_platform_data cardhu_pca954x_data = {
77 .modes = cardhu_pca954x_modes,
78 .num_modes = ARRAY_SIZE(cardhu_pca954x_modes),
79};
80
81static int cardhu_camera_init(void)
82{
83 int ret;
84
85 /* Boards E1198 and E1291 are of Cardhu personality
86 * and donot have TCA6416 exp for camera */
87 if ((board_info.board_id == BOARD_E1198) ||
88 (board_info.board_id == BOARD_E1291)) {
89 tegra_gpio_enable(CAM1_POWER_DWN_GPIO);
90 ret = gpio_request(CAM1_POWER_DWN_GPIO, "camera_power_en");
91 if (ret < 0)
92 pr_err("%s: gpio_request failed for gpio %s\n",
93 __func__, "CAM1_POWER_DWN_GPIO");
94 tegra_gpio_enable(CAM3_POWER_DWN_GPIO);
95 ret = gpio_request(CAM3_POWER_DWN_GPIO, "cam3_power_en");
96 if (ret < 0)
97 pr_err("%s: gpio_request failed for gpio %s\n",
98 __func__, "CAM3_POWER_DWN_GPIO");
99
100 tegra_gpio_enable(CAM2_POWER_DWN_GPIO);
101 ret = gpio_request(CAM2_POWER_DWN_GPIO, "camera2_power_en");
102 if (ret < 0)
103 pr_err("%s: gpio_request failed for gpio %s\n",
104 __func__, "CAM2_POWER_DWN_GPIO");
105
106 tegra_gpio_enable(OV5650_RESETN_GPIO);
107 ret = gpio_request(OV5650_RESETN_GPIO, "camera_reset");
108 if (ret < 0)
109 pr_err("%s: gpio_request failed for gpio %s\n",
110 __func__, "OV5650_RESETN_GPIO");
111
112 gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
113 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
114 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
115 mdelay(10);
116
117 gpio_direction_output(OV5650_RESETN_GPIO, 1);
118 mdelay(5);
119 gpio_direction_output(OV5650_RESETN_GPIO, 0);
120 mdelay(5);
121 gpio_direction_output(OV5650_RESETN_GPIO, 1);
122 mdelay(5);
123 }
124
125 /* To select the CSIB MUX either for cam2 or cam3 */
126 tegra_gpio_enable(CAMERA_CSI_MUX_SEL_GPIO);
127 ret = gpio_request(CAMERA_CSI_MUX_SEL_GPIO, "camera_csi_sel");
128 if (ret < 0)
129 pr_err("%s: gpio_request failed for gpio %s\n",
130 __func__, "CAMERA_CSI_MUX_SEL_GPIO");
131 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0);
132 gpio_export(CAMERA_CSI_MUX_SEL_GPIO, false);
133
134 return 0;
135}
136
137static int cardhu_left_ov5650_power_on(void)
138{
139 /* Boards E1198 and E1291 are of Cardhu personality
140 * and donot have TCA6416 exp for camera */
141 if ((board_info.board_id == BOARD_E1198) ||
142 (board_info.board_id == BOARD_E1291)) {
143
144 if (cardhu_vdd_2v8_cam1 == NULL) {
145 cardhu_vdd_2v8_cam1 = regulator_get(NULL, "vdd_2v8_cam1");
146 if (WARN_ON(IS_ERR(cardhu_vdd_2v8_cam1))) {
147 pr_err("%s: couldn't get regulator vdd_2v8_cam1: %ld\n",
148 __func__, PTR_ERR(cardhu_vdd_2v8_cam1));
149 goto reg_alloc_fail;
150 }
151 }
152 regulator_enable(cardhu_vdd_2v8_cam1);
153 mdelay(5);
154 }
155
156 /* Enable VDD_1V8_Cam1 */
157 if (cardhu_1v8_cam1 == NULL) {
158 cardhu_1v8_cam1 = regulator_get(NULL, "vdd_1v8_cam1");
159 if (WARN_ON(IS_ERR(cardhu_1v8_cam1))) {
160 pr_err("%s: couldn't get regulator vdd_1v8_cam1: %ld\n",
161 __func__, PTR_ERR(cardhu_1v8_cam1));
162 goto reg_alloc_fail;
163 }
164 }
165 regulator_enable(cardhu_1v8_cam1);
166
167 mdelay(5);
168 if ((board_info.board_id == BOARD_E1198) ||
169 (board_info.board_id == BOARD_E1291)) {
170 gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
171 mdelay(20);
172 gpio_direction_output(OV5650_RESETN_GPIO, 0);
173 mdelay(100);
174 gpio_direction_output(OV5650_RESETN_GPIO, 1);
175 }
176
177 if (board_info.board_id == BOARD_PM269) {
178 gpio_direction_output(CAM1_RST_L_GPIO, 0);
179 mdelay(100);
180 gpio_direction_output(CAM1_RST_L_GPIO, 1);
181 }
182
183 return 0;
184
185reg_alloc_fail:
186 if (cardhu_1v8_cam1) {
187 regulator_put(cardhu_1v8_cam1);
188 cardhu_1v8_cam1 = NULL;
189 }
190 if (cardhu_vdd_2v8_cam1) {
191 regulator_put(cardhu_vdd_2v8_cam1);
192 cardhu_vdd_2v8_cam1 = NULL;
193 }
194
195 return -ENODEV;
196
197}
198
199static int cardhu_left_ov5650_power_off(void)
200{
201 /* Boards E1198 and E1291 are of Cardhu personality
202 * and donot have TCA6416 exp for camera */
203 if ((board_info.board_id == BOARD_E1198) ||
204 (board_info.board_id == BOARD_E1291)) {
205 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
206 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
207 gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
208 }
209 if (cardhu_1v8_cam1)
210 regulator_disable(cardhu_1v8_cam1);
211 if (cardhu_vdd_2v8_cam1)
212 regulator_disable(cardhu_vdd_2v8_cam1);
213
214 return 0;
215}
216
217struct ov5650_platform_data cardhu_left_ov5650_data = {
218 .power_on = cardhu_left_ov5650_power_on,
219 .power_off = cardhu_left_ov5650_power_off,
220};
221
222#ifdef CONFIG_VIDEO_OV14810
223static int cardhu_ov14810_power_on(void)
224{
225 if (board_info.board_id == BOARD_E1198) {
226 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
227 mdelay(20);
228 gpio_direction_output(OV14810_RESETN_GPIO, 0);
229 mdelay(100);
230 gpio_direction_output(OV14810_RESETN_GPIO, 1);
231 }
232
233 return 0;
234}
235
236static int cardhu_ov14810_power_off(void)
237{
238 if (board_info.board_id == BOARD_E1198) {
239 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
240 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
241 gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
242 }
243
244 return 0;
245}
246
247struct ov14810_platform_data cardhu_ov14810_data = {
248 .power_on = cardhu_ov14810_power_on,
249 .power_off = cardhu_ov14810_power_off,
250};
251
252struct ov14810_platform_data cardhu_ov14810uC_data = {
253 .power_on = NULL,
254 .power_off = NULL,
255};
256
257struct ov14810_platform_data cardhu_ov14810SlaveDev_data = {
258 .power_on = NULL,
259 .power_off = NULL,
260};
261
262static struct i2c_board_info cardhu_i2c_board_info_e1214[] = {
263 {
264 I2C_BOARD_INFO("ov14810", 0x36),
265 .platform_data = &cardhu_ov14810_data,
266 },
267 {
268 I2C_BOARD_INFO("ov14810uC", 0x67),
269 .platform_data = &cardhu_ov14810uC_data,
270 },
271 {
272 I2C_BOARD_INFO("ov14810SlaveDev", 0x69),
273 .platform_data = &cardhu_ov14810SlaveDev_data,
274 }
275};
276#endif
277
278static int cardhu_right_ov5650_power_on(void)
279{
280 /* CSI-B and front sensor are muxed on cardhu */
281 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0);
282
283 /* Boards E1198 and E1291 are of Cardhu personality
284 * and donot have TCA6416 exp for camera */
285 if ((board_info.board_id == BOARD_E1198) ||
286 (board_info.board_id == BOARD_E1291)) {
287
288 gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
289 gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
290 mdelay(10);
291
292 if (cardhu_vdd_2v8_cam2 == NULL) {
293 cardhu_vdd_2v8_cam2 = regulator_get(NULL, "vdd_2v8_cam2");
294 if (WARN_ON(IS_ERR(cardhu_vdd_2v8_cam2))) {
295 pr_err("%s: couldn't get regulator vdd_2v8_cam2: %ld\n",
296 __func__, PTR_ERR(cardhu_vdd_2v8_cam2));
297 goto reg_alloc_fail;
298 }
299 }
300 regulator_enable(cardhu_vdd_2v8_cam2);
301 mdelay(5);
302 }
303
304 /* Enable VDD_1V8_Cam2 */
305 if (cardhu_1v8_cam2 == NULL) {
306 cardhu_1v8_cam2 = regulator_get(NULL, "vdd_1v8_cam2");
307 if (WARN_ON(IS_ERR(cardhu_1v8_cam2))) {
308 pr_err("%s: couldn't get regulator vdd_1v8_cam2: %ld\n",
309 __func__, PTR_ERR(cardhu_1v8_cam2));
310 goto reg_alloc_fail;
311 }
312 }
313 regulator_enable(cardhu_1v8_cam2);
314
315 mdelay(5);
316
317 if (board_info.board_id == BOARD_PM269) {
318 gpio_direction_output(CAM2_RST_L_GPIO, 0);
319 mdelay(100);
320 gpio_direction_output(CAM2_RST_L_GPIO, 1);
321 }
322
323 return 0;
324
325reg_alloc_fail:
326 if (cardhu_1v8_cam2) {
327 regulator_put(cardhu_1v8_cam2);
328 cardhu_1v8_cam2 = NULL;
329 }
330 if (cardhu_vdd_2v8_cam2) {
331 regulator_put(cardhu_vdd_2v8_cam2);
332 cardhu_vdd_2v8_cam2 = NULL;
333 }
334
335 return -ENODEV;
336
337}
338
339static int cardhu_right_ov5650_power_off(void)
340{
341 /* CSI-B and front sensor are muxed on cardhu */
342 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0);
343
344 /* Boards E1198 and E1291 are of Cardhu personality
345 * and donot have TCA6416 exp for camera */
346 if ((board_info.board_id == BOARD_E1198) ||
347 (board_info.board_id == BOARD_E1291)) {
348 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
349 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
350 gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
351 }
352
353 if (cardhu_1v8_cam2)
354 regulator_disable(cardhu_1v8_cam2);
355 if (cardhu_vdd_2v8_cam2)
356 regulator_disable(cardhu_vdd_2v8_cam2);
357
358 return 0;
359}
360
361static void cardhu_ov5650_synchronize_sensors(void)
362{
363 if (board_info.board_id == BOARD_E1198) {
364 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
365 mdelay(50);
366 gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
367 mdelay(50);
368 }
369 else if (board_info.board_id == BOARD_E1291) {
370 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
371 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
372 mdelay(50);
373 gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
374 gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
375 mdelay(50);
376 }
377 else
378 pr_err("%s: UnSupported BoardId\n", __func__);
379}
380
381struct ov5650_platform_data cardhu_right_ov5650_data = {
382 .power_on = cardhu_right_ov5650_power_on,
383 .power_off = cardhu_right_ov5650_power_off,
384 .synchronize_sensors = cardhu_ov5650_synchronize_sensors,
385};
386
387static int cardhu_ov2710_power_on(void)
388{
389 /* CSI-B and front sensor are muxed on cardhu */
390 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
391
392 /* Boards E1198 and E1291 are of Cardhu personality
393 * and donot have TCA6416 exp for camera */
394 if ((board_info.board_id == BOARD_E1198) ||
395 (board_info.board_id == BOARD_E1291)) {
396
397 gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
398 gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
399 gpio_direction_output(CAM3_POWER_DWN_GPIO, 0);
400 mdelay(10);
401
402 if (cardhu_vdd_cam3 == NULL) {
403 cardhu_vdd_cam3 = regulator_get(NULL, "vdd_cam3");
404 if (WARN_ON(IS_ERR(cardhu_vdd_cam3))) {
405 pr_err("%s: couldn't get regulator vdd_cam3: %ld\n",
406 __func__, PTR_ERR(cardhu_vdd_cam3));
407 goto reg_alloc_fail;
408 }
409 }
410 regulator_enable(cardhu_vdd_cam3);
411 }
412
413 /* Enable VDD_1V8_Cam3 */
414 if (cardhu_1v8_cam3 == NULL) {
415 cardhu_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3");
416 if (WARN_ON(IS_ERR(cardhu_1v8_cam3))) {
417 pr_err("%s: couldn't get regulator vdd_1v8_cam3: %ld\n",
418 __func__, PTR_ERR(cardhu_1v8_cam3));
419 goto reg_alloc_fail;
420 }
421 }
422 regulator_enable(cardhu_1v8_cam3);
423 mdelay(5);
424
425 return 0;
426
427reg_alloc_fail:
428 if (cardhu_1v8_cam3) {
429 regulator_put(cardhu_1v8_cam3);
430 cardhu_1v8_cam3 = NULL;
431 }
432 if (cardhu_vdd_cam3) {
433 regulator_put(cardhu_vdd_cam3);
434 cardhu_vdd_cam3 = NULL;
435 }
436
437 return -ENODEV;
438}
439
440static int cardhu_ov2710_power_off(void)
441{
442 /* CSI-B and front sensor are muxed on cardhu */
443 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
444
445 /* Boards E1198 and E1291 are of Cardhu personality
446 * and donot have TCA6416 exp for camera */
447 if ((board_info.board_id == BOARD_E1198) ||
448 (board_info.board_id == BOARD_E1291)) {
449 gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
450 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
451 gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
452 }
453
454 if (cardhu_1v8_cam3)
455 regulator_disable(cardhu_1v8_cam3);
456 if (cardhu_vdd_cam3)
457 regulator_disable(cardhu_vdd_cam3);
458
459 return 0;
460}
461
462struct ov2710_platform_data cardhu_ov2710_data = {
463 .power_on = cardhu_ov2710_power_on,
464 .power_off = cardhu_ov2710_power_off,
465};
466
467static const struct i2c_board_info cardhu_i2c3_board_info[] = {
468 {
469 I2C_BOARD_INFO("pca9546", 0x70),
470 .platform_data = &cardhu_pca954x_data,
471 },
472};
473
474static struct sh532u_platform_data sh532u_left_pdata = {
475 .num = 1,
476 .sync = 2,
477 .dev_name = "focuser",
478 .gpio_reset = TEGRA_GPIO_PBB0,
479};
480
481static struct sh532u_platform_data sh532u_right_pdata = {
482 .num = 2,
483 .sync = 1,
484 .dev_name = "focuser",
485 .gpio_reset = TEGRA_GPIO_PBB0,
486};
487
488static struct sh532u_platform_data pm269_sh532u_left_pdata = {
489 .num = 1,
490 .sync = 2,
491 .dev_name = "focuser",
492 .gpio_reset = CAM1_RST_L_GPIO,
493};
494
495static struct sh532u_platform_data pm269_sh532u_right_pdata = {
496 .num = 2,
497 .sync = 1,
498 .dev_name = "focuser",
499 .gpio_reset = CAM2_RST_L_GPIO,
500};
501
502static struct nvc_torch_pin_state cardhu_tps61050_pinstate = {
503 .mask = 0x0008, /*VGP3*/
504 .values = 0x0008,
505};
506
507static struct tps61050_platform_data cardhu_tps61050_pdata = {
508 .dev_name = "torch",
509 .pinstate = &cardhu_tps61050_pinstate,
510};
511
512static const struct i2c_board_info cardhu_i2c_board_info_tps61050[] = {
513 {
514 I2C_BOARD_INFO("tps61050", 0x33),
515 .platform_data = &cardhu_tps61050_pdata,
516 },
517};
518
519static struct i2c_board_info cardhu_i2c6_board_info[] = {
520 {
521 I2C_BOARD_INFO("ov5650L", 0x36),
522 .platform_data = &cardhu_left_ov5650_data,
523 },
524 {
525 I2C_BOARD_INFO("sh532u", 0x72),
526 .platform_data = &sh532u_left_pdata,
527 },
528};
529
530static struct i2c_board_info cardhu_i2c7_board_info[] = {
531 {
532 I2C_BOARD_INFO("ov5650R", 0x36),
533 .platform_data = &cardhu_right_ov5650_data,
534 },
535 {
536 I2C_BOARD_INFO("sh532u", 0x72),
537 .platform_data = &sh532u_right_pdata,
538 },
539};
540
541static struct i2c_board_info pm269_i2c6_board_info[] = {
542 {
543 I2C_BOARD_INFO("ov5650L", 0x36),
544 .platform_data = &cardhu_left_ov5650_data,
545 },
546 {
547 I2C_BOARD_INFO("sh532u", 0x72),
548 .platform_data = &pm269_sh532u_left_pdata,
549 },
550};
551
552static struct i2c_board_info pm269_i2c7_board_info[] = {
553 {
554 I2C_BOARD_INFO("ov5650R", 0x36),
555 .platform_data = &cardhu_right_ov5650_data,
556 },
557 {
558 I2C_BOARD_INFO("sh532u", 0x72),
559 .platform_data = &pm269_sh532u_right_pdata,
560 },
561};
562
563static struct i2c_board_info cardhu_i2c8_board_info[] = {
564 {
565 I2C_BOARD_INFO("ov2710", 0x36),
566 .platform_data = &cardhu_ov2710_data,
567 },
568};
569
570static int nct_get_temp(void *_data, long *temp)
571{
572 struct nct1008_data *data = _data;
573 return nct1008_thermal_get_temp(data, temp);
574}
575
576static int nct_get_temp_low(void *_data, long *temp)
577{
578 struct nct1008_data *data = _data;
579 return nct1008_thermal_get_temp_low(data, temp);
580}
581
582static int nct_set_limits(void *_data,
583 long lo_limit_milli,
584 long hi_limit_milli)
585{
586 struct nct1008_data *data = _data;
587 return nct1008_thermal_set_limits(data,
588 lo_limit_milli,
589 hi_limit_milli);
590}
591
592static int nct_set_alert(void *_data,
593 void (*alert_func)(void *),
594 void *alert_data)
595{
596 struct nct1008_data *data = _data;
597 return nct1008_thermal_set_alert(data, alert_func, alert_data);
598}
599
600static int nct_set_shutdown_temp(void *_data, long shutdown_temp)
601{
602 struct nct1008_data *data = _data;
603 return nct1008_thermal_set_shutdown_temp(data, shutdown_temp);
604}
605
606static void nct1008_probe_callback(struct nct1008_data *data)
607{
608 struct tegra_thermal_device *thermal_device;
609
610 thermal_device = kzalloc(sizeof(struct tegra_thermal_device),
611 GFP_KERNEL);
612 if (!thermal_device) {
613 pr_err("unable to allocate thermal device\n");
614 return;
615 }
616
617 thermal_device->name = "nct1008";
618 thermal_device->data = data;
619 thermal_device->offset = TDIODE_OFFSET;
620 thermal_device->get_temp = nct_get_temp;
621 thermal_device->get_temp_low = nct_get_temp_low;
622 thermal_device->set_limits = nct_set_limits;
623 thermal_device->set_alert = nct_set_alert;
624 thermal_device->set_shutdown_temp = nct_set_shutdown_temp;
625
626 tegra_thermal_set_device(thermal_device);
627}
628
629static struct nct1008_platform_data cardhu_nct1008_pdata = {
630 .supported_hwrev = true,
631 .ext_range = true,
632 .conv_rate = 0x08,
633 .offset = 8, /* 4 * 2C. Bug 844025 - 1C for device accuracies */
634 .probe_callback = nct1008_probe_callback,
635};
636
637static struct i2c_board_info cardhu_i2c4_bq27510_board_info[] = {
638 {
639 I2C_BOARD_INFO("bq27510", 0x55),
640 },
641};
642
643static struct i2c_board_info cardhu_i2c4_nct1008_board_info[] = {
644 {
645 I2C_BOARD_INFO("nct1008", 0x4C),
646 .platform_data = &cardhu_nct1008_pdata,
647 .irq = -1,
648 }
649};
650
651static int cardhu_nct1008_init(void)
652{
653 int nct1008_port = -1;
654 int ret = 0;
655
656 if ((board_info.board_id == BOARD_E1198) ||
657 (board_info.board_id == BOARD_E1291) ||
658 (board_info.board_id == BOARD_E1257) ||
659 (board_info.board_id == BOARD_PM269) ||
660 (board_info.board_id == BOARD_PM305) ||
661 (board_info.board_id == BOARD_PM311)) {
662 nct1008_port = TEGRA_GPIO_PN6;
663 } else if ((board_info.board_id == BOARD_E1186) ||
664 (board_info.board_id == BOARD_E1187) ||
665 (board_info.board_id == BOARD_E1256)) {
666 /* FIXME: seems to be conflicting with usb3 vbus on E1186 */
667 /* nct1008_port = TEGRA_GPIO_PH7; */
668 }
669
670 if (nct1008_port >= 0) {
671 /* FIXME: enable irq when throttling is supported */
672 cardhu_i2c4_nct1008_board_info[0].irq = TEGRA_GPIO_TO_IRQ(nct1008_port);
673
674 ret = gpio_request(nct1008_port, "temp_alert");
675 if (ret < 0)
676 return ret;
677
678 ret = gpio_direction_input(nct1008_port);
679 if (ret < 0)
680 gpio_free(nct1008_port);
681 else
682 tegra_gpio_enable(nct1008_port);
683 }
684
685 return ret;
686}
687
688#if defined(CONFIG_GPIO_PCA953X)
689static struct pca953x_platform_data cardhu_pmu_tca6416_data = {
690 .gpio_base = PMU_TCA6416_GPIO_BASE,
691};
692
693static const struct i2c_board_info cardhu_i2c4_board_info_tca6416[] = {
694 {
695 I2C_BOARD_INFO("tca6416", 0x20),
696 .platform_data = &cardhu_pmu_tca6416_data,
697 },
698};
699
700static struct pca953x_platform_data cardhu_cam_tca6416_data = {
701 .gpio_base = CAM_TCA6416_GPIO_BASE,
702};
703
704static const struct i2c_board_info cardhu_i2c2_board_info_tca6416[] = {
705 {
706 I2C_BOARD_INFO("tca6416", 0x20),
707 .platform_data = &cardhu_cam_tca6416_data,
708 },
709};
710
711static int __init pmu_tca6416_init(void)
712{
713 if ((board_info.board_id == BOARD_E1198) ||
714 (board_info.board_id == BOARD_E1291))
715 return 0;
716
717 pr_info("Registering pmu pca6416\n");
718 i2c_register_board_info(4, cardhu_i2c4_board_info_tca6416,
719 ARRAY_SIZE(cardhu_i2c4_board_info_tca6416));
720 return 0;
721}
722
723static int __init cam_tca6416_init(void)
724{
725 /* Boards E1198 and E1291 are of Cardhu personality
726 * and donot have TCA6416 exp for camera */
727 if ((board_info.board_id == BOARD_E1198) ||
728 (board_info.board_id == BOARD_E1291))
729 return 0;
730
731 pr_info("Registering cam pca6416\n");
732 i2c_register_board_info(2, cardhu_i2c2_board_info_tca6416,
733 ARRAY_SIZE(cardhu_i2c2_board_info_tca6416));
734 return 0;
735}
736#else
737static int __init pmu_tca6416_init(void)
738{
739 return 0;
740}
741
742static int __init cam_tca6416_init(void)
743{
744 return 0;
745}
746#endif
747
748/* MPU board file definition */
749#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
750#define MPU_GYRO_NAME "mpu3050"
751#endif
752#if (MPU_GYRO_TYPE == MPU_TYPE_MPU6050)
753#define MPU_GYRO_NAME "mpu6050"
754#endif
755static struct mpu_platform_data mpu_gyro_data = {
756 .int_config = 0x10,
757 .level_shifter = 0,
758 .orientation = MPU_GYRO_ORIENTATION, /* Located in board_[platformname].h */
759};
760
761#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
762static struct ext_slave_platform_data mpu_accel_data = {
763 .address = MPU_ACCEL_ADDR,
764 .irq = 0,
765 .adapt_num = MPU_ACCEL_BUS_NUM,
766 .bus = EXT_SLAVE_BUS_SECONDARY,
767 .orientation = MPU_ACCEL_ORIENTATION, /* Located in board_[platformname].h */
768};
769#endif
770
771static struct ext_slave_platform_data mpu_compass_data = {
772 .address = MPU_COMPASS_ADDR,
773 .irq = 0,
774 .adapt_num = MPU_COMPASS_BUS_NUM,
775 .bus = EXT_SLAVE_BUS_PRIMARY,
776 .orientation = MPU_COMPASS_ORIENTATION, /* Located in board_[platformname].h */
777};
778
779static struct i2c_board_info __initdata inv_mpu_i2c2_board_info[] = {
780 {
781 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
782 .irq = TEGRA_GPIO_TO_IRQ(MPU_GYRO_IRQ_GPIO),
783 .platform_data = &mpu_gyro_data,
784 },
785#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
786 {
787 I2C_BOARD_INFO(MPU_ACCEL_NAME, MPU_ACCEL_ADDR),
788#if MPU_ACCEL_IRQ_GPIO
789 .irq = TEGRA_GPIO_TO_IRQ(MPU_ACCEL_IRQ_GPIO),
790#endif
791 .platform_data = &mpu_accel_data,
792 },
793#endif
794 {
795 I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
796#if MPU_COMPASS_IRQ_GPIO
797 .irq = TEGRA_GPIO_TO_IRQ(MPU_COMPASS_IRQ_GPIO),
798#endif
799 .platform_data = &mpu_compass_data,
800 },
801};
802
803static void mpuirq_init(void)
804{
805 int ret = 0;
806
807 pr_info("*** MPU START *** mpuirq_init...\n");
808
809#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
810#if MPU_ACCEL_IRQ_GPIO
811 /* ACCEL-IRQ assignment */
812 tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
813 ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
814 if (ret < 0) {
815 pr_err("%s: gpio_request failed %d\n", __func__, ret);
816 return;
817 }
818
819 ret = gpio_direction_input(MPU_ACCEL_IRQ_GPIO);
820 if (ret < 0) {
821 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
822 gpio_free(MPU_ACCEL_IRQ_GPIO);
823 return;
824 }
825#endif
826#endif
827
828 /* MPU-IRQ assignment */
829 tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
830 ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
831 if (ret < 0) {
832 pr_err("%s: gpio_request failed %d\n", __func__, ret);
833 return;
834 }
835
836 ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO);
837 if (ret < 0) {
838 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
839 gpio_free(MPU_GYRO_IRQ_GPIO);
840 return;
841 }
842 pr_info("*** MPU END *** mpuirq_init...\n");
843
844 i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c2_board_info,
845 ARRAY_SIZE(inv_mpu_i2c2_board_info));
846}
847
848static struct i2c_board_info cardhu_i2c2_isl_board_info[] = {
849 {
850 I2C_BOARD_INFO("isl29028", 0x44),
851 }
852};
853
854static struct i2c_board_info cardhu_i2c2_ltr_board_info[] = {
855 {
856 I2C_BOARD_INFO("LTR_558ALS", 0x23),
857 }
858};
859
860int __init cardhu_sensors_init(void)
861{
862 int err;
863
864 tegra_get_board_info(&board_info);
865
866 //cardhu_camera_init();
867 //cam_tca6416_init();
868
869 //i2c_register_board_info(2, cardhu_i2c3_board_info,
870 // ARRAY_SIZE(cardhu_i2c3_board_info));
871
872 //i2c_register_board_info(2, cardhu_i2c_board_info_tps61050,
873 // ARRAY_SIZE(cardhu_i2c_board_info_tps61050));
874
875#if 0 // DIFFERENT CAMERA INITIALIZATION ON CARMA BOARD
876#ifdef CONFIG_VIDEO_OV14810
877 /* This is disabled by default; To enable this change Kconfig;
878 * there should be some way to detect dynamically which board
879 * is connected (E1211/E1214), till that time sensor selection
880 * logic is static;
881 * e1214 corresponds to ov14810 sensor */
882 i2c_register_board_info(2, cardhu_i2c_board_info_e1214,
883 ARRAY_SIZE(cardhu_i2c_board_info_e1214));
884#else
885 /* Left camera is on PCA954x's I2C BUS0, Right camera is on BUS1 &
886 * Front camera is on BUS2 */
887 if (board_info.board_id != BOARD_PM269) {
888 i2c_register_board_info(PCA954x_I2C_BUS0,
889 cardhu_i2c6_board_info,
890 ARRAY_SIZE(cardhu_i2c6_board_info));
891
892 i2c_register_board_info(PCA954x_I2C_BUS1,
893 cardhu_i2c7_board_info,
894 ARRAY_SIZE(cardhu_i2c7_board_info));
895 } else {
896 i2c_register_board_info(PCA954x_I2C_BUS0,
897 pm269_i2c6_board_info,
898 ARRAY_SIZE(pm269_i2c6_board_info));
899
900 i2c_register_board_info(PCA954x_I2C_BUS1,
901 pm269_i2c7_board_info,
902 ARRAY_SIZE(pm269_i2c7_board_info));
903 }
904 i2c_register_board_info(PCA954x_I2C_BUS2, cardhu_i2c8_board_info,
905 ARRAY_SIZE(cardhu_i2c8_board_info));
906
907#endif
908#endif
909 //pmu_tca6416_init();
910
911 //if (board_info.board_id == BOARD_E1291)
912 // i2c_register_board_info(4, cardhu_i2c4_bq27510_board_info,
913 // ARRAY_SIZE(cardhu_i2c4_bq27510_board_info));
914
915 //if (board_info.sku == BOARD_SKU_B11)
916 // i2c_register_board_info(2, cardhu_i2c2_ltr_board_info,
917 // ARRAY_SIZE(cardhu_i2c2_ltr_board_info));
918 //else
919 // i2c_register_board_info(2, cardhu_i2c2_isl_board_info,
920 // ARRAY_SIZE(cardhu_i2c2_isl_board_info));
921
922 err = cardhu_nct1008_init();
923 if (err)
924 return err;
925
926 i2c_register_board_info(1, cardhu_i2c4_nct1008_board_info,
927 ARRAY_SIZE(cardhu_i2c4_nct1008_board_info));
928
929 mpuirq_init();
930 return 0;
931}
932
933#if defined(CONFIG_GPIO_PCA953X)
934struct ov5650_gpios {
935 const char *name;
936 int gpio;
937 int enabled;
938};
939
940#define OV5650_GPIO(_name, _gpio, _enabled) \
941 { \
942 .name = _name, \
943 .gpio = _gpio, \
944 .enabled = _enabled, \
945 }
946
947static struct ov5650_gpios ov5650_gpio_keys[] = {
948 [0] = OV5650_GPIO("cam1_pwdn", CAM1_PWR_DN_GPIO, 0),
949 [1] = OV5650_GPIO("cam1_rst_lo", CAM1_RST_L_GPIO, 1),
950 [2] = OV5650_GPIO("cam1_af_pwdn_lo", CAM1_AF_PWR_DN_L_GPIO, 0),
951 [3] = OV5650_GPIO("cam1_ldo_shdn_lo", CAM1_LDO_SHUTDN_L_GPIO, 1),
952 [4] = OV5650_GPIO("cam2_pwdn", CAM2_PWR_DN_GPIO, 0),
953 [5] = OV5650_GPIO("cam2_rst_lo", CAM2_RST_L_GPIO, 1),
954 [6] = OV5650_GPIO("cam2_af_pwdn_lo", CAM2_AF_PWR_DN_L_GPIO, 0),
955 [7] = OV5650_GPIO("cam2_ldo_shdn_lo", CAM2_LDO_SHUTDN_L_GPIO, 1),
956 [8] = OV5650_GPIO("cam3_pwdn", CAM_FRONT_PWR_DN_GPIO, 0),
957 [9] = OV5650_GPIO("cam3_rst_lo", CAM_FRONT_RST_L_GPIO, 1),
958 [10] = OV5650_GPIO("cam3_af_pwdn_lo", CAM_FRONT_AF_PWR_DN_L_GPIO, 0),
959 [11] = OV5650_GPIO("cam3_ldo_shdn_lo", CAM_FRONT_LDO_SHUTDN_L_GPIO, 1),
960 [12] = OV5650_GPIO("cam_led_exp", CAM_FRONT_LED_EXP, 1),
961 [13] = OV5650_GPIO("cam_led_rear_exp", CAM_SNN_LED_REAR_EXP, 1),
962 [14] = OV5650_GPIO("cam_i2c_mux_rst", CAM_I2C_MUX_RST_EXP, 1),
963};
964
965int __init cardhu_ov5650_late_init(void)
966{
967 int ret;
968 int i;
969
970 if (!machine_is_cardhu())
971 return 0;
972
973 if ((board_info.board_id == BOARD_E1198) ||
974 (board_info.board_id == BOARD_E1291))
975 return 0;
976
977 printk("%s: \n", __func__);
978 for (i = 0; i < ARRAY_SIZE(ov5650_gpio_keys); i++) {
979 ret = gpio_request(ov5650_gpio_keys[i].gpio,
980 ov5650_gpio_keys[i].name);
981 if (ret < 0) {
982 printk("%s: gpio_request failed for gpio #%d\n",
983 __func__, i);
984 goto fail;
985 }
986 printk("%s: enable - %d\n", __func__, i);
987 gpio_direction_output(ov5650_gpio_keys[i].gpio,
988 ov5650_gpio_keys[i].enabled);
989 gpio_export(ov5650_gpio_keys[i].gpio, false);
990 }
991
992 return 0;
993
994fail:
995 while (i--)
996 gpio_free(ov5650_gpio_keys[i].gpio);
997 return ret;
998}
999
1000late_initcall(cardhu_ov5650_late_init);
1001#endif
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
new file mode 100644
index 00000000000..6001dae7c10
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -0,0 +1,1230 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu.c
3 *
4 * Copyright (c) 2011-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/serial_8250.h>
28#include <linux/i2c.h>
29#include <linux/i2c/panjit_ts.h>
30#include <linux/dma-mapping.h>
31#include <linux/delay.h>
32#include <linux/i2c-tegra.h>
33#include <linux/gpio.h>
34#include <linux/input.h>
35#include <linux/platform_data/tegra_usb.h>
36#include <linux/spi/spi.h>
37#include <linux/i2c/atmel_mxt_ts.h>
38#include <linux/tegra_uart.h>
39#include <linux/memblock.h>
40#include <linux/spi-tegra.h>
41#include <linux/nfc/pn544.h>
42
43#include <sound/wm8903.h>
44#include <sound/max98095.h>
45#include <media/tegra_dtv.h>
46
47#include <mach/clk.h>
48#include <mach/iomap.h>
49#include <mach/irqs.h>
50#include <mach/pinmux.h>
51#include <mach/iomap.h>
52#include <mach/io.h>
53#include <mach/i2s.h>
54#include <mach/tegra_asoc_pdata.h>
55#include <mach/tegra_wm8903_pdata.h>
56#include <asm/mach-types.h>
57#include <asm/mach/arch.h>
58#include <mach/usb_phy.h>
59#include <mach/thermal.h>
60#include <mach/pci.h>
61
62#include "board.h"
63#include "clock.h"
64#include "board-cardhu.h"
65#include "devices.h"
66#include "gpio-names.h"
67#include "fuse.h"
68#include "pm.h"
69#include "baseband-xmm-power.h"
70#include "wdt-recovery.h"
71
72#define PEX_EN TEGRA_GPIO_PQ0
73
74/* All units are in millicelsius */
75static struct tegra_thermal_data thermal_data = {
76 .temp_throttle = 85000,
77 .temp_shutdown = 90000,
78 .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */
79#ifdef CONFIG_TEGRA_EDP_LIMITS
80 .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */
81 .hysteresis_edp = 3000,
82#endif
83#ifdef CONFIG_TEGRA_THERMAL_SYSFS
84 .tc1 = 0,
85 .tc2 = 1,
86 .passive_delay = 2000,
87#else
88 .hysteresis_throttle = 1000,
89#endif
90};
91
92/* !!!TODO: Change for cardhu (Taken from Ventana) */
93static struct tegra_utmip_config utmi_phy_config[] = {
94 [0] = {
95 .hssync_start_delay = 0,
96 .idle_wait_delay = 17,
97 .elastic_limit = 16,
98 .term_range_adj = 6,
99 .xcvr_setup = 15,
100 .xcvr_setup_offset = 0,
101 .xcvr_use_fuses = 1,
102 .xcvr_lsfslew = 2,
103 .xcvr_lsrslew = 2,
104 },
105 [1] = {
106 .hssync_start_delay = 0,
107 .idle_wait_delay = 17,
108 .elastic_limit = 16,
109 .term_range_adj = 6,
110 .xcvr_setup = 15,
111 .xcvr_setup_offset = 0,
112 .xcvr_use_fuses = 1,
113 .xcvr_lsfslew = 2,
114 .xcvr_lsrslew = 2,
115 },
116 [2] = {
117 .hssync_start_delay = 0,
118 .idle_wait_delay = 17,
119 .elastic_limit = 16,
120 .term_range_adj = 6,
121 .xcvr_setup = 8,
122 .xcvr_setup_offset = 0,
123 .xcvr_use_fuses = 1,
124 .xcvr_lsfslew = 2,
125 .xcvr_lsrslew = 2,
126 },
127};
128
129static struct resource cardhu_bcm4329_rfkill_resources[] = {
130 {
131 .name = "bcm4329_nshutdown_gpio",
132 .start = TEGRA_GPIO_PU0,
133 .end = TEGRA_GPIO_PU0,
134 .flags = IORESOURCE_IO,
135 },
136};
137
138static struct platform_device cardhu_bcm4329_rfkill_device = {
139 .name = "bcm4329_rfkill",
140 .id = -1,
141 .num_resources = ARRAY_SIZE(cardhu_bcm4329_rfkill_resources),
142 .resource = cardhu_bcm4329_rfkill_resources,
143};
144
145static struct resource cardhu_bluesleep_resources[] = {
146 [0] = {
147 .name = "gpio_host_wake",
148 .start = TEGRA_GPIO_PU6,
149 .end = TEGRA_GPIO_PU6,
150 .flags = IORESOURCE_IO,
151 },
152 [1] = {
153 .name = "gpio_ext_wake",
154 .start = TEGRA_GPIO_PU1,
155 .end = TEGRA_GPIO_PU1,
156 .flags = IORESOURCE_IO,
157 },
158 [2] = {
159 .name = "host_wake",
160 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
161 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
162 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
163 },
164};
165
166static struct platform_device cardhu_bluesleep_device = {
167 .name = "bluesleep",
168 .id = -1,
169 .num_resources = ARRAY_SIZE(cardhu_bluesleep_resources),
170 .resource = cardhu_bluesleep_resources,
171};
172
173static noinline void __init cardhu_setup_bluesleep(void)
174{
175 platform_device_register(&cardhu_bluesleep_device);
176 tegra_gpio_enable(TEGRA_GPIO_PU6);
177 tegra_gpio_enable(TEGRA_GPIO_PU1);
178 return;
179}
180
181static __initdata struct tegra_clk_init_table cardhu_clk_init_table[] = {
182 /* name parent rate enabled */
183 { "pll_m", NULL, 0, false},
184 { "hda", "pll_p", 108000000, false},
185 { "hda2codec_2x","pll_p", 48000000, false},
186 { "pwm", "pll_p", 3187500, false},
187 { "blink", "clk_32k", 32768, true},
188 { "i2s0", "pll_a_out0", 0, false},
189 { "i2s1", "pll_a_out0", 0, false},
190 { "i2s3", "pll_a_out0", 0, false},
191 { "spdif_out", "pll_a_out0", 0, false},
192 { "d_audio", "clk_m", 12000000, false},
193 { "dam0", "clk_m", 12000000, false},
194 { "dam1", "clk_m", 12000000, false},
195 { "dam2", "clk_m", 12000000, false},
196 { "audio1", "i2s1_sync", 0, false},
197 { "audio3", "i2s3_sync", 0, false},
198 { "vi_sensor", "pll_p", 150000000, false},
199 { "i2c1", "pll_p", 3200000, false},
200 { "i2c2", "pll_p", 3200000, false},
201 { "i2c3", "pll_p", 3200000, false},
202 { "i2c4", "pll_p", 3200000, false},
203 { "i2c5", "pll_p", 3200000, false},
204 { NULL, NULL, 0, 0},
205};
206
207static struct pn544_i2c_platform_data nfc_pdata = {
208 .irq_gpio = TEGRA_GPIO_PX0,
209 .ven_gpio = TEGRA_GPIO_PP3,
210 .firm_gpio = TEGRA_GPIO_PO7,
211 };
212
213static struct i2c_board_info __initdata cardhu_i2c_bus3_board_info[] = {
214 {
215 I2C_BOARD_INFO("pn544", 0x28),
216 .platform_data = &nfc_pdata,
217 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PX0),
218 },
219};
220static struct tegra_i2c_platform_data cardhu_i2c1_platform_data = {
221 .adapter_nr = 0,
222 .bus_count = 1,
223 .bus_clk_rate = { 100000, 0 },
224 .scl_gpio = {TEGRA_GPIO_PC4, 0},
225 .sda_gpio = {TEGRA_GPIO_PC5, 0},
226 .arb_recovery = arb_lost_recovery,
227};
228
229static struct tegra_i2c_platform_data cardhu_i2c2_platform_data = {
230 .adapter_nr = 1,
231 .bus_count = 1,
232 .bus_clk_rate = { 100000, 0 },
233 .is_clkon_always = true,
234 .scl_gpio = {TEGRA_GPIO_PT5, 0},
235 .sda_gpio = {TEGRA_GPIO_PT6, 0},
236 .arb_recovery = arb_lost_recovery,
237};
238
239static struct tegra_i2c_platform_data cardhu_i2c3_platform_data = {
240 .adapter_nr = 2,
241 .bus_count = 1,
242 .bus_clk_rate = { 100000, 0 },
243 .scl_gpio = {TEGRA_GPIO_PBB1, 0},
244 .sda_gpio = {TEGRA_GPIO_PBB2, 0},
245 .arb_recovery = arb_lost_recovery,
246};
247
248static struct tegra_i2c_platform_data cardhu_i2c4_platform_data = {
249 .adapter_nr = 3,
250 .bus_count = 1,
251 .bus_clk_rate = { 100000, 0 },
252 .scl_gpio = {TEGRA_GPIO_PV4, 0},
253 .sda_gpio = {TEGRA_GPIO_PV5, 0},
254 .arb_recovery = arb_lost_recovery,
255};
256
257static struct tegra_i2c_platform_data cardhu_i2c5_platform_data = {
258 .adapter_nr = 4,
259 .bus_count = 1,
260 .bus_clk_rate = { 400000, 0 },
261 .scl_gpio = {TEGRA_GPIO_PZ6, 0},
262 .sda_gpio = {TEGRA_GPIO_PZ7, 0},
263 .arb_recovery = arb_lost_recovery,
264};
265
266
267#if 0
268struct tegra_wired_jack_conf audio_wr_jack_conf = {
269 .hp_det_n = TEGRA_GPIO_PW2,
270 .en_mic_ext = TEGRA_GPIO_PX1,
271 .en_mic_int = TEGRA_GPIO_PX0,
272};
273#endif
274
275static struct wm8903_platform_data cardhu_wm8903_pdata = {
276 .irq_active_low = 0,
277 .micdet_cfg = 0,
278 .micdet_delay = 100,
279 .gpio_base = CARDHU_GPIO_WM8903(0),
280 .gpio_cfg = {
281 (WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT << WM8903_GP1_FN_SHIFT),
282 (WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT << WM8903_GP2_FN_SHIFT) |
283 WM8903_GP2_DIR,
284 0,
285 WM8903_GPIO_NO_CONFIG,
286 WM8903_GPIO_NO_CONFIG,
287 },
288};
289
290/* Equalizer filter coefs generated from the MAXIM MAX98095
291 * evkit software tool */
292static struct max98095_eq_cfg max98095_eq_cfg[] = {
293 {
294 .name = "FLAT",
295 .rate = 44100,
296 .band1 = {0x2000, 0xC002, 0x4000, 0x00E9, 0x0000},
297 .band2 = {0x2000, 0xC00F, 0x4000, 0x02BC, 0x0000},
298 .band3 = {0x2000, 0xC0A7, 0x4000, 0x0916, 0x0000},
299 .band4 = {0x2000, 0xC5C2, 0x4000, 0x1A87, 0x0000},
300 .band5 = {0x2000, 0xF6B0, 0x4000, 0x3F51, 0x0000},
301 },
302 {
303 .name = "LOWPASS1K",
304 .rate = 44100,
305 .band1 = {0x205D, 0xC001, 0x3FEF, 0x002E, 0x02E0},
306 .band2 = {0x5B9A, 0xC093, 0x3AB2, 0x088B, 0x1981},
307 .band3 = {0x0D22, 0xC170, 0x26EA, 0x0D79, 0x32CF},
308 .band4 = {0x0894, 0xC612, 0x01B3, 0x1B34, 0x3FFA},
309 .band5 = {0x0815, 0x3FFF, 0xCF78, 0x0000, 0x29B7},
310 },
311 { /* BASS=-12dB, TREBLE=+9dB, Fc=5KHz */
312 .name = "HIBOOST",
313 .rate = 44100,
314 .band1 = {0x0815, 0xC001, 0x3AA4, 0x0003, 0x19A2},
315 .band2 = {0x0815, 0xC103, 0x092F, 0x0B55, 0x3F56},
316 .band3 = {0x0E0A, 0xC306, 0x1E5C, 0x136E, 0x3856},
317 .band4 = {0x2459, 0xF665, 0x0CAA, 0x3F46, 0x3EBB},
318 .band5 = {0x5BBB, 0x3FFF, 0xCEB0, 0x0000, 0x28CA},
319 },
320 { /* BASS=12dB, TREBLE=+12dB */
321 .name = "LOUD12DB",
322 .rate = 44100,
323 .band1 = {0x7FC1, 0xC001, 0x3EE8, 0x0020, 0x0BC7},
324 .band2 = {0x51E9, 0xC016, 0x3C7C, 0x033F, 0x14E9},
325 .band3 = {0x1745, 0xC12C, 0x1680, 0x0C2F, 0x3BE9},
326 .band4 = {0x4536, 0xD7E2, 0x0ED4, 0x31DD, 0x3E42},
327 .band5 = {0x7FEF, 0x3FFF, 0x0BAB, 0x0000, 0x3EED},
328 },
329 {
330 .name = "FLAT",
331 .rate = 16000,
332 .band1 = {0x2000, 0xC004, 0x4000, 0x0141, 0x0000},
333 .band2 = {0x2000, 0xC033, 0x4000, 0x0505, 0x0000},
334 .band3 = {0x2000, 0xC268, 0x4000, 0x115F, 0x0000},
335 .band4 = {0x2000, 0xDA62, 0x4000, 0x33C6, 0x0000},
336 .band5 = {0x2000, 0x4000, 0x4000, 0x0000, 0x0000},
337 },
338 {
339 .name = "LOWPASS1K",
340 .rate = 16000,
341 .band1 = {0x2000, 0xC004, 0x4000, 0x0141, 0x0000},
342 .band2 = {0x5BE8, 0xC3E0, 0x3307, 0x15ED, 0x26A0},
343 .band3 = {0x0F71, 0xD15A, 0x08B3, 0x2BD0, 0x3F67},
344 .band4 = {0x0815, 0x3FFF, 0xCF78, 0x0000, 0x29B7},
345 .band5 = {0x0815, 0x3FFF, 0xCF78, 0x0000, 0x29B7},
346 },
347 { /* BASS=-12dB, TREBLE=+9dB, Fc=2KHz */
348 .name = "HIBOOST",
349 .rate = 16000,
350 .band1 = {0x0815, 0xC001, 0x3BD2, 0x0009, 0x16BF},
351 .band2 = {0x080E, 0xC17E, 0xF653, 0x0DBD, 0x3F43},
352 .band3 = {0x0F80, 0xDF45, 0xEE33, 0x36FE, 0x3D79},
353 .band4 = {0x590B, 0x3FF0, 0xE882, 0x02BD, 0x3B87},
354 .band5 = {0x4C87, 0xF3D0, 0x063F, 0x3ED4, 0x3FB1},
355 },
356 { /* BASS=12dB, TREBLE=+12dB */
357 .name = "LOUD12DB",
358 .rate = 16000,
359 .band1 = {0x7FC1, 0xC001, 0x3D07, 0x0058, 0x1344},
360 .band2 = {0x2DA6, 0xC013, 0x3CF1, 0x02FF, 0x138B},
361 .band3 = {0x18F1, 0xC08E, 0x244D, 0x0863, 0x34B5},
362 .band4 = {0x2BE0, 0xF385, 0x04FD, 0x3EC5, 0x3FCE},
363 .band5 = {0x7FEF, 0x4000, 0x0BAB, 0x0000, 0x3EED},
364 },
365};
366
367static struct max98095_pdata cardhu_max98095_pdata = {
368 /* equalizer configuration */
369 .eq_cfg = max98095_eq_cfg,
370 .eq_cfgcnt = ARRAY_SIZE(max98095_eq_cfg),
371
372 /* Biquad filter response configuration */
373 .bq_cfg = NULL,
374 .bq_cfgcnt = 0,
375
376 /* microphone configuration */
377 .digmic_left_mode = 1,
378 .digmic_right_mode = 1,
379};
380
381static struct i2c_board_info __initdata cardhu_codec_wm8903_info = {
382 I2C_BOARD_INFO("wm8903", 0x1a),
383 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
384 .platform_data = &cardhu_wm8903_pdata,
385};
386
387static struct i2c_board_info __initdata cardhu_codec_aic326x_info = {
388 I2C_BOARD_INFO("aic3262-codec", 0x18),
389 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
390};
391
392static struct i2c_board_info __initdata cardhu_codec_max98095_info = {
393 I2C_BOARD_INFO("max98095", 0x10),
394 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
395 .platform_data = &cardhu_max98095_pdata,
396};
397
398// Configura il pinmux come gpio di output e asserisce il reset del codec
399static void hda_init(void)
400{
401 int rc;
402 rc = gpio_request(HDA_RESET, "hda_reset");
403 if (rc)
404 pr_err("HDA_RESET gpio request failed:%d\n", rc);
405 tegra_gpio_enable(HDA_RESET);
406 rc = gpio_direction_output(HDA_RESET, 1);
407 if (rc)
408 pr_err("HDA_RESET gpio direction configuration failed:%d\n", rc);
409}
410
411static void cardhu_audio_init(void)
412{
413 hda_init();
414}
415
416static void cardhu_i2c_init(void)
417{
418 tegra_i2c_device1.dev.platform_data = &cardhu_i2c1_platform_data;
419 tegra_i2c_device2.dev.platform_data = &cardhu_i2c2_platform_data;
420 tegra_i2c_device3.dev.platform_data = &cardhu_i2c3_platform_data;
421 tegra_i2c_device4.dev.platform_data = &cardhu_i2c4_platform_data;
422 tegra_i2c_device5.dev.platform_data = &cardhu_i2c5_platform_data;
423
424 platform_device_register(&tegra_i2c_device5);
425 platform_device_register(&tegra_i2c_device4);
426 platform_device_register(&tegra_i2c_device3);
427 platform_device_register(&tegra_i2c_device2);
428 platform_device_register(&tegra_i2c_device1);
429
430 i2c_register_board_info(4, &cardhu_codec_wm8903_info, 1);
431 i2c_register_board_info(4, &cardhu_codec_max98095_info, 1);
432 i2c_register_board_info(4, &cardhu_codec_aic326x_info, 1);
433
434 i2c_register_board_info(2, cardhu_i2c_bus3_board_info, 1);
435}
436
437static struct platform_device *cardhu_uart_devices[] __initdata = {
438 //&tegra_uarta_device,
439 //&tegra_uartb_device,
440 //&tegra_uartc_device,
441 //&tegra_uartd_device,
442 //&tegra_uarte_device,
443};
444static struct uart_clk_parent uart_parent_clk[] = {
445 [0] = {.name = "clk_m"},
446 [1] = {.name = "pll_p"},
447#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
448 [2] = {.name = "pll_m"},
449#endif
450};
451
452static struct tegra_uart_platform_data cardhu_uart_pdata;
453static struct tegra_uart_platform_data cardhu_loopback_uart_pdata;
454
455static void __init uart_debug_init(void)
456{
457 struct board_info board_info;
458 int debug_port_id;
459
460 tegra_get_board_info(&board_info);
461
462 debug_port_id = get_tegra_uart_debug_port_id();
463 if (debug_port_id < 0) {
464 debug_port_id = 0;
465 /* UARTB is debug port
466 * for SLT - E1186/E1187/PM269
467 * for E1256/E1257
468 */
469 if (((board_info.sku & SKU_SLT_ULPI_SUPPORT) &&
470 ((board_info.board_id == BOARD_E1186) ||
471 (board_info.board_id == BOARD_E1187) ||
472 (board_info.board_id == BOARD_PM269))) ||
473 (board_info.board_id == BOARD_E1256) ||
474 (board_info.board_id == BOARD_E1257))
475 debug_port_id = 1;
476 }
477
478 switch (debug_port_id) {
479 case 0:
480 /* UARTA is the debug port. */
481 pr_info("Selecting UARTA as the debug console\n");
482 cardhu_uart_devices[0] = &debug_uarta_device;
483 debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
484 debug_uart_port_base = ((struct plat_serial8250_port *)(
485 debug_uarta_device.dev.platform_data))->mapbase;
486 break;
487
488 case 1:
489 /* UARTB is the debug port. */
490 pr_info("Selecting UARTB as the debug console\n");
491 cardhu_uart_devices[1] = &debug_uartb_device;
492 debug_uart_clk = clk_get_sys("serial8250.0", "uartb");
493 debug_uart_port_base = ((struct plat_serial8250_port *)(
494 debug_uartb_device.dev.platform_data))->mapbase;
495 break;
496
497 case 2:
498 /* UARTC is the debug port. */
499 pr_info("Selecting UARTC as the debug console\n");
500 cardhu_uart_devices[2] = &debug_uartc_device;
501 debug_uart_clk = clk_get_sys("serial8250.0", "uartc");
502 debug_uart_port_base = ((struct plat_serial8250_port *)(
503 debug_uartc_device.dev.platform_data))->mapbase;
504 break;
505
506 case 3:
507 /* UARTD is the debug port. */
508 pr_info("Selecting UARTD as the debug console\n");
509 cardhu_uart_devices[3] = &debug_uartd_device;
510 debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
511 debug_uart_port_base = ((struct plat_serial8250_port *)(
512 debug_uartd_device.dev.platform_data))->mapbase;
513 break;
514
515 case 4:
516 /* UARTE is the debug port. */
517 pr_info("Selecting UARTE as the debug console\n");
518 cardhu_uart_devices[4] = &debug_uarte_device;
519 debug_uart_clk = clk_get_sys("serial8250.0", "uarte");
520 debug_uart_port_base = ((struct plat_serial8250_port *)(
521 debug_uarte_device.dev.platform_data))->mapbase;
522 break;
523
524 default:
525 pr_info("The debug console id %d is invalid, Assuming UARTA", debug_port_id);
526 cardhu_uart_devices[0] = &debug_uarta_device;
527 debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
528 debug_uart_port_base = ((struct plat_serial8250_port *)(
529 debug_uarta_device.dev.platform_data))->mapbase;
530 break;
531 }
532 return;
533}
534
535static void __init cardhu_uart_init(void)
536{
537 struct clk *c;
538 int i;
539
540 for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
541 c = tegra_get_clock_by_name(uart_parent_clk[i].name);
542 if (IS_ERR_OR_NULL(c)) {
543 pr_err("Not able to get the clock for %s\n",
544 uart_parent_clk[i].name);
545 continue;
546 }
547 uart_parent_clk[i].parent_clk = c;
548 uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
549 }
550 cardhu_uart_pdata.parent_clk_list = uart_parent_clk;
551 cardhu_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
552 cardhu_loopback_uart_pdata.parent_clk_list = uart_parent_clk;
553 cardhu_loopback_uart_pdata.parent_clk_count =
554 ARRAY_SIZE(uart_parent_clk);
555 cardhu_loopback_uart_pdata.is_loopback = true;
556 tegra_uarta_device.dev.platform_data = &cardhu_uart_pdata;
557 tegra_uartb_device.dev.platform_data = &cardhu_uart_pdata;
558 tegra_uartc_device.dev.platform_data = &cardhu_uart_pdata;
559 tegra_uartd_device.dev.platform_data = &cardhu_uart_pdata;
560 /* UARTE is used for loopback test purpose */
561 tegra_uarte_device.dev.platform_data = &cardhu_loopback_uart_pdata;
562
563 /* Register low speed only if it is selected */
564 if (!is_tegra_debug_uartport_hs()) {
565 uart_debug_init();
566 /* Clock enable for the debug channel */
567 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
568 pr_info("The debug console clock name is %s\n",
569 debug_uart_clk->name);
570 c = tegra_get_clock_by_name("pll_p");
571 if (IS_ERR_OR_NULL(c))
572 pr_err("Not getting the parent clock pll_p\n");
573 else
574 clk_set_parent(debug_uart_clk, c);
575
576 clk_enable(debug_uart_clk);
577 clk_set_rate(debug_uart_clk, clk_get_rate(c));
578 } else {
579 pr_err("Not getting the clock %s for debug console\n",
580 debug_uart_clk->name);
581 }
582 }
583
584 platform_add_devices(cardhu_uart_devices,
585 ARRAY_SIZE(cardhu_uart_devices));
586}
587
588static struct platform_device tegra_camera = {
589 .name = "tegra_camera",
590 .id = -1,
591};
592
593static struct platform_device *cardhu_spi_devices[] __initdata = {
594 &tegra_spi_device4,
595};
596
597struct spi_clk_parent spi_parent_clk[] = {
598 [0] = {.name = "pll_p"},
599#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
600 [1] = {.name = "pll_m"},
601 [2] = {.name = "clk_m"},
602#else
603 [1] = {.name = "clk_m"},
604#endif
605};
606
607static struct tegra_spi_platform_data cardhu_spi_pdata = {
608 .is_dma_based = true,
609 .max_dma_buffer = (16 * 1024),
610 .is_clkon_always = false,
611 .max_rate = 100000000,
612};
613
614static void __init cardhu_spi_init(void)
615{
616 int i;
617 struct clk *c;
618 struct board_info board_info;
619
620 tegra_get_board_info(&board_info);
621
622 for (i = 0; i < ARRAY_SIZE(spi_parent_clk); ++i) {
623 c = tegra_get_clock_by_name(spi_parent_clk[i].name);
624 if (IS_ERR_OR_NULL(c)) {
625 pr_err("Not able to get the clock for %s\n",
626 spi_parent_clk[i].name);
627 continue;
628 }
629 spi_parent_clk[i].parent_clk = c;
630 spi_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
631 }
632 cardhu_spi_pdata.parent_clk_list = spi_parent_clk;
633 cardhu_spi_pdata.parent_clk_count = ARRAY_SIZE(spi_parent_clk);
634 tegra_spi_device4.dev.platform_data = &cardhu_spi_pdata;
635 platform_add_devices(cardhu_spi_devices,
636 ARRAY_SIZE(cardhu_spi_devices));
637
638 if (board_info.board_id == BOARD_E1198) {
639 tegra_spi_device2.dev.platform_data = &cardhu_spi_pdata;
640 platform_device_register(&tegra_spi_device2);
641 tegra_spi_slave_device1.dev.platform_data = &cardhu_spi_pdata;
642 platform_device_register(&tegra_spi_slave_device1);
643 }
644}
645
646static void __init cardhu_dtv_init(void)
647{
648 struct board_info board_info;
649
650 tegra_get_board_info(&board_info);
651
652 if (board_info.board_id == BOARD_E1186)
653 platform_device_register(&tegra_dtv_device);
654}
655
656static struct resource tegra_rtc_resources[] = {
657 [0] = {
658 .start = TEGRA_RTC_BASE,
659 .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1,
660 .flags = IORESOURCE_MEM,
661 },
662 [1] = {
663 .start = INT_RTC,
664 .end = INT_RTC,
665 .flags = IORESOURCE_IRQ,
666 },
667};
668
669static struct platform_device tegra_rtc_device = {
670 .name = "tegra_rtc",
671 .id = -1,
672 .resource = tegra_rtc_resources,
673 .num_resources = ARRAY_SIZE(tegra_rtc_resources),
674};
675
676static struct tegra_wm8903_platform_data cardhu_audio_wm8903_pdata = {
677 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
678 .gpio_hp_det = TEGRA_GPIO_HP_DET,
679 .gpio_hp_mute = -1,
680 .gpio_int_mic_en = -1,
681 .gpio_ext_mic_en = -1,
682};
683
684static struct tegra_asoc_platform_data cardhu_audio_max98095_pdata = {
685 .gpio_spkr_en = -1,
686 .gpio_hp_det = TEGRA_GPIO_HP_DET,
687 .gpio_hp_mute = -1,
688 .gpio_int_mic_en = -1,
689 .gpio_ext_mic_en = -1,
690};
691
692static struct platform_device cardhu_audio_wm8903_device = {
693 .name = "tegra-snd-wm8903",
694 .id = 0,
695 .dev = {
696 .platform_data = &cardhu_audio_wm8903_pdata,
697 },
698};
699
700static struct platform_device cardhu_audio_max98095_device = {
701 .name = "tegra-snd-max98095",
702 .id = 0,
703 .dev = {
704 .platform_data = &cardhu_audio_max98095_pdata,
705 },
706};
707
708static struct tegra_asoc_platform_data cardhu_audio_aic326x_pdata = {
709 .gpio_spkr_en = -1,
710 .gpio_hp_det = TEGRA_GPIO_HP_DET,
711 .gpio_hp_mute = -1,
712 .gpio_int_mic_en = -1,
713 .gpio_ext_mic_en = -1,
714 /*defaults for Verbier-Cardhu board with TI AIC326X codec*/
715 .audio_port_id = {
716 [HIFI_CODEC] = 0,
717 [BASEBAND] = -1,
718 [BT_SCO] = 3,
719 },
720 .baseband_param = {
721 .rate = -1,
722 .channels = -1,
723 },
724};
725
726static struct platform_device cardhu_audio_aic326x_device = {
727 .name = "tegra-snd-aic326x",
728 .id = 0,
729 .dev = {
730 .platform_data = &cardhu_audio_aic326x_pdata,
731 },
732};
733
734static struct platform_device *cardhu_devices[] __initdata = {
735 &tegra_pmu_device,
736 &tegra_rtc_device,
737#ifndef CONFIG_TEGRA_USB0_EHCI1_HOST
738 &tegra_udc_device,
739#endif
740#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
741 &tegra_smmu_device,
742#endif
743 &tegra_wdt_device,
744#if defined(CONFIG_TEGRA_AVP)
745 &tegra_avp_device,
746#endif
747 &tegra_camera,
748#if defined(CONFIG_CRYPTO_DEV_TEGRA_SE)
749 &tegra_se_device,
750#endif
751 &tegra_ahub_device,
752 &tegra_dam_device0,
753 &tegra_dam_device1,
754 &tegra_dam_device2,
755 &tegra_i2s_device0,
756 &tegra_i2s_device1,
757 &tegra_i2s_device3,
758 &tegra_spdif_device,
759 &spdif_dit_device,
760 &bluetooth_dit_device,
761 &baseband_dit_device,
762 &cardhu_bcm4329_rfkill_device,
763 &tegra_pcm_device,
764 &cardhu_audio_wm8903_device,
765 &cardhu_audio_max98095_device,
766 &cardhu_audio_aic326x_device,
767 &tegra_hda_device,
768#if defined(CONFIG_CRYPTO_DEV_TEGRA_AES)
769 &tegra_aes_device,
770#endif
771};
772
773#define MXT_CONFIG_CRC 0xD62DE8
774static const u8 config[] = {
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0xFF, 0xFF, 0x32, 0x0A, 0x00, 0x14, 0x14, 0x00,
777 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00,
778 0x1B, 0x2A, 0x00, 0x20, 0x3C, 0x04, 0x05, 0x00,
779 0x02, 0x01, 0x00, 0x0A, 0x0A, 0x0A, 0x0A, 0xFF,
780 0x02, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x64, 0x02, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
786 0x00, 0x00, 0x00, 0x05, 0x0A, 0x15, 0x1E, 0x00,
787 0x00, 0x04, 0xFF, 0x03, 0x3F, 0x64, 0x64, 0x01,
788 0x0A, 0x14, 0x28, 0x4B, 0x00, 0x02, 0x00, 0x64,
789 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x00, 0x08, 0x10, 0x3C, 0x00, 0x00,
793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
795};
796
797#define MXT_CONFIG_CRC_SKU2000 0xA24D9A
798static const u8 config_sku2000[] = {
799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800 0xFF, 0xFF, 0x32, 0x0A, 0x00, 0x14, 0x14, 0x19,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00,
802 0x1B, 0x2A, 0x00, 0x20, 0x3A, 0x04, 0x05, 0x00, //23=thr 2 di
803 0x04, 0x04, 0x41, 0x0A, 0x0A, 0x0A, 0x0A, 0xFF,
804 0x02, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
805 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, //0A=limit
806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
810 0x00, 0x00, 0x00, 0x05, 0x0A, 0x15, 0x1E, 0x00,
811 0x00, 0x04, 0x00, 0x03, 0x3F, 0x64, 0x64, 0x01,
812 0x0A, 0x14, 0x28, 0x4B, 0x00, 0x02, 0x00, 0x64,
813 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816 0x00, 0x00, 0x00, 0x08, 0x10, 0x3C, 0x00, 0x00,
817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
819};
820
821static struct mxt_platform_data atmel_mxt_info = {
822 .x_line = 27,
823 .y_line = 42,
824 .x_size = 768,
825 .y_size = 1366,
826 .blen = 0x20,
827 .threshold = 0x3C,
828 .voltage = 3300000, /* 3.3V */
829 .orient = 5,
830 .config = config,
831 .config_length = 157,
832 .config_crc = MXT_CONFIG_CRC,
833 .irqflags = IRQF_TRIGGER_FALLING,
834/* .read_chg = &read_chg, */
835 .read_chg = NULL,
836};
837
838static struct i2c_board_info __initdata atmel_i2c_info[] = {
839 {
840 I2C_BOARD_INFO("atmel_mxt_ts", 0x5A),
841 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PH4),
842 .platform_data = &atmel_mxt_info,
843 }
844};
845
846static int __init cardhu_touch_init(void)
847{
848 struct board_info BoardInfo;
849
850 tegra_gpio_enable(TEGRA_GPIO_PH4);
851 tegra_gpio_enable(TEGRA_GPIO_PH6);
852
853 gpio_request(TEGRA_GPIO_PH4, "atmel-irq");
854 gpio_direction_input(TEGRA_GPIO_PH4);
855
856 gpio_request(TEGRA_GPIO_PH6, "atmel-reset");
857 gpio_direction_output(TEGRA_GPIO_PH6, 0);
858 msleep(1);
859 gpio_set_value(TEGRA_GPIO_PH6, 1);
860 msleep(100);
861
862 tegra_get_board_info(&BoardInfo);
863 if ((BoardInfo.sku & SKU_TOUCH_MASK) == SKU_TOUCH_2000) {
864 atmel_mxt_info.config = config_sku2000;
865 atmel_mxt_info.config_crc = MXT_CONFIG_CRC_SKU2000;
866 }
867
868 i2c_register_board_info(1, atmel_i2c_info, 1);
869
870 return 0;
871}
872
873static struct tegra_uhsic_config uhsic_phy_config = {
874 .enable_gpio = EN_HSIC_GPIO,
875 .reset_gpio = -1,
876 .sync_start_delay = 9,
877 .idle_wait_delay = 17,
878 .term_range_adj = 0,
879 .elastic_underrun_limit = 16,
880 .elastic_overrun_limit = 16,
881};
882
883static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = {
884 .phy_type = TEGRA_USB_PHY_TYPE_HSIC,
885 .phy_config = &uhsic_phy_config,
886 .operating_mode = TEGRA_USB_HOST,
887 .power_down_on_bus_suspend = 1,
888 .default_enable = true,
889};
890
891static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
892 [0] = {
893 .phy_config = &utmi_phy_config[0],
894 .operating_mode = TEGRA_USB_HOST,
895 .power_down_on_bus_suspend = 1,
896 .default_enable = true,
897 },
898 [1] = {
899 .phy_config = &utmi_phy_config[1],
900 .operating_mode = TEGRA_USB_HOST,
901 .power_down_on_bus_suspend = 1,
902 .default_enable = true,
903 },
904 [2] = {
905 .phy_config = &utmi_phy_config[2],
906 .operating_mode = TEGRA_USB_HOST,
907 .power_down_on_bus_suspend = 1,
908 .hotplug = 1,
909 .default_enable = true,
910 },
911};
912
913static struct tegra_otg_platform_data tegra_otg_pdata = {
914 .ehci_device = &tegra_ehci1_device,
915 .ehci_pdata = &tegra_ehci_pdata[0],
916};
917
918#ifdef CONFIG_USB_SUPPORT
919static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
920 [0] = {
921 .instance = 0,
922 .vbus_gpio = -1,
923 .vbus_reg_supply = "vdd_vbus_micro_usb",
924 },
925 [1] = {
926 .instance = 1,
927 .vbus_gpio = -1,
928 },
929 [2] = {
930 .instance = 2,
931 .vbus_gpio = -1,
932 .vbus_reg_supply = "vdd_vbus_typea_usb",
933 },
934};
935
936static int cardhu_usb_hsic_postsupend(void)
937{
938#ifdef CONFIG_TEGRA_BB_XMM_POWER
939 baseband_xmm_set_power_status(BBXMM_PS_L2);
940#endif
941 return 0;
942}
943
944static int cardhu_usb_hsic_preresume(void)
945{
946#ifdef CONFIG_TEGRA_BB_XMM_POWER
947 baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
948#endif
949 return 0;
950}
951
952static int cardhu_usb_hsic_phy_ready(void)
953{
954#ifdef CONFIG_TEGRA_BB_XMM_POWER
955 baseband_xmm_set_power_status(BBXMM_PS_L0);
956#endif
957 return 0;
958}
959
960static int cardhu_usb_hsic_phy_off(void)
961{
962#ifdef CONFIG_TEGRA_BB_XMM_POWER
963 baseband_xmm_set_power_status(BBXMM_PS_L3);
964#endif
965 return 0;
966}
967
968static void cardhu_usb_init(void)
969{
970 struct board_info bi;
971
972 tegra_get_board_info(&bi);
973
974 tegra_usb_phy_init(tegra_usb_phy_pdata,
975 ARRAY_SIZE(tegra_usb_phy_pdata));
976
977#ifndef CONFIG_TEGRA_USB0_EHCI1_HOST
978 tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
979 platform_device_register(&tegra_otg_device);
980#else
981 tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0];
982 platform_device_register(&tegra_ehci1_device);
983#endif
984
985 if (bi.board_id == BOARD_PM267) {
986 uhsic_phy_config.reset_gpio =
987 PM267_SMSC4640_HSIC_HUB_RESET_GPIO;
988 tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata;
989 platform_device_register(&tegra_ehci2_device);
990 } else if (bi.board_id == BOARD_E1256) {
991 tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata;
992 platform_device_register(&tegra_ehci2_device);
993 } else if (bi.board_id == BOARD_E1186) {
994 /* for baseband devices do not switch off phy during suspend */
995 tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0;
996 uhsic_phy_config.postsuspend = cardhu_usb_hsic_postsupend;
997 uhsic_phy_config.preresume = cardhu_usb_hsic_preresume;
998 uhsic_phy_config.usb_phy_ready = cardhu_usb_hsic_phy_ready;
999 uhsic_phy_config.post_phy_off = cardhu_usb_hsic_phy_off;
1000 tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata;
1001 /* baseband registration happens in baseband-xmm-power */
1002 } else {
1003 tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1];
1004 platform_device_register(&tegra_ehci2_device);
1005 }
1006
1007 tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2];
1008 platform_device_register(&tegra_ehci3_device);
1009
1010}
1011#else
1012static void cardhu_usb_init(void) { }
1013#endif
1014
1015static void cardhu_gps_init(void)
1016{
1017 tegra_gpio_enable(TEGRA_GPIO_PU2);
1018 tegra_gpio_enable(TEGRA_GPIO_PU3);
1019}
1020
1021static void cardhu_nfc_init(void)
1022{
1023 tegra_gpio_enable(TEGRA_GPIO_PX0);
1024 tegra_gpio_enable(TEGRA_GPIO_PP3);
1025 tegra_gpio_enable(TEGRA_GPIO_PO7);
1026}
1027
1028static struct baseband_power_platform_data tegra_baseband_power_data = {
1029 .baseband_type = BASEBAND_XMM,
1030 .modem = {
1031 .xmm = {
1032 .bb_rst = XMM_GPIO_BB_RST,
1033 .bb_on = XMM_GPIO_BB_ON,
1034 .ipc_bb_wake = XMM_GPIO_IPC_BB_WAKE,
1035 .ipc_ap_wake = XMM_GPIO_IPC_AP_WAKE,
1036 .ipc_hsic_active = XMM_GPIO_IPC_HSIC_ACTIVE,
1037 .ipc_hsic_sus_req = XMM_GPIO_IPC_HSIC_SUS_REQ,
1038 .hsic_device = &tegra_ehci2_device,
1039 },
1040 },
1041};
1042
1043static struct platform_device tegra_baseband_power_device = {
1044 .name = "baseband_xmm_power",
1045 .id = -1,
1046 .dev = {
1047 .platform_data = &tegra_baseband_power_data,
1048 },
1049};
1050
1051static struct platform_device tegra_baseband_power2_device = {
1052 .name = "baseband_xmm_power2",
1053 .id = -1,
1054 .dev = {
1055 .platform_data = &tegra_baseband_power_data,
1056 },
1057};
1058
1059
1060static struct tegra_pci_platform_data cardhu_pci_platform_data = {
1061 .port_status[0] = 1,
1062 .port_status[1] = 1,
1063 .port_status[2] = 1,
1064 .use_dock_detect = 0,
1065 .gpio = 0,
1066};
1067
1068static void cardhu_pci_init(void)
1069{
1070 struct board_info board_info;
1071
1072 int rc;
1073
1074 // NOTE
1075 // VDD_1V2_GEN HAS TO BE PROGRAMMED TO PROVIDE PROPER VOLTAGE LEVEL BY THE BOOTLOADER
1076
1077 // Enable PEX logic power supply on Carma
1078 rc = gpio_request(PEX_EN, "pex_power");
1079 if (rc)
1080 pr_err("PEX_EN gpio request failed:%d\n", rc);
1081
1082 tegra_gpio_enable(PEX_EN);
1083 rc = gpio_direction_output(PEX_EN, 0);
1084 if (rc)
1085 pr_err("PEX gpio direction configuration failed:%d\n", rc);
1086
1087 tegra_get_board_info(&board_info);
1088 if (board_info.board_id == BOARD_E1291) {
1089 cardhu_pci_platform_data.port_status[0] = 1;
1090 cardhu_pci_platform_data.port_status[1] = 1;
1091 cardhu_pci_platform_data.port_status[2] = 1;
1092 cardhu_pci_platform_data.use_dock_detect = 1;
1093 cardhu_pci_platform_data.gpio = DOCK_DETECT_GPIO;
1094 }
1095 tegra_pci_device.dev.platform_data = &cardhu_pci_platform_data;
1096 platform_device_register(&tegra_pci_device);
1097}
1098
1099static void cardhu_modem_init(void)
1100{
1101 struct board_info board_info;
1102 int w_disable_gpio, ret;
1103
1104 tegra_get_board_info(&board_info);
1105 switch (board_info.board_id) {
1106 case BOARD_E1291:
1107 case BOARD_E1198:
1108 if (((board_info.board_id == BOARD_E1291) &&
1109 (board_info.fab < BOARD_FAB_A03)) ||
1110 ((board_info.board_id == BOARD_E1198) &&
1111 (board_info.fab < BOARD_FAB_A02))) {
1112 w_disable_gpio = TEGRA_GPIO_PH5;
1113 } else {
1114 w_disable_gpio = TEGRA_GPIO_PDD5;
1115 }
1116 tegra_gpio_enable(w_disable_gpio);
1117 ret = gpio_request(w_disable_gpio, "w_disable_gpio");
1118 if (ret < 0)
1119 pr_err("%s: gpio_request failed for gpio %d\n",
1120 __func__, w_disable_gpio);
1121 else
1122 gpio_direction_input(w_disable_gpio);
1123
1124 /* E1291-A04 & E1198:A02: Set PERST signal to high */
1125 if (((board_info.board_id == BOARD_E1291) &&
1126 (board_info.fab >= BOARD_FAB_A04)) ||
1127 ((board_info.board_id == BOARD_E1198) &&
1128 (board_info.fab >= BOARD_FAB_A02))) {
1129 ret = gpio_request(TEGRA_GPIO_PH7, "modem_perst");
1130 if (ret < 0) {
1131 pr_err("%s(): Error in allocating gpio "
1132 "TEGRA_GPIO_PH7\n", __func__);
1133 break;
1134 }
1135 gpio_direction_output(TEGRA_GPIO_PH7, 1);
1136 tegra_gpio_enable(TEGRA_GPIO_PH7);
1137 }
1138 break;
1139 case BOARD_E1186:
1140 tegra_gpio_enable(
1141 tegra_baseband_power_data.modem.xmm.bb_rst);
1142 tegra_gpio_enable(
1143 tegra_baseband_power_data.modem.xmm.bb_on);
1144 tegra_gpio_enable(
1145 tegra_baseband_power_data.modem.xmm.ipc_bb_wake);
1146 tegra_gpio_enable(
1147 tegra_baseband_power_data.modem.xmm.ipc_ap_wake);
1148 tegra_gpio_enable(
1149 tegra_baseband_power_data.modem.xmm.ipc_hsic_active);
1150 tegra_gpio_enable(
1151 tegra_baseband_power_data.modem.xmm.ipc_hsic_sus_req);
1152 platform_device_register(&tegra_baseband_power_device);
1153 platform_device_register(&tegra_baseband_power2_device);
1154 break;
1155 default:
1156 break;
1157 }
1158
1159}
1160
1161#ifdef CONFIG_SATA_AHCI_TEGRA
1162static void cardhu_sata_init(void)
1163{
1164 platform_device_register(&tegra_sata_device);
1165}
1166#else
1167static void cardhu_sata_init(void) { }
1168#endif
1169
1170static void __init tegra_cardhu_init(void)
1171{
1172 tegra_thermal_init(&thermal_data);
1173 tegra_clk_init_from_table(cardhu_clk_init_table);
1174 cardhu_pinmux_init();
1175 cardhu_i2c_init();
1176 cardhu_spi_init();
1177 cardhu_usb_init();
1178#ifdef CONFIG_TEGRA_EDP_LIMITS
1179 cardhu_edp_init();
1180#endif
1181 cardhu_uart_init();
1182 platform_add_devices(cardhu_devices, ARRAY_SIZE(cardhu_devices));
1183 cardhu_audio_init();
1184 tegra_ram_console_debug_init();
1185 cardhu_sdhci_init();
1186 cardhu_regulator_init();
1187 //cardhu_dtv_init();
1188 cardhu_suspend_init();
1189 //cardhu_touch_init();
1190 //cardhu_gps_init();
1191 //cardhu_modem_init();
1192 //cardhu_kbc_init();
1193 //cardhu_scroll_init();
1194 //cardhu_keys_init();
1195 cardhu_panel_init();
1196 //cardhu_pmon_init();
1197 cardhu_sensors_init();
1198 //cardhu_setup_bluesleep();
1199 cardhu_sata_init();
1200 //audio_wired_jack_init();
1201 cardhu_pins_state_init();
1202 cardhu_emc_init();
1203 tegra_release_bootloader_fb();
1204 //cardhu_nfc_init();
1205 cardhu_pci_init();
1206#ifdef CONFIG_TEGRA_WDT_RECOVERY
1207 tegra_wdt_recovery_init();
1208#endif
1209}
1210
1211static void __init tegra_cardhu_reserve(void)
1212{
1213#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM)
1214 /* support 1920X1200 with 24bpp */
1215 tegra_reserve(0, SZ_8M + SZ_1M, SZ_8M + SZ_1M);
1216#else
1217 tegra_reserve(SZ_128M, SZ_8M, SZ_8M);
1218#endif
1219 tegra_ram_console_debug_reserve(SZ_1M);
1220}
1221
1222MACHINE_START(CARDHU, "cardhu")
1223 .boot_params = 0x80000100,
1224 .map_io = tegra_map_common_io,
1225 .reserve = tegra_cardhu_reserve,
1226 .init_early = tegra_init_early,
1227 .init_irq = tegra_init_irq,
1228 .timer = &tegra_timer,
1229 .init_machine = tegra_cardhu_init,
1230MACHINE_END
diff --git a/arch/arm/mach-tegra/board-cardhu.h b/arch/arm/mach-tegra/board-cardhu.h
new file mode 100644
index 00000000000..a0d0ebf3a77
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu.h
@@ -0,0 +1,257 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu.h
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef _MACH_TEGRA_BOARD_CARDHU_H
22#define _MACH_TEGRA_BOARD_CARDHU_H
23
24#include <mach/gpio.h>
25#include <mach/irqs.h>
26#include <linux/mfd/tps6591x.h>
27#include <linux/mfd/ricoh583.h>
28
29/* Processor Board ID */
30#define BOARD_E1187 0x0B57
31#define BOARD_E1186 0x0B56
32#define BOARD_E1198 0x0B62
33#define BOARD_E1256 0x0C38
34#define BOARD_E1257 0x0C39
35#define BOARD_E1291 0x0C5B
36#define BOARD_PM267 0x0243
37#define BOARD_PM269 0x0245
38#define BOARD_E1208 0x0C08
39#define BOARD_PM305 0x0305
40#define BOARD_PM311 0x030B
41#define BOARD_PMU_PM298 0x0262
42#define BOARD_PMU_PM299 0x0263
43
44/* SKU Information */
45#define BOARD_SKU_B11 0xb11
46
47#define SKU_DCDC_TPS62361_SUPPORT 0x1
48#define SKU_SLT_ULPI_SUPPORT 0x2
49#define SKU_T30S_SUPPORT 0x4
50#define SKU_TOUCHSCREEN_MECH_FIX 0x0100
51
52#define SKU_TOUCH_MASK 0xFF00
53#define SKU_TOUCH_2000 0x0B00
54
55#define SKU_MEMORY_TYPE_BIT 0x3
56#define SKU_MEMORY_TYPE_MASK 0x7
57/* If BOARD_PM269 */
58#define SKU_MEMORY_SAMSUNG_EC 0x0
59#define SKU_MEMORY_ELPIDA 0x2
60#define SKU_MEMORY_SAMSUNG_EB 0x4
61/* If BOARD_PM272 */
62#define SKU_MEMORY_1GB_1R_HYNIX 0x0
63#define SKU_MEMORY_2GB_2R_HYH9 0x2
64/* If other BOARD_ variants */
65#define SKU_MEMORY_CARDHU_1GB_1R 0x0
66#define SKU_MEMORY_CARDHU_2GB_2R 0x2
67#define SKU_MEMORY_CARDHU_2GB_1R_HYK0 0x4
68#define SKU_MEMORY_CARDHU_2GB_1R_HYH9 0x6
69#define SKU_MEMORY_CARDHU_2GB_1R_HYNIX 0x1
70#define MEMORY_TYPE(sku) (((sku) >> SKU_MEMORY_TYPE_BIT) & SKU_MEMORY_TYPE_MASK)
71
72/* Board Fab version */
73#define BOARD_FAB_A00 0x0
74#define BOARD_FAB_A01 0x1
75#define BOARD_FAB_A02 0x2
76#define BOARD_FAB_A03 0x3
77#define BOARD_FAB_A04 0x4
78#define BOARD_FAB_A05 0x5
79
80/* Display Board ID */
81#define BOARD_DISPLAY_PM313 0x030D
82#define BOARD_DISPLAY_E1247 0x0C2F
83
84/* External peripheral act as gpio */
85/* TPS6591x GPIOs */
86#define TPS6591X_GPIO_BASE TEGRA_NR_GPIOS
87#define TPS6591X_GPIO_0 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP0)
88#define TPS6591X_GPIO_1 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP1)
89#define TPS6591X_GPIO_2 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP2)
90#define TPS6591X_GPIO_3 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP3)
91#define TPS6591X_GPIO_4 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP4)
92#define TPS6591X_GPIO_5 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP5)
93#define TPS6591X_GPIO_6 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP6)
94#define TPS6591X_GPIO_7 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP7)
95#define TPS6591X_GPIO_8 (TPS6591X_GPIO_BASE + TPS6591X_GPIO_GP8)
96#define TPS6591X_GPIO_END (TPS6591X_GPIO_BASE + TPS6591X_GPIO_NR)
97
98/* RICOH583 GPIO */
99#define RICOH583_GPIO_BASE TEGRA_NR_GPIOS
100#define RICOH583_GPIO_END (RICOH583_GPIO_BASE + 8)
101
102/* MAX77663 GPIO */
103#define MAX77663_GPIO_BASE TEGRA_NR_GPIOS
104#define MAX77663_GPIO_END (MAX77663_GPIO_BASE + MAX77663_GPIO_NR)
105
106/* PMU_TCA6416 GPIOs */
107#define PMU_TCA6416_GPIO_BASE (TPS6591X_GPIO_END)
108#define PMU_TCA6416_GPIO_PORT00 (PMU_TCA6416_GPIO_BASE + 0)
109#define PMU_TCA6416_GPIO_PORT01 (PMU_TCA6416_GPIO_BASE + 1)
110#define PMU_TCA6416_GPIO_PORT02 (PMU_TCA6416_GPIO_BASE + 2)
111#define PMU_TCA6416_GPIO_PORT03 (PMU_TCA6416_GPIO_BASE + 3)
112#define PMU_TCA6416_GPIO_PORT04 (PMU_TCA6416_GPIO_BASE + 4)
113#define PMU_TCA6416_GPIO_PORT05 (PMU_TCA6416_GPIO_BASE + 5)
114#define PMU_TCA6416_GPIO_PORT06 (PMU_TCA6416_GPIO_BASE + 6)
115#define PMU_TCA6416_GPIO_PORT07 (PMU_TCA6416_GPIO_BASE + 7)
116#define PMU_TCA6416_GPIO_PORT10 (PMU_TCA6416_GPIO_BASE + 8)
117#define PMU_TCA6416_GPIO_PORT11 (PMU_TCA6416_GPIO_BASE + 9)
118#define PMU_TCA6416_GPIO_PORT12 (PMU_TCA6416_GPIO_BASE + 10)
119#define PMU_TCA6416_GPIO_PORT13 (PMU_TCA6416_GPIO_BASE + 11)
120#define PMU_TCA6416_GPIO_PORT14 (PMU_TCA6416_GPIO_BASE + 12)
121#define PMU_TCA6416_GPIO_PORT15 (PMU_TCA6416_GPIO_BASE + 13)
122#define PMU_TCA6416_GPIO_PORT16 (PMU_TCA6416_GPIO_BASE + 14)
123#define PMU_TCA6416_GPIO_PORT17 (PMU_TCA6416_GPIO_BASE + 15)
124#define PMU_TCA6416_GPIO_END (PMU_TCA6416_GPIO_BASE + 16)
125
126/* PMU_TCA6416 GPIO assignment */
127#define EN_HSIC_GPIO PMU_TCA6416_GPIO_PORT11 /* PMU_GPIO25 */
128#define PM267_SMSC4640_HSIC_HUB_RESET_GPIO PMU_TCA6416_GPIO_PORT17 /* PMU_GPIO31 */
129
130/* CAM_TCA6416 GPIOs */
131#define CAM_TCA6416_GPIO_BASE PMU_TCA6416_GPIO_END
132#define CAM1_PWR_DN_GPIO CAM_TCA6416_GPIO_BASE + 0
133#define CAM1_RST_L_GPIO CAM_TCA6416_GPIO_BASE + 1
134#define CAM1_AF_PWR_DN_L_GPIO CAM_TCA6416_GPIO_BASE + 2
135#define CAM1_LDO_SHUTDN_L_GPIO CAM_TCA6416_GPIO_BASE + 3
136#define CAM2_PWR_DN_GPIO CAM_TCA6416_GPIO_BASE + 4
137#define CAM2_RST_L_GPIO CAM_TCA6416_GPIO_BASE + 5
138#define CAM2_AF_PWR_DN_L_GPIO CAM_TCA6416_GPIO_BASE + 6
139#define CAM2_LDO_SHUTDN_L_GPIO CAM_TCA6416_GPIO_BASE + 7
140#define CAM_FRONT_PWR_DN_GPIO CAM_TCA6416_GPIO_BASE + 8
141#define CAM_FRONT_RST_L_GPIO CAM_TCA6416_GPIO_BASE + 9
142#define CAM_FRONT_AF_PWR_DN_L_GPIO CAM_TCA6416_GPIO_BASE + 10
143#define CAM_FRONT_LDO_SHUTDN_L_GPIO CAM_TCA6416_GPIO_BASE + 11
144#define CAM_FRONT_LED_EXP CAM_TCA6416_GPIO_BASE + 12
145#define CAM_SNN_LED_REAR_EXP CAM_TCA6416_GPIO_BASE + 13
146/* PIN 19 NOT USED and is reserved */
147#define CAM_NOT_USED CAM_TCA6416_GPIO_BASE + 14
148#define CAM_I2C_MUX_RST_EXP CAM_TCA6416_GPIO_BASE + 15
149#define CAM_TCA6416_GPIO_END CAM_TCA6416_GPIO_BASE + 16
150
151/* WM8903 GPIOs */
152#define CARDHU_GPIO_WM8903(_x_) (CAM_TCA6416_GPIO_END + (_x_))
153#define CARDHU_GPIO_WM8903_END CARDHU_GPIO_WM8903(4)
154
155/* Audio-related GPIOs */
156#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PW3
157#define TEGRA_GPIO_SPKR_EN CARDHU_GPIO_WM8903(2)
158#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
159
160/* CAMERA RELATED GPIOs on CARDHU */
161#define OV5650_RESETN_GPIO TEGRA_GPIO_PBB0
162#define CAM1_POWER_DWN_GPIO TEGRA_GPIO_PBB5
163#define CAM2_POWER_DWN_GPIO TEGRA_GPIO_PBB6
164#define CAM3_POWER_DWN_GPIO TEGRA_GPIO_PBB7
165#define CAMERA_CSI_CAM_SEL_GPIO TEGRA_GPIO_PBB4
166#define CAMERA_CSI_MUX_SEL_GPIO TEGRA_GPIO_PCC1
167#define CAM1_LDO_EN_GPIO TEGRA_GPIO_PR6
168#define CAM2_LDO_EN_GPIO TEGRA_GPIO_PR7
169#define CAM3_LDO_EN_GPIO TEGRA_GPIO_PS0
170#define OV14810_RESETN_GPIO TEGRA_GPIO_PBB0
171
172#define CAMERA_FLASH_SYNC_GPIO TEGRA_GPIO_PBB3
173#define CAMERA_FLASH_MAX_TORCH_AMP 7
174#define CAMERA_FLASH_MAX_FLASH_AMP 7
175
176/* PCA954x I2C bus expander bus addresses */
177#define PCA954x_I2C_BUS_BASE 6
178#define PCA954x_I2C_BUS0 (PCA954x_I2C_BUS_BASE + 0)
179#define PCA954x_I2C_BUS1 (PCA954x_I2C_BUS_BASE + 1)
180#define PCA954x_I2C_BUS2 (PCA954x_I2C_BUS_BASE + 2)
181#define PCA954x_I2C_BUS3 (PCA954x_I2C_BUS_BASE + 3)
182
183#define AC_PRESENT_GPIO TPS6591X_GPIO_4
184
185/*****************Interrupt tables ******************/
186/* External peripheral act as interrupt controller */
187/* TPS6591x IRQs */
188#define TPS6591X_IRQ_BASE TEGRA_NR_IRQS
189#define TPS6591X_IRQ_END (TPS6591X_IRQ_BASE + 18)
190#define DOCK_DETECT_GPIO TEGRA_GPIO_PU4
191
192/* RICOH583 IRQs */
193#define RICOH583_IRQ_BASE TEGRA_NR_IRQS
194#define RICOH583_IRQ_END (RICOH583_IRQ_BASE + RICOH583_NR_IRQS)
195
196/* MAX77663 IRQs */
197#define MAX77663_IRQ_BASE TEGRA_NR_IRQS
198#define MAX77663_IRQ_END (MAX77663_IRQ_BASE + MAX77663_IRQ_NR)
199
200/* HDA AUDIO RESET */
201#define HDA_RESET TEGRA_GPIO_PEE2
202
203int cardhu_charge_init(void);
204int cardhu_regulator_init(void);
205int cardhu_suspend_init(void);
206int cardhu_sdhci_init(void);
207int cardhu_pinmux_init(void);
208int cardhu_panel_init(void);
209int cardhu_sensors_init(void);
210int cardhu_kbc_init(void);
211int cardhu_scroll_init(void);
212int cardhu_keys_init(void);
213int cardhu_pins_state_init(void);
214int cardhu_emc_init(void);
215int cardhu_edp_init(void);
216int cardhu_pmon_init(void);
217int cardhu_pm298_gpio_switch_regulator_init(void);
218int cardhu_pm298_regulator_init(void);
219int cardhu_pm299_gpio_switch_regulator_init(void);
220int cardhu_pm299_regulator_init(void);
221
222#define MPU_TYPE_MPU3050 1
223#define MPU_TYPE_MPU6050 2
224#define MPU_GYRO_TYPE MPU_TYPE_MPU3050
225#define MPU_GYRO_IRQ_GPIO TEGRA_GPIO_PX1
226#define MPU_GYRO_ADDR 0x68
227#define MPU_GYRO_BUS_NUM 2
228#define MPU_GYRO_ORIENTATION { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
229#define MPU_ACCEL_NAME "kxtf9"
230#define MPU_ACCEL_IRQ_GPIO TEGRA_GPIO_PL1
231#define MPU_ACCEL_ADDR 0x0F
232#define MPU_ACCEL_BUS_NUM 2
233#define MPU_ACCEL_ORIENTATION { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
234#define MPU_COMPASS_NAME "ak8975"
235#define MPU_COMPASS_IRQ_GPIO 0
236#define MPU_COMPASS_ADDR 0x0C
237#define MPU_COMPASS_BUS_NUM 2
238#define MPU_COMPASS_ORIENTATION { 1, 0, 0, 0, 1, 0, 0, 0, 1 }
239
240/* Baseband GPIO addresses */
241#define BB_GPIO_BB_EN TEGRA_GPIO_PR5
242#define BB_GPIO_BB_RST TEGRA_GPIO_PS4
243#define BB_GPIO_SPI_INT TEGRA_GPIO_PS6
244#define BB_GPIO_SPI_SS TEGRA_GPIO_PV0
245#define BB_GPIO_AWR TEGRA_GPIO_PS7
246#define BB_GPIO_CWR TEGRA_GPIO_PU5
247
248#define XMM_GPIO_BB_ON BB_GPIO_BB_EN
249#define XMM_GPIO_BB_RST BB_GPIO_BB_RST
250#define XMM_GPIO_IPC_HSIC_ACTIVE BB_GPIO_SPI_INT
251#define XMM_GPIO_IPC_HSIC_SUS_REQ BB_GPIO_SPI_SS
252#define XMM_GPIO_IPC_BB_WAKE BB_GPIO_AWR
253#define XMM_GPIO_IPC_AP_WAKE BB_GPIO_CWR
254
255#define TDIODE_OFFSET (10000) /* in millicelsius */
256
257#endif
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
new file mode 100644
index 00000000000..9f47e04446f
--- /dev/null
+++ b/arch/arm/mach-tegra/board-dt.c
@@ -0,0 +1,119 @@
1/*
2 * nVidia Tegra device tree board support
3 *
4 * Copyright (C) 2010 Secret Lab Technologies, Ltd.
5 * Copyright (C) 2010 Google, Inc.
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/platform_device.h>
21#include <linux/serial_8250.h>
22#include <linux/clk.h>
23#include <linux/dma-mapping.h>
24#include <linux/irqdomain.h>
25#include <linux/of.h>
26#include <linux/of_address.h>
27#include <linux/of_fdt.h>
28#include <linux/of_irq.h>
29#include <linux/of_platform.h>
30#include <linux/pda_power.h>
31#include <linux/io.h>
32#include <linux/i2c.h>
33#include <linux/i2c-tegra.h>
34
35#include <asm/mach-types.h>
36#include <asm/mach/arch.h>
37#include <asm/mach/time.h>
38#include <asm/setup.h>
39
40#include <mach/iomap.h>
41#include <mach/irqs.h>
42
43#include "board.h"
44#include "board-harmony.h"
45#include "clock.h"
46#include "devices.h"
47
48void harmony_pinmux_init(void);
49void seaboard_pinmux_init(void);
50
51
52struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
53 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
54 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
55 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL),
56 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL),
57 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL),
58 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
59 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
60 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
61 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL),
62 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.1", NULL),
63 OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL),
64 {}
65};
66
67static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
68 /* name parent rate enabled */
69 { "uartd", "pll_p", 216000000, true },
70 { NULL, NULL, 0, 0},
71};
72
73static struct of_device_id tegra_dt_match_table[] __initdata = {
74 { .compatible = "simple-bus", },
75 {}
76};
77
78static struct of_device_id tegra_dt_gic_match[] __initdata = {
79 { .compatible = "nvidia,tegra20-gic", },
80 {}
81};
82
83static void __init tegra_dt_init(void)
84{
85 struct device_node *node;
86
87 node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match,
88 TEGRA_ARM_INT_DIST_BASE);
89 if (node)
90 irq_domain_add_simple(node, INT_GIC_BASE);
91
92 tegra_clk_init_from_table(tegra_dt_clk_init_table);
93
94 if (of_machine_is_compatible("nvidia,harmony"))
95 harmony_pinmux_init();
96 else if (of_machine_is_compatible("nvidia,seaboard"))
97 seaboard_pinmux_init();
98
99 /*
100 * Finished with the static registrations now; fill in the missing
101 * devices
102 */
103 of_platform_populate(NULL, tegra_dt_match_table, tegra20_auxdata_lookup, NULL);
104}
105
106static const char * tegra_dt_board_compat[] = {
107 "nvidia,harmony",
108 "nvidia,seaboard",
109 NULL
110};
111
112DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)")
113 .map_io = tegra_map_common_io,
114 .init_early = tegra_init_early,
115 .init_irq = tegra_init_irq,
116 .timer = &tegra_timer,
117 .init_machine = tegra_dt_init,
118 .dt_compat = tegra_dt_board_compat,
119MACHINE_END
diff --git a/arch/arm/mach-tegra/board-enterprise-baseband.c b/arch/arm/mach-tegra/board-enterprise-baseband.c
new file mode 100644
index 00000000000..7552e287154
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-baseband.c
@@ -0,0 +1,247 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-baseband.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/resource.h>
22#include <linux/platform_device.h>
23#include <linux/delay.h>
24#include <linux/gpio.h>
25#include <linux/interrupt.h>
26#include <linux/irq.h>
27#include <linux/err.h>
28#include <linux/wakelock.h>
29#include <linux/platform_data/tegra_usb.h>
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <mach/pinmux.h>
33#include <mach/usb_phy.h>
34#include <mach/tegra_usb_modem_power.h>
35#include "devices.h"
36#include "gpio-names.h"
37
38/* Tegra3 BB GPIO */
39#define MODEM_PWR_ON TEGRA_GPIO_PE0
40#define MODEM_RESET TEGRA_GPIO_PE1
41#define BB_RST_OUT TEGRA_GPIO_PV1
42
43/* Icera BB GPIO */
44#define AP2MDM_ACK TEGRA_GPIO_PE3
45#define MDM2AP_ACK TEGRA_GPIO_PU5
46#define AP2MDM_ACK2 TEGRA_GPIO_PE2
47#define MDM2AP_ACK2 TEGRA_GPIO_PV0
48
49/* ULPI GPIO */
50#define ULPI_STP TEGRA_GPIO_PY3
51#define ULPI_DIR TEGRA_GPIO_PY1
52#define ULPI_D0 TEGRA_GPIO_PO1
53#define ULPI_D1 TEGRA_GPIO_PO2
54
55static struct wake_lock mdm_wake_lock;
56
57static struct gpio modem_gpios[] = {
58 {MODEM_PWR_ON, GPIOF_OUT_INIT_LOW, "MODEM PWR ON"},
59 {MODEM_RESET, GPIOF_IN, "MODEM RESET"},
60 {BB_RST_OUT, GPIOF_IN, "BB RST OUT"},
61 {MDM2AP_ACK, GPIOF_IN, "MDM2AP_ACK"},
62 {AP2MDM_ACK2, GPIOF_OUT_INIT_HIGH, "AP2MDM ACK2"},
63 {AP2MDM_ACK, GPIOF_OUT_INIT_LOW, "AP2MDM ACK"},
64 {ULPI_STP, GPIOF_IN, "ULPI_STP"},
65 {ULPI_DIR, GPIOF_OUT_INIT_LOW, "ULPI_DIR"},
66 {ULPI_D0, GPIOF_OUT_INIT_LOW, "ULPI_D0"},
67 {ULPI_D1, GPIOF_OUT_INIT_LOW, "ULPI_D1"},
68};
69
70static int baseband_phy_on(void);
71static int baseband_phy_off(void);
72static void baseband_phy_restore_start(void);
73static void baseband_phy_restore_end(void);
74
75static struct tegra_ulpi_trimmer e1219_trimmer = { 10, 1, 1, 1 };
76
77static struct tegra_ulpi_config ehci2_null_ulpi_phy_config = {
78 .trimmer = &e1219_trimmer,
79 .post_phy_on = baseband_phy_on,
80 .pre_phy_off = baseband_phy_off,
81 .phy_restore_start = baseband_phy_restore_start,
82 .phy_restore_end = baseband_phy_restore_end,
83 .phy_restore_gpio = MDM2AP_ACK,
84 .ulpi_dir_gpio = ULPI_DIR,
85 .ulpi_d0_gpio = ULPI_D0,
86 .ulpi_d1_gpio = ULPI_D1,
87};
88
89static struct tegra_ehci_platform_data ehci2_null_ulpi_platform_data = {
90 .operating_mode = TEGRA_USB_HOST,
91 .power_down_on_bus_suspend = 0,
92 .phy_config = &ehci2_null_ulpi_phy_config,
93 .phy_type = TEGRA_USB_PHY_TYPE_NULL_ULPI,
94};
95
96static int __init tegra_null_ulpi_init(void)
97{
98 tegra_ehci2_device.dev.platform_data = &ehci2_null_ulpi_platform_data;
99 platform_device_register(&tegra_ehci2_device);
100 return 0;
101}
102
103static irqreturn_t mdm_start_thread(int irq, void *data)
104{
105 if (gpio_get_value(BB_RST_OUT)) {
106 pr_info("BB_RST_OUT high\n");
107 } else {
108 pr_info("BB_RST_OUT low\n");
109 }
110
111 /* hold wait lock to complete the enumeration */
112 wake_lock_timeout(&mdm_wake_lock, HZ * 10);
113
114 return IRQ_HANDLED;
115}
116
117static int baseband_phy_on(void)
118{
119 static bool phy_init = false;
120
121 if (!phy_init) {
122 /* set AP2MDM_ACK2 low */
123 gpio_set_value(AP2MDM_ACK2, 0);
124 phy_init = true;
125 }
126 pr_info("%s\n", __func__);
127 return 0;
128}
129
130static int baseband_phy_off(void)
131{
132 pr_info("%s\n", __func__);
133 return 0;
134}
135
136static void baseband_phy_restore_start(void)
137{
138 /* set AP2MDM_ACK2 high */
139 gpio_set_value(AP2MDM_ACK2, 1);
140}
141
142static void baseband_phy_restore_end(void)
143{
144 /* set AP2MDM_ACK2 low */
145 gpio_set_value(AP2MDM_ACK2, 0);
146}
147
148static void baseband_start(void)
149{
150 /*
151 * Leave baseband powered OFF.
152 * User-space daemons will take care of powering it up.
153 */
154 pr_info("%s\n", __func__);
155 gpio_set_value(MODEM_PWR_ON, 0);
156}
157
158static void baseband_reset(void)
159{
160 /* Initiate power cycle on baseband sub system */
161 pr_info("%s\n", __func__);
162 gpio_set_value(MODEM_PWR_ON, 0);
163 mdelay(200);
164 gpio_set_value(MODEM_PWR_ON, 1);
165}
166
167static int baseband_init(void)
168{
169 int irq;
170 int ret;
171
172 ret = gpio_request_array(modem_gpios, ARRAY_SIZE(modem_gpios));
173 if (ret)
174 return ret;
175
176 /* enable pull-up for ULPI STP */
177 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_ULPI_STP,
178 TEGRA_PUPD_PULL_UP);
179
180 /* enable pull-up for MDM2AP_ACK2 */
181 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_GPIO_PV0,
182 TEGRA_PUPD_PULL_UP);
183
184 tegra_gpio_enable(MODEM_PWR_ON);
185 tegra_gpio_enable(MODEM_RESET);
186 tegra_gpio_enable(AP2MDM_ACK2);
187 tegra_gpio_enable(BB_RST_OUT);
188 tegra_gpio_enable(AP2MDM_ACK);
189 tegra_gpio_enable(MDM2AP_ACK);
190 tegra_gpio_enable(TEGRA_GPIO_PY3);
191 tegra_gpio_enable(TEGRA_GPIO_PO1);
192 tegra_gpio_enable(TEGRA_GPIO_PO2);
193
194 /* export GPIO for user space access through sysfs */
195 gpio_export(MODEM_PWR_ON, false);
196
197 /* phy init */
198 tegra_null_ulpi_init();
199
200 wake_lock_init(&mdm_wake_lock, WAKE_LOCK_SUSPEND, "mdm_lock");
201
202 /* enable IRQ for BB_RST_OUT */
203 irq = gpio_to_irq(BB_RST_OUT);
204
205 ret = request_threaded_irq(irq, NULL, mdm_start_thread,
206 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
207 "mdm_start", NULL);
208 if (ret < 0) {
209 pr_err("%s: request_threaded_irq error\n", __func__);
210 return ret;
211 }
212
213 ret = enable_irq_wake(irq);
214 if (ret) {
215 pr_err("%s: enable_irq_wake error\n", __func__);
216 free_irq(irq, NULL);
217 return ret;
218 }
219
220 return 0;
221}
222
223static const struct tegra_modem_operations baseband_operations = {
224 .init = baseband_init,
225 .start = baseband_start,
226 .reset = baseband_reset,
227};
228
229static struct tegra_usb_modem_power_platform_data baseband_pdata = {
230 .ops = &baseband_operations,
231 .wake_gpio = MDM2AP_ACK2,
232 .flags = IRQF_TRIGGER_FALLING,
233};
234
235static struct platform_device icera_baseband_device = {
236 .name = "tegra_usb_modem_power",
237 .id = -1,
238 .dev = {
239 .platform_data = &baseband_pdata,
240 },
241};
242
243int __init enterprise_modem_init(void)
244{
245 platform_device_register(&icera_baseband_device);
246 return 0;
247}
diff --git a/arch/arm/mach-tegra/board-enterprise-kbc.c b/arch/arm/mach-tegra/board-enterprise-kbc.c
new file mode 100644
index 00000000000..4b719d78c9a
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-kbc.c
@@ -0,0 +1,107 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-kbc.c
3 * Keys configuration for Nvidia tegra3 enterprise platform.
4 *
5 * Copyright (C) 2011 NVIDIA, Inc.
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
19 * 02111-1307, USA
20 */
21
22#include <linux/kernel.h>
23#include <linux/platform_device.h>
24#include <linux/input.h>
25#include <mach/io.h>
26#include <mach/iomap.h>
27#include <mach/kbc.h>
28
29#include "board.h"
30#include "board-enterprise.h"
31#include "devices.h"
32
33#define ENTERPRISE_ROW_COUNT 3
34#define ENTERPRISE_COL_COUNT 3
35
36static const u32 kbd_keymap[] = {
37 KEY(0, 0, KEY_POWER),
38
39 KEY(1, 0, KEY_HOME),
40 KEY(1, 1, KEY_BACK),
41 KEY(1, 2, KEY_VOLUMEDOWN),
42
43 KEY(2, 0, KEY_MENU),
44 KEY(2, 1, KEY_SEARCH),
45 KEY(2, 2, KEY_VOLUMEUP),
46};
47
48static const struct matrix_keymap_data keymap_data = {
49 .keymap = kbd_keymap,
50 .keymap_size = ARRAY_SIZE(kbd_keymap),
51};
52
53static struct tegra_kbc_wake_key enterprise_wake_cfg[] = {
54 [0] = {
55 .row = 0,
56 .col = 0,
57 },
58 [1] = {
59 .row = 1,
60 .col = 0,
61 },
62 [2] = {
63 .row = 1,
64 .col = 1,
65 },
66 [3] = {
67 .row = 2,
68 .col = 0,
69 },
70};
71
72static struct tegra_kbc_platform_data enterprise_kbc_platform_data = {
73 .debounce_cnt = 20 * 32, /* 20 ms debaunce time */
74 .repeat_cnt = 1,
75 .scan_count = 30,
76 .wakeup = true,
77 .keymap_data = &keymap_data,
78 .wake_cnt = 4,
79 .wake_cfg = &enterprise_wake_cfg[0],
80#ifdef CONFIG_ANDROID
81 .disable_ev_rep = true,
82#endif
83};
84
85int __init enterprise_kbc_init(void)
86{
87 struct tegra_kbc_platform_data *data = &enterprise_kbc_platform_data;
88 int i;
89 tegra_kbc_device.dev.platform_data = &enterprise_kbc_platform_data;
90 pr_info("Registering tegra-kbc\n");
91
92 BUG_ON((KBC_MAX_ROW + KBC_MAX_COL) > KBC_MAX_GPIO);
93 for (i = 0; i < ENTERPRISE_ROW_COUNT; i++) {
94 data->pin_cfg[i].num = i;
95 data->pin_cfg[i].is_row = true;
96 data->pin_cfg[i].en = true;
97 }
98 for (i = 0; i < ENTERPRISE_COL_COUNT; i++) {
99 data->pin_cfg[i + KBC_PIN_GPIO_16].num = i;
100 data->pin_cfg[i + KBC_PIN_GPIO_16].en = true;
101 }
102
103 platform_device_register(&tegra_kbc_device);
104 pr_info("Registering successful tegra-kbc\n");
105 return 0;
106}
107
diff --git a/arch/arm/mach-tegra/board-enterprise-memory.c b/arch/arm/mach-tegra/board-enterprise-memory.c
new file mode 100644
index 00000000000..fca1a08ed70
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-memory.c
@@ -0,0 +1,761 @@
1/*
2 * Copyright (C) 2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22#include "board-enterprise.h"
23#include "tegra3_emc.h"
24#include "board.h"
25
26
27static const struct tegra_emc_table enterprise_emc_tables_h5tc2g[] = {
28 {
29 0x32, /* Rev 3.2 */
30 12750, /* SDRAM frequency */
31 {
32 0x00000000, /* EMC_RC */
33 0x00000001, /* EMC_RFC */
34 0x00000002, /* EMC_RAS */
35 0x00000002, /* EMC_RP */
36 0x00000004, /* EMC_R2W */
37 0x00000004, /* EMC_W2R */
38 0x00000001, /* EMC_R2P */
39 0x00000005, /* EMC_W2P */
40 0x00000002, /* EMC_RD_RCD */
41 0x00000002, /* EMC_WR_RCD */
42 0x00000001, /* EMC_RRD */
43 0x00000001, /* EMC_REXT */
44 0x00000000, /* EMC_WEXT */
45 0x00000001, /* EMC_WDV */
46 0x00000003, /* EMC_QUSE */
47 0x00000001, /* EMC_QRST */
48 0x00000009, /* EMC_QSAFE */
49 0x0000000a, /* EMC_RDV */
50 0x0000002f, /* EMC_REFRESH */
51 0x00000000, /* EMC_BURST_REFRESH_NUM */
52 0x0000000b, /* EMC_PRE_REFRESH_REQ_CNT */
53 0x00000001, /* EMC_PDEX2WR */
54 0x00000001, /* EMC_PDEX2RD */
55 0x00000002, /* EMC_PCHG2PDEN */
56 0x00000000, /* EMC_ACT2PDEN */
57 0x00000001, /* EMC_AR2PDEN */
58 0x00000007, /* EMC_RW2PDEN */
59 0x00000002, /* EMC_TXSR */
60 0x00000002, /* EMC_TXSRDLL */
61 0x00000003, /* EMC_TCKE */
62 0x00000008, /* EMC_TFAW */
63 0x00000004, /* EMC_TRPAB */
64 0x00000001, /* EMC_TCLKSTABLE */
65 0x00000002, /* EMC_TCLKSTOP */
66 0x00000036, /* EMC_TREFBW */
67 0x00000004, /* EMC_QUSE_EXTRA */
68 0x00000004, /* EMC_FBIO_CFG6 */
69 0x00000000, /* EMC_ODT_WRITE */
70 0x00000000, /* EMC_ODT_READ */
71 0x00004282, /* EMC_FBIO_CFG5 */
72 0x007800a4, /* EMC_CFG_DIG_DLL */
73 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
74 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
75 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
76 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
77 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
78 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
79 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
80 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
81 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
82 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
83 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
84 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
85 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
86 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
87 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
88 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
89 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
90 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
91 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
92 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
93 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
94 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
95 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
96 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
97 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
98 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
99 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
100 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
101 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
102 0x00100220, /* EMC_XM2CMDPADCTRL */
103 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
104 0x00000000, /* EMC_XM2DQPADCTRL2 */
105 0x77ffc004, /* EMC_XM2CLKPADCTRL */
106 0x01f1f008, /* EMC_XM2COMPPADCTRL */
107 0x00000000, /* EMC_XM2VTTGENPADCTRL */
108 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
109 0x08000068, /* EMC_XM2QUSEPADCTRL */
110 0x08000000, /* EMC_XM2DQSPADCTRL3 */
111 0x00000802, /* EMC_CTT_TERM_CTRL */
112 0x00064000, /* EMC_ZCAL_INTERVAL */
113 0x00000009, /* EMC_ZCAL_WAIT_CNT */
114 0x00090009, /* EMC_MRS_WAIT_CNT */
115 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
116 0x00000000, /* EMC_CTT */
117 0x00000000, /* EMC_CTT_DURATION */
118 0x80000164, /* EMC_DYN_SELF_REF_CONTROL */
119 0x00050001, /* MC_EMEM_ARB_CFG */
120 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
121 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
122 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
123 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
124 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
125 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
126 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
127 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
128 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
129 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
130 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
131 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
132 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
133 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
134 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
135 0x77230303, /* MC_EMEM_ARB_MISC0 */
136 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
137 0x50000000, /* EMC_FBIO_SPARE */
138 0xff00ff00, /* EMC_CFG_RSV */
139 },
140 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
141 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
142 0x00000001, /* EMC_CFG.PERIODIC_QRST */
143 0x00000000, /* Mode Register 0 */
144 0x00010022, /* Mode Register 1 */
145 0x00020001, /* Mode Register 2 */
146 0x00000001, /* EMC_CFG.DYN_SELF_REF */
147 },
148 {
149 0x32, /* Rev 3.2 */
150 25500, /* SDRAM frequency */
151 {
152 0x00000001, /* EMC_RC */
153 0x00000003, /* EMC_RFC */
154 0x00000002, /* EMC_RAS */
155 0x00000002, /* EMC_RP */
156 0x00000004, /* EMC_R2W */
157 0x00000004, /* EMC_W2R */
158 0x00000001, /* EMC_R2P */
159 0x00000005, /* EMC_W2P */
160 0x00000002, /* EMC_RD_RCD */
161 0x00000002, /* EMC_WR_RCD */
162 0x00000001, /* EMC_RRD */
163 0x00000001, /* EMC_REXT */
164 0x00000000, /* EMC_WEXT */
165 0x00000001, /* EMC_WDV */
166 0x00000003, /* EMC_QUSE */
167 0x00000001, /* EMC_QRST */
168 0x00000009, /* EMC_QSAFE */
169 0x0000000a, /* EMC_RDV */
170 0x0000005e, /* EMC_REFRESH */
171 0x00000000, /* EMC_BURST_REFRESH_NUM */
172 0x00000017, /* EMC_PRE_REFRESH_REQ_CNT */
173 0x00000001, /* EMC_PDEX2WR */
174 0x00000001, /* EMC_PDEX2RD */
175 0x00000002, /* EMC_PCHG2PDEN */
176 0x00000000, /* EMC_ACT2PDEN */
177 0x00000001, /* EMC_AR2PDEN */
178 0x00000007, /* EMC_RW2PDEN */
179 0x00000004, /* EMC_TXSR */
180 0x00000004, /* EMC_TXSRDLL */
181 0x00000003, /* EMC_TCKE */
182 0x00000008, /* EMC_TFAW */
183 0x00000004, /* EMC_TRPAB */
184 0x00000004, /* EMC_TCLKSTABLE */
185 0x00000002, /* EMC_TCLKSTOP */
186 0x00000068, /* EMC_TREFBW */
187 0x00000004, /* EMC_QUSE_EXTRA */
188 0x00000004, /* EMC_FBIO_CFG6 */
189 0x00000000, /* EMC_ODT_WRITE */
190 0x00000000, /* EMC_ODT_READ */
191 0x00004282, /* EMC_FBIO_CFG5 */
192 0x007800a4, /* EMC_CFG_DIG_DLL */
193 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
194 0x00090000, /* EMC_DLL_XFORM_DQS0 */
195 0x00090000, /* EMC_DLL_XFORM_DQS1 */
196 0x00090000, /* EMC_DLL_XFORM_DQS2 */
197 0x00090000, /* EMC_DLL_XFORM_DQS3 */
198 0x00000010, /* EMC_DLL_XFORM_DQS4 */
199 0x00000010, /* EMC_DLL_XFORM_DQS5 */
200 0x00000010, /* EMC_DLL_XFORM_DQS6 */
201 0x00000010, /* EMC_DLL_XFORM_DQS7 */
202 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
203 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
204 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
205 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
206 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
207 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
208 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
209 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
210 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
211 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
212 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
213 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
214 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
215 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
216 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
217 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
218 0x00088000, /* EMC_DLL_XFORM_DQ0 */
219 0x00088000, /* EMC_DLL_XFORM_DQ1 */
220 0x00088000, /* EMC_DLL_XFORM_DQ2 */
221 0x00088000, /* EMC_DLL_XFORM_DQ3 */
222 0x00100220, /* EMC_XM2CMDPADCTRL */
223 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
224 0x00000000, /* EMC_XM2DQPADCTRL2 */
225 0x77ffc004, /* EMC_XM2CLKPADCTRL */
226 0x01f1f008, /* EMC_XM2COMPPADCTRL */
227 0x00000000, /* EMC_XM2VTTGENPADCTRL */
228 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
229 0x08000068, /* EMC_XM2QUSEPADCTRL */
230 0x08000000, /* EMC_XM2DQSPADCTRL3 */
231 0x00000802, /* EMC_CTT_TERM_CTRL */
232 0x00064000, /* EMC_ZCAL_INTERVAL */
233 0x0000000a, /* EMC_ZCAL_WAIT_CNT */
234 0x00090009, /* EMC_MRS_WAIT_CNT */
235 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
236 0x00000000, /* EMC_CTT */
237 0x00000000, /* EMC_CTT_DURATION */
238 0x800001c2, /* EMC_DYN_SELF_REF_CONTROL */
239 0x00020001, /* MC_EMEM_ARB_CFG */
240 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
241 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
242 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
243 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
244 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
245 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
246 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
247 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
248 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
249 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
250 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
251 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
252 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
253 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
254 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
255 0x74030303, /* MC_EMEM_ARB_MISC0 */
256 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
257 0x50000000, /* EMC_FBIO_SPARE */
258 0xff00ff00, /* EMC_CFG_RSV */
259 },
260 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
261 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
262 0x00000001, /* EMC_CFG.PERIODIC_QRST */
263 0x00000000, /* Mode Register 0 */
264 0x00010022, /* Mode Register 1 */
265 0x00020001, /* Mode Register 2 */
266 0x00000001, /* EMC_CFG.DYN_SELF_REF */
267 },
268 {
269 0x32, /* Rev 3.2 */
270 51000, /* SDRAM frequency */
271 {
272 0x00000003, /* EMC_RC */
273 0x00000006, /* EMC_RFC */
274 0x00000002, /* EMC_RAS */
275 0x00000002, /* EMC_RP */
276 0x00000004, /* EMC_R2W */
277 0x00000004, /* EMC_W2R */
278 0x00000001, /* EMC_R2P */
279 0x00000005, /* EMC_W2P */
280 0x00000002, /* EMC_RD_RCD */
281 0x00000002, /* EMC_WR_RCD */
282 0x00000001, /* EMC_RRD */
283 0x00000001, /* EMC_REXT */
284 0x00000000, /* EMC_WEXT */
285 0x00000001, /* EMC_WDV */
286 0x00000003, /* EMC_QUSE */
287 0x00000001, /* EMC_QRST */
288 0x00000009, /* EMC_QSAFE */
289 0x0000000a, /* EMC_RDV */
290 0x000000c0, /* EMC_REFRESH */
291 0x00000000, /* EMC_BURST_REFRESH_NUM */
292 0x00000030, /* EMC_PRE_REFRESH_REQ_CNT */
293 0x00000001, /* EMC_PDEX2WR */
294 0x00000001, /* EMC_PDEX2RD */
295 0x00000002, /* EMC_PCHG2PDEN */
296 0x00000000, /* EMC_ACT2PDEN */
297 0x00000001, /* EMC_AR2PDEN */
298 0x00000007, /* EMC_RW2PDEN */
299 0x00000008, /* EMC_TXSR */
300 0x00000008, /* EMC_TXSRDLL */
301 0x00000003, /* EMC_TCKE */
302 0x00000008, /* EMC_TFAW */
303 0x00000004, /* EMC_TRPAB */
304 0x00000004, /* EMC_TCLKSTABLE */
305 0x00000002, /* EMC_TCLKSTOP */
306 0x000000d5, /* EMC_TREFBW */
307 0x00000004, /* EMC_QUSE_EXTRA */
308 0x00000004, /* EMC_FBIO_CFG6 */
309 0x00000000, /* EMC_ODT_WRITE */
310 0x00000000, /* EMC_ODT_READ */
311 0x00004282, /* EMC_FBIO_CFG5 */
312 0x007800a4, /* EMC_CFG_DIG_DLL */
313 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
314 0x00090000, /* EMC_DLL_XFORM_DQS0 */
315 0x00090000, /* EMC_DLL_XFORM_DQS1 */
316 0x00090000, /* EMC_DLL_XFORM_DQS2 */
317 0x00090000, /* EMC_DLL_XFORM_DQS3 */
318 0x00000010, /* EMC_DLL_XFORM_DQS4 */
319 0x00000010, /* EMC_DLL_XFORM_DQS5 */
320 0x00000010, /* EMC_DLL_XFORM_DQS6 */
321 0x00000010, /* EMC_DLL_XFORM_DQS7 */
322 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
323 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
324 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
325 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
326 0x00000018, /* EMC_DLL_XFORM_QUSE4 */
327 0x00000018, /* EMC_DLL_XFORM_QUSE5 */
328 0x00000018, /* EMC_DLL_XFORM_QUSE6 */
329 0x00000018, /* EMC_DLL_XFORM_QUSE7 */
330 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
331 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
332 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
333 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
334 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
335 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
336 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
337 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
338 0x00088000, /* EMC_DLL_XFORM_DQ0 */
339 0x00088000, /* EMC_DLL_XFORM_DQ1 */
340 0x00088000, /* EMC_DLL_XFORM_DQ2 */
341 0x00088000, /* EMC_DLL_XFORM_DQ3 */
342 0x00100220, /* EMC_XM2CMDPADCTRL */
343 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
344 0x00000000, /* EMC_XM2DQPADCTRL2 */
345 0x77ffc004, /* EMC_XM2CLKPADCTRL */
346 0x01f1f008, /* EMC_XM2COMPPADCTRL */
347 0x00000000, /* EMC_XM2VTTGENPADCTRL */
348 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
349 0x08000068, /* EMC_XM2QUSEPADCTRL */
350 0x08000000, /* EMC_XM2DQSPADCTRL3 */
351 0x00000802, /* EMC_CTT_TERM_CTRL */
352 0x00064000, /* EMC_ZCAL_INTERVAL */
353 0x00000013, /* EMC_ZCAL_WAIT_CNT */
354 0x00090009, /* EMC_MRS_WAIT_CNT */
355 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
356 0x00000000, /* EMC_CTT */
357 0x00000000, /* EMC_CTT_DURATION */
358 0x80000287, /* EMC_DYN_SELF_REF_CONTROL */
359 0x00010001, /* MC_EMEM_ARB_CFG */
360 0xc000000a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
361 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
362 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
363 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
364 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
365 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
366 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
367 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
368 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
369 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
370 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
371 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
372 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
373 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
374 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
375 0x72c30303, /* MC_EMEM_ARB_MISC0 */
376 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
377 0x50000000, /* EMC_FBIO_SPARE */
378 0xff00ff00, /* EMC_CFG_RSV */
379 },
380 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
381 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
382 0x00000001, /* EMC_CFG.PERIODIC_QRST */
383 0x00000000, /* Mode Register 0 */
384 0x00010022, /* Mode Register 1 */
385 0x00020001, /* Mode Register 2 */
386 0x00000001, /* EMC_CFG.DYN_SELF_REF */
387 },
388 {
389 0x32, /* Rev 3.2 */
390 102000, /* SDRAM frequency */
391 {
392 0x00000006, /* EMC_RC */
393 0x0000000d, /* EMC_RFC */
394 0x00000004, /* EMC_RAS */
395 0x00000002, /* EMC_RP */
396 0x00000004, /* EMC_R2W */
397 0x00000004, /* EMC_W2R */
398 0x00000001, /* EMC_R2P */
399 0x00000005, /* EMC_W2P */
400 0x00000002, /* EMC_RD_RCD */
401 0x00000002, /* EMC_WR_RCD */
402 0x00000001, /* EMC_RRD */
403 0x00000001, /* EMC_REXT */
404 0x00000000, /* EMC_WEXT */
405 0x00000001, /* EMC_WDV */
406 0x00000003, /* EMC_QUSE */
407 0x00000001, /* EMC_QRST */
408 0x00000009, /* EMC_QSAFE */
409 0x0000000a, /* EMC_RDV */
410 0x00000181, /* EMC_REFRESH */
411 0x00000000, /* EMC_BURST_REFRESH_NUM */
412 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
413 0x00000001, /* EMC_PDEX2WR */
414 0x00000001, /* EMC_PDEX2RD */
415 0x00000002, /* EMC_PCHG2PDEN */
416 0x00000000, /* EMC_ACT2PDEN */
417 0x00000001, /* EMC_AR2PDEN */
418 0x00000007, /* EMC_RW2PDEN */
419 0x0000000f, /* EMC_TXSR */
420 0x0000000f, /* EMC_TXSRDLL */
421 0x00000003, /* EMC_TCKE */
422 0x00000008, /* EMC_TFAW */
423 0x00000004, /* EMC_TRPAB */
424 0x00000004, /* EMC_TCLKSTABLE */
425 0x00000002, /* EMC_TCLKSTOP */
426 0x000001a9, /* EMC_TREFBW */
427 0x00000004, /* EMC_QUSE_EXTRA */
428 0x00000006, /* EMC_FBIO_CFG6 */
429 0x00000000, /* EMC_ODT_WRITE */
430 0x00000000, /* EMC_ODT_READ */
431 0x00004282, /* EMC_FBIO_CFG5 */
432 0x007800a4, /* EMC_CFG_DIG_DLL */
433 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
434 0x00090000, /* EMC_DLL_XFORM_DQS0 */
435 0x00090000, /* EMC_DLL_XFORM_DQS1 */
436 0x00090000, /* EMC_DLL_XFORM_DQS2 */
437 0x00090000, /* EMC_DLL_XFORM_DQS3 */
438 0x00000010, /* EMC_DLL_XFORM_DQS4 */
439 0x00000010, /* EMC_DLL_XFORM_DQS5 */
440 0x00000010, /* EMC_DLL_XFORM_DQS6 */
441 0x00000010, /* EMC_DLL_XFORM_DQS7 */
442 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
443 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
444 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
445 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
446 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
447 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
448 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
449 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
450 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
451 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
452 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
453 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
454 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
455 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
456 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
457 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
458 0x00088000, /* EMC_DLL_XFORM_DQ0 */
459 0x00088000, /* EMC_DLL_XFORM_DQ1 */
460 0x00088000, /* EMC_DLL_XFORM_DQ2 */
461 0x00088000, /* EMC_DLL_XFORM_DQ3 */
462 0x00100220, /* EMC_XM2CMDPADCTRL */
463 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
464 0x00000000, /* EMC_XM2DQPADCTRL2 */
465 0x77ffc004, /* EMC_XM2CLKPADCTRL */
466 0x01f1f008, /* EMC_XM2COMPPADCTRL */
467 0x00000000, /* EMC_XM2VTTGENPADCTRL */
468 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
469 0x08000068, /* EMC_XM2QUSEPADCTRL */
470 0x08000000, /* EMC_XM2DQSPADCTRL3 */
471 0x00000802, /* EMC_CTT_TERM_CTRL */
472 0x00064000, /* EMC_ZCAL_INTERVAL */
473 0x00000025, /* EMC_ZCAL_WAIT_CNT */
474 0x00090009, /* EMC_MRS_WAIT_CNT */
475 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
476 0x00000000, /* EMC_CTT */
477 0x00000000, /* EMC_CTT_DURATION */
478 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
479 0x00000001, /* MC_EMEM_ARB_CFG */
480 0xc0000013, /* MC_EMEM_ARB_OUTSTANDING_REQ */
481 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
482 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
483 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
484 0x00000001, /* MC_EMEM_ARB_TIMING_RAS */
485 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
486 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
487 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
488 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
489 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
490 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
491 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
492 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
493 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
494 0x00060403, /* MC_EMEM_ARB_DA_COVERS */
495 0x72430504, /* MC_EMEM_ARB_MISC0 */
496 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
497 0x50000000, /* EMC_FBIO_SPARE */
498 0xff00ff00, /* EMC_CFG_RSV */
499 },
500 0x0000000a, /* EMC_ZCAL_WAIT_CNT after clock change */
501 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
502 0x00000001, /* EMC_CFG.PERIODIC_QRST */
503 0x00000000, /* Mode Register 0 */
504 0x00010022, /* Mode Register 1 */
505 0x00020001, /* Mode Register 2 */
506 0x00000001, /* EMC_CFG.DYN_SELF_REF */
507 },
508 {
509 0x32, /* Rev 3.2 */
510 204000, /* SDRAM frequency */
511 {
512 0x0000000c, /* EMC_RC */
513 0x0000001a, /* EMC_RFC */
514 0x00000008, /* EMC_RAS */
515 0x00000003, /* EMC_RP */
516 0x00000005, /* EMC_R2W */
517 0x00000004, /* EMC_W2R */
518 0x00000001, /* EMC_R2P */
519 0x00000006, /* EMC_W2P */
520 0x00000003, /* EMC_RD_RCD */
521 0x00000003, /* EMC_WR_RCD */
522 0x00000002, /* EMC_RRD */
523 0x00000002, /* EMC_REXT */
524 0x00000000, /* EMC_WEXT */
525 0x00000001, /* EMC_WDV */
526 0x00000003, /* EMC_QUSE */
527 0x00000001, /* EMC_QRST */
528 0x0000000b, /* EMC_QSAFE */
529 0x0000000a, /* EMC_RDV */
530 0x00000303, /* EMC_REFRESH */
531 0x00000000, /* EMC_BURST_REFRESH_NUM */
532 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
533 0x00000001, /* EMC_PDEX2WR */
534 0x00000001, /* EMC_PDEX2RD */
535 0x00000003, /* EMC_PCHG2PDEN */
536 0x00000000, /* EMC_ACT2PDEN */
537 0x00000001, /* EMC_AR2PDEN */
538 0x00000007, /* EMC_RW2PDEN */
539 0x0000001d, /* EMC_TXSR */
540 0x0000001d, /* EMC_TXSRDLL */
541 0x00000004, /* EMC_TCKE */
542 0x0000000b, /* EMC_TFAW */
543 0x00000005, /* EMC_TRPAB */
544 0x00000004, /* EMC_TCLKSTABLE */
545 0x00000002, /* EMC_TCLKSTOP */
546 0x00000351, /* EMC_TREFBW */
547 0x00000004, /* EMC_QUSE_EXTRA */
548 0x00000006, /* EMC_FBIO_CFG6 */
549 0x00000000, /* EMC_ODT_WRITE */
550 0x00000000, /* EMC_ODT_READ */
551 0x00004282, /* EMC_FBIO_CFG5 */
552 0x004400a4, /* EMC_CFG_DIG_DLL */
553 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
554 0x0007c000, /* EMC_DLL_XFORM_DQS0 */
555 0x0007c000, /* EMC_DLL_XFORM_DQS1 */
556 0x0007c000, /* EMC_DLL_XFORM_DQS2 */
557 0x0007c000, /* EMC_DLL_XFORM_DQS3 */
558 0x00000010, /* EMC_DLL_XFORM_DQS4 */
559 0x00000010, /* EMC_DLL_XFORM_DQS5 */
560 0x00000010, /* EMC_DLL_XFORM_DQS6 */
561 0x00000010, /* EMC_DLL_XFORM_DQS7 */
562 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
563 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
564 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
565 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
566 0x00000018, /* EMC_DLL_XFORM_QUSE4 */
567 0x00000018, /* EMC_DLL_XFORM_QUSE5 */
568 0x00000018, /* EMC_DLL_XFORM_QUSE6 */
569 0x00000018, /* EMC_DLL_XFORM_QUSE7 */
570 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
571 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
572 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
573 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
574 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
575 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
576 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
577 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
578 0x00088000, /* EMC_DLL_XFORM_DQ0 */
579 0x00088000, /* EMC_DLL_XFORM_DQ1 */
580 0x00088000, /* EMC_DLL_XFORM_DQ2 */
581 0x00088000, /* EMC_DLL_XFORM_DQ3 */
582 0x000f0220, /* EMC_XM2CMDPADCTRL */
583 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
584 0x00000000, /* EMC_XM2DQPADCTRL2 */
585 0x77ffc004, /* EMC_XM2CLKPADCTRL */
586 0x01f1f008, /* EMC_XM2COMPPADCTRL */
587 0x00000000, /* EMC_XM2VTTGENPADCTRL */
588 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
589 0x08000068, /* EMC_XM2QUSEPADCTRL */
590 0x08000000, /* EMC_XM2DQSPADCTRL3 */
591 0x00000802, /* EMC_CTT_TERM_CTRL */
592 0x00064000, /* EMC_ZCAL_INTERVAL */
593 0x0000004a, /* EMC_ZCAL_WAIT_CNT */
594 0x00090009, /* EMC_MRS_WAIT_CNT */
595 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
596 0x00000000, /* EMC_CTT */
597 0x00000000, /* EMC_CTT_DURATION */
598 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
599 0x00000003, /* MC_EMEM_ARB_CFG */
600 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
601 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
602 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
603 0x00000006, /* MC_EMEM_ARB_TIMING_RC */
604 0x00000003, /* MC_EMEM_ARB_TIMING_RAS */
605 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
606 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
607 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
608 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
609 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
610 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
611 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
612 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
613 0x02030001, /* MC_EMEM_ARB_DA_TURNS */
614 0x00070506, /* MC_EMEM_ARB_DA_COVERS */
615 0x71e40a07, /* MC_EMEM_ARB_MISC0 */
616 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
617 0x50000000, /* EMC_FBIO_SPARE */
618 0xff00ff00, /* EMC_CFG_RSV */
619 },
620 0x00000013, /* EMC_ZCAL_WAIT_CNT after clock change */
621 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
622 0x00000001, /* EMC_CFG.PERIODIC_QRST */
623 0x00000000, /* Mode Register 0 */
624 0x00010042, /* Mode Register 1 */
625 0x00020001, /* Mode Register 2 */
626 0x00000001, /* EMC_CFG.DYN_SELF_REF */
627 },
628 {
629 0x32, /* Rev 3.2 */
630 400000, /* SDRAM frequency */
631 {
632 0x00000017, /* EMC_RC */
633 0x00000033, /* EMC_RFC */
634 0x00000010, /* EMC_RAS */
635 0x00000007, /* EMC_RP */
636 0x00000007, /* EMC_R2W */
637 0x00000007, /* EMC_W2R */
638 0x00000002, /* EMC_R2P */
639 0x0000000a, /* EMC_W2P */
640 0x00000007, /* EMC_RD_RCD */
641 0x00000007, /* EMC_WR_RCD */
642 0x00000003, /* EMC_RRD */
643 0x00000002, /* EMC_REXT */
644 0x00000000, /* EMC_WEXT */
645 0x00000003, /* EMC_WDV */
646 0x00000007, /* EMC_QUSE */
647 0x00000004, /* EMC_QRST */
648 0x0000000b, /* EMC_QSAFE */
649 0x0000000e, /* EMC_RDV */
650 0x000005e9, /* EMC_REFRESH */
651 0x00000000, /* EMC_BURST_REFRESH_NUM */
652 0x0000017a, /* EMC_PRE_REFRESH_REQ_CNT */
653 0x00000002, /* EMC_PDEX2WR */
654 0x00000002, /* EMC_PDEX2RD */
655 0x00000007, /* EMC_PCHG2PDEN */
656 0x00000000, /* EMC_ACT2PDEN */
657 0x00000001, /* EMC_AR2PDEN */
658 0x0000000c, /* EMC_RW2PDEN */
659 0x00000038, /* EMC_TXSR */
660 0x00000038, /* EMC_TXSRDLL */
661 0x00000006, /* EMC_TCKE */
662 0x00000014, /* EMC_TFAW */
663 0x00000009, /* EMC_TRPAB */
664 0x00000004, /* EMC_TCLKSTABLE */
665 0x00000002, /* EMC_TCLKSTOP */
666 0x00000680, /* EMC_TREFBW */
667 0x00000000, /* EMC_QUSE_EXTRA */
668 0x00000006, /* EMC_FBIO_CFG6 */
669 0x00000000, /* EMC_ODT_WRITE */
670 0x00000000, /* EMC_ODT_READ */
671 0x00006282, /* EMC_FBIO_CFG5 */
672 0x001d0084, /* EMC_CFG_DIG_DLL */
673 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
674 0x00024000, /* EMC_DLL_XFORM_DQS0 */
675 0x00024000, /* EMC_DLL_XFORM_DQS1 */
676 0x00024000, /* EMC_DLL_XFORM_DQS2 */
677 0x00024000, /* EMC_DLL_XFORM_DQS3 */
678 0x00000010, /* EMC_DLL_XFORM_DQS4 */
679 0x00000010, /* EMC_DLL_XFORM_DQS5 */
680 0x00000010, /* EMC_DLL_XFORM_DQS6 */
681 0x00000010, /* EMC_DLL_XFORM_DQS7 */
682 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
683 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
684 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
685 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
686 0x00000008, /* EMC_DLL_XFORM_QUSE4 */
687 0x00000008, /* EMC_DLL_XFORM_QUSE5 */
688 0x00000008, /* EMC_DLL_XFORM_QUSE6 */
689 0x00000008, /* EMC_DLL_XFORM_QUSE7 */
690 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
691 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
692 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
693 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
694 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
695 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
696 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
697 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
698 0x00048000, /* EMC_DLL_XFORM_DQ0 */
699 0x00048000, /* EMC_DLL_XFORM_DQ1 */
700 0x00048000, /* EMC_DLL_XFORM_DQ2 */
701 0x00048000, /* EMC_DLL_XFORM_DQ3 */
702 0x00060220, /* EMC_XM2CMDPADCTRL */
703 0x0800003d, /* EMC_XM2DQSPADCTRL2 */
704 0x00000000, /* EMC_XM2DQPADCTRL2 */
705 0x77ffc004, /* EMC_XM2CLKPADCTRL */
706 0x01f1f408, /* EMC_XM2COMPPADCTRL */
707 0x00000000, /* EMC_XM2VTTGENPADCTRL */
708 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
709 0x08000068, /* EMC_XM2QUSEPADCTRL */
710 0x08000000, /* EMC_XM2DQSPADCTRL3 */
711 0x00000802, /* EMC_CTT_TERM_CTRL */
712 0x00064000, /* EMC_ZCAL_INTERVAL */
713 0x00000090, /* EMC_ZCAL_WAIT_CNT */
714 0x000c000c, /* EMC_MRS_WAIT_CNT */
715 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
716 0x00000000, /* EMC_CTT */
717 0x00000000, /* EMC_CTT_DURATION */
718 0x80000ce6, /* EMC_DYN_SELF_REF_CONTROL */
719 0x00000006, /* MC_EMEM_ARB_CFG */
720 0x80000048, /* MC_EMEM_ARB_OUTSTANDING_REQ */
721 0x00000002, /* MC_EMEM_ARB_TIMING_RCD */
722 0x00000003, /* MC_EMEM_ARB_TIMING_RP */
723 0x0000000c, /* MC_EMEM_ARB_TIMING_RC */
724 0x00000007, /* MC_EMEM_ARB_TIMING_RAS */
725 0x00000009, /* MC_EMEM_ARB_TIMING_FAW */
726 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
727 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
728 0x00000006, /* MC_EMEM_ARB_TIMING_WAP2PRE */
729 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
730 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
731 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
732 0x00000004, /* MC_EMEM_ARB_TIMING_W2R */
733 0x04040001, /* MC_EMEM_ARB_DA_TURNS */
734 0x000d090c, /* MC_EMEM_ARB_DA_COVERS */
735 0x71c6120d, /* MC_EMEM_ARB_MISC0 */
736 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
737 0x10000000, /* EMC_FBIO_SPARE */
738 0xff00ff00, /* EMC_CFG_RSV */
739 },
740 0x00000024, /* EMC_ZCAL_WAIT_CNT after clock change */
741 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
742 0x00000001, /* EMC_CFG.PERIODIC_QRST */
743 0x00000000, /* Mode Register 0 */
744 0x00010082, /* Mode Register 1 */
745 0x00020004, /* Mode Register 2 */
746 0x00000000, /* EMC_CFG.DYN_SELF_REF */
747 },
748};
749
750int enterprise_emc_init(void)
751{
752 struct board_info board_info;
753
754 tegra_get_board_info(&board_info);
755
756 if (board_info.fab <= BOARD_FAB_A02)
757 tegra_init_emc(enterprise_emc_tables_h5tc2g,
758 ARRAY_SIZE(enterprise_emc_tables_h5tc2g));
759
760 return 0;
761}
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
new file mode 100644
index 00000000000..9dc5da1f28d
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -0,0 +1,905 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-panel.c
3 *
4 * Copyright (c) 2011-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/resource.h>
25#include <asm/mach-types.h>
26#include <linux/platform_device.h>
27#include <linux/earlysuspend.h>
28#include <linux/tegra_pwm_bl.h>
29#include <asm/atomic.h>
30#include <linux/nvhost.h>
31#include <mach/nvmap.h>
32#include <mach/irqs.h>
33#include <mach/iomap.h>
34#include <mach/dc.h>
35#include <mach/fb.h>
36#include <mach/hardware.h>
37
38#include "board.h"
39#include "board-enterprise.h"
40#include "devices.h"
41#include "gpio-names.h"
42
43#define DC_CTRL_MODE TEGRA_DC_OUT_ONE_SHOT_MODE
44
45/* Select panel to be used. */
46#define AVDD_LCD PMU_TCA6416_GPIO_PORT17
47#define DSI_PANEL_RESET 1
48
49#define enterprise_lvds_shutdown TEGRA_GPIO_PL2
50#define enterprise_hdmi_hpd TEGRA_GPIO_PN7
51
52#define enterprise_dsi_panel_reset TEGRA_GPIO_PW0
53
54#define enterprise_lcd_2d_3d TEGRA_GPIO_PH1
55#define ENTERPRISE_STEREO_3D 0
56#define ENTERPRISE_STEREO_2D 1
57
58#define enterprise_lcd_swp_pl TEGRA_GPIO_PH2
59#define ENTERPRISE_STEREO_LANDSCAPE 0
60#define ENTERPRISE_STEREO_PORTRAIT 1
61
62#define enterprise_lcd_te TEGRA_GPIO_PJ1
63
64#ifdef CONFIG_TEGRA_DC
65static struct regulator *enterprise_dsi_reg;
66static struct regulator *enterprise_lcd_reg;
67
68static struct regulator *enterprise_hdmi_reg;
69static struct regulator *enterprise_hdmi_pll;
70static struct regulator *enterprise_hdmi_vddio;
71#endif
72
73static atomic_t sd_brightness = ATOMIC_INIT(255);
74
75static tegra_dc_bl_output enterprise_bl_output_measured_a02 = {
76 1, 5, 9, 10, 11, 12, 12, 13,
77 13, 14, 14, 15, 15, 16, 16, 17,
78 17, 18, 18, 19, 19, 20, 21, 21,
79 22, 22, 23, 24, 24, 25, 26, 26,
80 27, 27, 28, 29, 29, 31, 31, 32,
81 32, 33, 34, 35, 36, 36, 37, 38,
82 39, 39, 40, 41, 41, 42, 43, 43,
83 44, 45, 45, 46, 47, 47, 48, 49,
84 49, 50, 51, 51, 52, 53, 53, 54,
85 55, 56, 56, 57, 58, 59, 60, 61,
86 61, 62, 63, 64, 65, 65, 66, 67,
87 67, 68, 69, 69, 70, 71, 71, 72,
88 73, 73, 74, 74, 75, 76, 76, 77,
89 77, 78, 79, 79, 80, 81, 82, 83,
90 83, 84, 85, 85, 86, 86, 88, 89,
91 90, 91, 91, 92, 93, 93, 94, 95,
92 95, 96, 97, 97, 98, 99, 99, 100,
93 101, 101, 102, 103, 103, 104, 105, 105,
94 107, 107, 108, 109, 110, 111, 111, 112,
95 113, 113, 114, 115, 115, 116, 117, 117,
96 118, 119, 119, 120, 121, 122, 123, 124,
97 124, 125, 126, 126, 127, 128, 129, 129,
98 130, 131, 131, 132, 133, 133, 134, 135,
99 135, 136, 137, 137, 138, 139, 139, 140,
100 142, 142, 143, 144, 145, 146, 147, 147,
101 148, 149, 149, 150, 151, 152, 153, 153,
102 153, 154, 155, 156, 157, 158, 158, 159,
103 160, 161, 162, 163, 163, 164, 165, 165,
104 166, 166, 167, 168, 169, 169, 170, 170,
105 171, 172, 173, 173, 174, 175, 175, 176,
106 176, 178, 178, 179, 180, 181, 182, 182,
107 183, 184, 185, 186, 186, 187, 188, 188
108};
109
110/* TODO: Measure BL response for this table */
111static tegra_dc_bl_output enterprise_bl_output_measured_a03 = {
112 0, 1, 2, 3, 4, 5, 6, 7,
113 8, 9, 10, 11, 12, 13, 14, 15,
114 16, 17, 18, 19, 20, 21, 22, 23,
115 24, 25, 26, 27, 28, 29, 30, 31,
116 32, 33, 34, 35, 36, 37, 38, 39,
117 40, 41, 42, 43, 44, 45, 46, 47,
118 48, 49, 50, 51, 52, 53, 54, 55,
119 56, 57, 58, 59, 60, 61, 62, 63,
120 64, 65, 66, 67, 68, 69, 70, 71,
121 72, 73, 74, 75, 76, 77, 78, 79,
122 80, 81, 82, 83, 84, 85, 86, 87,
123 88, 89, 90, 91, 92, 93, 94, 95,
124 96, 97, 98, 99, 100, 101, 102, 103,
125 104, 105, 106, 107, 108, 109, 110, 111,
126 112, 113, 114, 115, 116, 117, 118, 119,
127 120, 121, 122, 123, 124, 125, 126, 127,
128 128, 129, 130, 131, 132, 133, 134, 135,
129 136, 137, 138, 139, 140, 141, 142, 143,
130 144, 145, 146, 147, 148, 149, 150, 151,
131 152, 153, 154, 155, 156, 157, 158, 159,
132 160, 161, 162, 163, 164, 165, 166, 167,
133 168, 169, 170, 171, 172, 173, 174, 175,
134 176, 177, 178, 179, 180, 181, 182, 183,
135 184, 185, 186, 187, 188, 189, 190, 191,
136 192, 193, 194, 195, 196, 197, 198, 199,
137 200, 201, 202, 203, 204, 205, 206, 207,
138 208, 209, 210, 211, 212, 213, 214, 215,
139 216, 217, 218, 219, 220, 221, 222, 223,
140 224, 225, 226, 227, 228, 229, 230, 231,
141 232, 233, 234, 235, 236, 237, 238, 239,
142 240, 241, 242, 243, 244, 245, 246, 247,
143 248, 249, 250, 251, 252, 253, 254, 255,
144};
145
146static p_tegra_dc_bl_output bl_output;
147
148static bool kernel_1st_panel_init = true;
149
150static int enterprise_backlight_notify(struct device *unused, int brightness)
151{
152 int cur_sd_brightness = atomic_read(&sd_brightness);
153 int orig_brightness = brightness;
154
155 /* SD brightness is a percentage, 8-bit value. */
156 brightness = (brightness * cur_sd_brightness) / 255;
157
158 /* Apply any backlight response curve */
159 if (brightness > 255)
160 pr_info("Error: Brightness > 255!\n");
161 else
162 brightness = bl_output[brightness];
163
164 return brightness;
165}
166
167static int enterprise_disp1_check_fb(struct device *dev, struct fb_info *info);
168
169/*
170 * In case which_pwm is TEGRA_PWM_PM0,
171 * gpio_conf_to_sfio should be TEGRA_GPIO_PW0: set LCD_CS1_N pin to SFIO
172 * In case which_pwm is TEGRA_PWM_PM1,
173 * gpio_conf_to_sfio should be TEGRA_GPIO_PW1: set LCD_M1 pin to SFIO
174 */
175static struct platform_tegra_pwm_backlight_data enterprise_disp1_backlight_data = {
176 .which_dc = 0,
177 .which_pwm = TEGRA_PWM_PM1,
178 .gpio_conf_to_sfio = TEGRA_GPIO_PW1,
179 .switch_to_sfio = &tegra_gpio_disable,
180 .max_brightness = 255,
181 .dft_brightness = 224,
182 .notify = enterprise_backlight_notify,
183 .period = 0xFF,
184 .clk_div = 0x3FF,
185 .clk_select = 0,
186 /* Only toggle backlight on fb blank notifications for disp1 */
187 .check_fb = enterprise_disp1_check_fb,
188};
189
190static struct platform_device enterprise_disp1_backlight_device = {
191 .name = "tegra-pwm-bl",
192 .id = -1,
193 .dev = {
194 .platform_data = &enterprise_disp1_backlight_data,
195 },
196};
197
198#ifdef CONFIG_TEGRA_DC
199static int enterprise_hdmi_vddio_enable(void)
200{
201 int ret;
202 if (!enterprise_hdmi_vddio) {
203 enterprise_hdmi_vddio = regulator_get(NULL, "hdmi_5v0");
204 if (IS_ERR_OR_NULL(enterprise_hdmi_vddio)) {
205 ret = PTR_ERR(enterprise_hdmi_vddio);
206 pr_err("hdmi: couldn't get regulator hdmi_5v0\n");
207 enterprise_hdmi_vddio = NULL;
208 return ret;
209 }
210 }
211 ret = regulator_enable(enterprise_hdmi_vddio);
212 if (ret < 0) {
213 pr_err("hdmi: couldn't enable regulator hdmi_5v0\n");
214 regulator_put(enterprise_hdmi_vddio);
215 enterprise_hdmi_vddio = NULL;
216 return ret;
217 }
218 return ret;
219}
220
221static int enterprise_hdmi_vddio_disable(void)
222{
223 if (enterprise_hdmi_vddio) {
224 regulator_disable(enterprise_hdmi_vddio);
225 regulator_put(enterprise_hdmi_vddio);
226 enterprise_hdmi_vddio = NULL;
227 }
228 return 0;
229}
230
231static int enterprise_hdmi_enable(void)
232{
233 int ret;
234 if (!enterprise_hdmi_reg) {
235 enterprise_hdmi_reg = regulator_get(NULL, "avdd_hdmi");
236 if (IS_ERR_OR_NULL(enterprise_hdmi_reg)) {
237 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
238 enterprise_hdmi_reg = NULL;
239 return PTR_ERR(enterprise_hdmi_reg);
240 }
241 }
242 ret = regulator_enable(enterprise_hdmi_reg);
243 if (ret < 0) {
244 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
245 return ret;
246 }
247 if (!enterprise_hdmi_pll) {
248 enterprise_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll");
249 if (IS_ERR_OR_NULL(enterprise_hdmi_pll)) {
250 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
251 enterprise_hdmi_pll = NULL;
252 regulator_put(enterprise_hdmi_reg);
253 enterprise_hdmi_reg = NULL;
254 return PTR_ERR(enterprise_hdmi_pll);
255 }
256 }
257 ret = regulator_enable(enterprise_hdmi_pll);
258 if (ret < 0) {
259 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
260 return ret;
261 }
262 return 0;
263}
264
265static int enterprise_hdmi_disable(void)
266{
267
268 regulator_disable(enterprise_hdmi_reg);
269 regulator_put(enterprise_hdmi_reg);
270 enterprise_hdmi_reg = NULL;
271
272 regulator_disable(enterprise_hdmi_pll);
273 regulator_put(enterprise_hdmi_pll);
274 enterprise_hdmi_pll = NULL;
275
276 return 0;
277}
278static struct resource enterprise_disp1_resources[] = {
279 {
280 .name = "irq",
281 .start = INT_DISPLAY_GENERAL,
282 .end = INT_DISPLAY_GENERAL,
283 .flags = IORESOURCE_IRQ,
284 },
285 {
286 .name = "regs",
287 .start = TEGRA_DISPLAY_BASE,
288 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
289 .flags = IORESOURCE_MEM,
290 },
291 {
292 .name = "fbmem",
293 .start = 0, /* Filled in by enterprise_panel_init() */
294 .end = 0, /* Filled in by enterprise_panel_init() */
295 .flags = IORESOURCE_MEM,
296 },
297 {
298 .name = "dsi_regs",
299 .start = TEGRA_DSI_BASE,
300 .end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
301 .flags = IORESOURCE_MEM,
302 },
303};
304
305static struct resource enterprise_disp2_resources[] = {
306 {
307 .name = "irq",
308 .start = INT_DISPLAY_B_GENERAL,
309 .end = INT_DISPLAY_B_GENERAL,
310 .flags = IORESOURCE_IRQ,
311 },
312 {
313 .name = "regs",
314 .start = TEGRA_DISPLAY2_BASE,
315 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
316 .flags = IORESOURCE_MEM,
317 },
318 {
319 .name = "fbmem",
320 .flags = IORESOURCE_MEM,
321 .start = 0,
322 .end = 0,
323 },
324 {
325 .name = "hdmi_regs",
326 .start = TEGRA_HDMI_BASE,
327 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
328 .flags = IORESOURCE_MEM,
329 },
330};
331
332static struct tegra_dc_sd_settings enterprise_sd_settings = {
333 .enable = 1, /* Normal mode operation */
334 .use_auto_pwm = false,
335 .hw_update_delay = 0,
336 .bin_width = -1,
337 .aggressiveness = 1,
338 .phase_in_adjustments = true,
339 .use_vid_luma = false,
340 /* Default video coefficients */
341 .coeff = {5, 9, 2},
342 .fc = {0, 0},
343 /* Immediate backlight changes */
344 .blp = {1024, 255},
345 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
346 /* Default BL TF */
347 .bltf = {
348 {
349 {57, 65, 74, 83},
350 {93, 103, 114, 126},
351 {138, 151, 165, 179},
352 {194, 209, 225, 242},
353 },
354 {
355 {58, 66, 75, 84},
356 {94, 105, 116, 127},
357 {140, 153, 166, 181},
358 {196, 211, 227, 244},
359 },
360 {
361 {60, 68, 77, 87},
362 {97, 107, 119, 130},
363 {143, 156, 170, 184},
364 {199, 215, 231, 248},
365 },
366 {
367 {64, 73, 82, 91},
368 {102, 113, 124, 137},
369 {149, 163, 177, 192},
370 {207, 223, 240, 255},
371 },
372 },
373 /* Default LUT */
374 .lut = {
375 {
376 {250, 250, 250},
377 {194, 194, 194},
378 {149, 149, 149},
379 {113, 113, 113},
380 {82, 82, 82},
381 {56, 56, 56},
382 {34, 34, 34},
383 {15, 15, 15},
384 {0, 0, 0},
385 },
386 {
387 {246, 246, 246},
388 {191, 191, 191},
389 {147, 147, 147},
390 {111, 111, 111},
391 {80, 80, 80},
392 {55, 55, 55},
393 {33, 33, 33},
394 {14, 14, 14},
395 {0, 0, 0},
396 },
397 {
398 {239, 239, 239},
399 {185, 185, 185},
400 {142, 142, 142},
401 {107, 107, 107},
402 {77, 77, 77},
403 {52, 52, 52},
404 {30, 30, 30},
405 {12, 12, 12},
406 {0, 0, 0},
407 },
408 {
409 {224, 224, 224},
410 {173, 173, 173},
411 {133, 133, 133},
412 {99, 99, 99},
413 {70, 70, 70},
414 {46, 46, 46},
415 {25, 25, 25},
416 {7, 7, 7},
417 {0, 0, 0},
418 },
419 },
420 .sd_brightness = &sd_brightness,
421 .bl_device = &enterprise_disp1_backlight_device,
422};
423
424static struct tegra_fb_data enterprise_hdmi_fb_data = {
425 .win = 0,
426 .xres = 1366,
427 .yres = 768,
428 .bits_per_pixel = 32,
429 .flags = TEGRA_FB_FLIP_ON_PROBE,
430};
431
432static struct tegra_dc_out enterprise_disp2_out = {
433 .type = TEGRA_DC_OUT_HDMI,
434 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
435 .parent_clk = "pll_d2_out0",
436
437 .dcc_bus = 3,
438 .hotplug_gpio = enterprise_hdmi_hpd,
439
440 .max_pixclock = KHZ2PICOS(148500),
441
442 .align = TEGRA_DC_ALIGN_MSB,
443 .order = TEGRA_DC_ORDER_RED_BLUE,
444
445 .enable = enterprise_hdmi_enable,
446 .disable = enterprise_hdmi_disable,
447 .postsuspend = enterprise_hdmi_vddio_disable,
448 .hotplug_init = enterprise_hdmi_vddio_enable,
449};
450
451static struct tegra_dc_platform_data enterprise_disp2_pdata = {
452 .flags = 0,
453 .default_out = &enterprise_disp2_out,
454 .fb = &enterprise_hdmi_fb_data,
455 .emc_clk_rate = 300000000,
456};
457
458static int enterprise_dsi_panel_enable(void)
459{
460 int ret;
461 struct board_info board_info;
462
463 tegra_get_board_info(&board_info);
464
465 if (enterprise_dsi_reg == NULL) {
466 enterprise_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
467 if (IS_ERR_OR_NULL(enterprise_dsi_reg)) {
468 pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
469 enterprise_dsi_reg = NULL;
470 return PTR_ERR(enterprise_dsi_reg);
471 }
472 }
473 ret = regulator_enable(enterprise_dsi_reg);
474 if (ret < 0) {
475 printk(KERN_ERR
476 "DSI regulator avdd_dsi_csi could not be enabled\n");
477 return ret;
478 }
479
480#if DSI_PANEL_RESET
481
482 if (board_info.fab >= BOARD_FAB_A03) {
483 if (enterprise_lcd_reg == NULL) {
484 enterprise_lcd_reg = regulator_get(NULL, "lcd_vddio_en");
485 if (IS_ERR_OR_NULL(enterprise_lcd_reg)) {
486 pr_err("Could not get regulator lcd_vddio_en\n");
487 ret = PTR_ERR(enterprise_lcd_reg);
488 enterprise_lcd_reg = NULL;
489 return ret;
490 }
491 }
492 if (enterprise_lcd_reg != NULL) {
493 ret = regulator_enable(enterprise_lcd_reg);
494 if (ret < 0) {
495 pr_err("Could not enable lcd_vddio_en\n");
496 return ret;
497 }
498 }
499 }
500
501 if (kernel_1st_panel_init != true) {
502 ret = gpio_request(enterprise_dsi_panel_reset, "panel reset");
503 if (ret < 0)
504 return ret;
505
506 ret = gpio_direction_output(enterprise_dsi_panel_reset, 0);
507 if (ret < 0) {
508 gpio_free(enterprise_dsi_panel_reset);
509 return ret;
510 }
511 tegra_gpio_enable(enterprise_dsi_panel_reset);
512
513 gpio_set_value(enterprise_dsi_panel_reset, 0);
514 udelay(2000);
515 gpio_set_value(enterprise_dsi_panel_reset, 1);
516 mdelay(20);
517 }
518#endif
519
520 return ret;
521}
522
523static int enterprise_dsi_panel_disable(void)
524{
525 if (enterprise_lcd_reg != NULL)
526 regulator_disable(enterprise_lcd_reg);
527
528#if DSI_PANEL_RESET
529 if (kernel_1st_panel_init != true) {
530 tegra_gpio_disable(enterprise_dsi_panel_reset);
531 gpio_free(enterprise_dsi_panel_reset);
532 } else
533 kernel_1st_panel_init = false;
534#endif
535 return 0;
536}
537#endif
538
539static void enterprise_stereo_set_mode(int mode)
540{
541 switch (mode) {
542 case TEGRA_DC_STEREO_MODE_2D:
543 gpio_set_value(TEGRA_GPIO_PH1, ENTERPRISE_STEREO_2D);
544 break;
545 case TEGRA_DC_STEREO_MODE_3D:
546 gpio_set_value(TEGRA_GPIO_PH1, ENTERPRISE_STEREO_3D);
547 break;
548 }
549}
550
551static void enterprise_stereo_set_orientation(int mode)
552{
553 switch (mode) {
554 case TEGRA_DC_STEREO_LANDSCAPE:
555 gpio_set_value(TEGRA_GPIO_PH2, ENTERPRISE_STEREO_LANDSCAPE);
556 break;
557 case TEGRA_DC_STEREO_PORTRAIT:
558 gpio_set_value(TEGRA_GPIO_PH2, ENTERPRISE_STEREO_PORTRAIT);
559 break;
560 }
561}
562
563#ifdef CONFIG_TEGRA_DC
564static int enterprise_dsi_panel_postsuspend(void)
565{
566 /* Do nothing for enterprise dsi panel */
567 return 0;
568}
569#endif
570
571static struct tegra_dsi_cmd dsi_init_cmd[]= {
572 DSI_CMD_SHORT(0x05, 0x11, 0x00),
573 DSI_DLY_MS(20),
574#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
575 DSI_CMD_SHORT(0x15, 0x35, 0x00),
576#endif
577 DSI_CMD_SHORT(0x05, 0x29, 0x00),
578 DSI_DLY_MS(20),
579};
580
581static struct tegra_dsi_cmd dsi_early_suspend_cmd[] = {
582 DSI_CMD_SHORT(0x05, 0x28, 0x00),
583 DSI_DLY_MS(20),
584#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
585 DSI_CMD_SHORT(0x05, 0x34, 0x00),
586#endif
587};
588
589static struct tegra_dsi_cmd dsi_late_resume_cmd[] = {
590#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
591 DSI_CMD_SHORT(0x15, 0x35, 0x00),
592#endif
593 DSI_CMD_SHORT(0x05, 0x29, 0x00),
594 DSI_DLY_MS(20),
595};
596
597static struct tegra_dsi_cmd dsi_suspend_cmd[] = {
598 DSI_CMD_SHORT(0x05, 0x28, 0x00),
599 DSI_DLY_MS(20),
600#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
601 DSI_CMD_SHORT(0x05, 0x34, 0x00),
602#endif
603 DSI_CMD_SHORT(0x05, 0x10, 0x00),
604 DSI_DLY_MS(5),
605};
606
607struct tegra_dsi_out enterprise_dsi = {
608 .n_data_lanes = 2,
609 .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
610#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
611 /* For one-shot mode, actual refresh rate is decided by the
612 * frequency of TE signal. Although the frequency of TE is
613 * expected running at rated_refresh_rate (typically 60Hz),
614 * it may vary. Mismatch between freq of DC and TE signal
615 * would cause frame drop. We increase refresh_rate to the
616 * value larger than maximum TE frequency to avoid missing
617 * any TE signal. The value of refresh_rate is also used to
618 * calculate the pixel clock.
619 */
620 .refresh_rate = 66,
621 .rated_refresh_rate = 60,
622#else
623 .refresh_rate = 60,
624#endif
625 .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
626
627 .panel_has_frame_buffer = true,
628 .dsi_instance = 0,
629
630 .panel_reset = DSI_PANEL_RESET,
631 .power_saving_suspend = true,
632 .n_init_cmd = ARRAY_SIZE(dsi_init_cmd),
633 .dsi_init_cmd = dsi_init_cmd,
634
635 .n_early_suspend_cmd = ARRAY_SIZE(dsi_early_suspend_cmd),
636 .dsi_early_suspend_cmd = dsi_early_suspend_cmd,
637
638 .n_late_resume_cmd = ARRAY_SIZE(dsi_late_resume_cmd),
639 .dsi_late_resume_cmd = dsi_late_resume_cmd,
640
641 .n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd),
642 .dsi_suspend_cmd = dsi_suspend_cmd,
643
644 .video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
645 .lp_cmd_mode_freq_khz = 20000,
646
647 /* TODO: Get the vender recommended freq */
648 .lp_read_cmd_mode_freq_khz = 200000,
649};
650
651static struct tegra_stereo_out enterprise_stereo = {
652 .set_mode = &enterprise_stereo_set_mode,
653 .set_orientation = &enterprise_stereo_set_orientation,
654};
655
656#ifdef CONFIG_TEGRA_DC
657static struct tegra_dc_mode enterprise_dsi_modes[] = {
658 {
659 .pclk = 10000000,
660 .h_ref_to_sync = 4,
661 .v_ref_to_sync = 1,
662 .h_sync_width = 16,
663 .v_sync_width = 1,
664 .h_back_porch = 32,
665 .v_back_porch = 1,
666 .h_active = 540,
667 .v_active = 960,
668 .h_front_porch = 32,
669 .v_front_porch = 2,
670 },
671};
672
673static struct tegra_fb_data enterprise_dsi_fb_data = {
674 .win = 0,
675 .xres = 540,
676 .yres = 960,
677 .bits_per_pixel = 32,
678 .flags = TEGRA_FB_FLIP_ON_PROBE,
679};
680
681static struct tegra_dc_out enterprise_disp1_out = {
682 .align = TEGRA_DC_ALIGN_MSB,
683 .order = TEGRA_DC_ORDER_RED_BLUE,
684 .sd_settings = &enterprise_sd_settings,
685
686 .flags = DC_CTRL_MODE,
687
688 .type = TEGRA_DC_OUT_DSI,
689
690 .modes = enterprise_dsi_modes,
691 .n_modes = ARRAY_SIZE(enterprise_dsi_modes),
692
693 .dsi = &enterprise_dsi,
694 .stereo = &enterprise_stereo,
695
696 .enable = enterprise_dsi_panel_enable,
697 .disable = enterprise_dsi_panel_disable,
698 .postsuspend = enterprise_dsi_panel_postsuspend,
699
700 .width = 53,
701 .height = 95,
702};
703static struct tegra_dc_platform_data enterprise_disp1_pdata = {
704 .flags = TEGRA_DC_FLAG_ENABLED,
705 .default_out = &enterprise_disp1_out,
706 .emc_clk_rate = 204000000,
707 .fb = &enterprise_dsi_fb_data,
708};
709
710static struct nvhost_device enterprise_disp1_device = {
711 .name = "tegradc",
712 .id = 0,
713 .resource = enterprise_disp1_resources,
714 .num_resources = ARRAY_SIZE(enterprise_disp1_resources),
715 .dev = {
716 .platform_data = &enterprise_disp1_pdata,
717 },
718};
719
720static int enterprise_disp1_check_fb(struct device *dev, struct fb_info *info)
721{
722 return info->device == &enterprise_disp1_device.dev;
723}
724
725static struct nvhost_device enterprise_disp2_device = {
726 .name = "tegradc",
727 .id = 1,
728 .resource = enterprise_disp2_resources,
729 .num_resources = ARRAY_SIZE(enterprise_disp2_resources),
730 .dev = {
731 .platform_data = &enterprise_disp2_pdata,
732 },
733};
734#endif
735
736#if defined(CONFIG_TEGRA_NVMAP)
737static struct nvmap_platform_carveout enterprise_carveouts[] = {
738 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
739 [1] = {
740 .name = "generic-0",
741 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
742 .base = 0, /* Filled in by enterprise_panel_init() */
743 .size = 0, /* Filled in by enterprise_panel_init() */
744 .buddy_size = SZ_32K,
745 },
746};
747
748static struct nvmap_platform_data enterprise_nvmap_data = {
749 .carveouts = enterprise_carveouts,
750 .nr_carveouts = ARRAY_SIZE(enterprise_carveouts),
751};
752
753static struct platform_device enterprise_nvmap_device = {
754 .name = "tegra-nvmap",
755 .id = -1,
756 .dev = {
757 .platform_data = &enterprise_nvmap_data,
758 },
759};
760#endif
761
762static struct platform_device *enterprise_gfx_devices[] __initdata = {
763#if defined(CONFIG_TEGRA_NVMAP)
764 &enterprise_nvmap_device,
765#endif
766 &tegra_pwfm0_device,
767};
768
769static struct platform_device *enterprise_bl_devices[] = {
770 &enterprise_disp1_backlight_device,
771};
772
773#ifdef CONFIG_HAS_EARLYSUSPEND
774/* put early_suspend/late_resume handlers here for the display in order
775 * to keep the code out of the display driver, keeping it closer to upstream
776 */
777struct early_suspend enterprise_panel_early_suspender;
778
779static void enterprise_panel_early_suspend(struct early_suspend *h)
780{
781 /* power down LCD, add use a black screen for HDMI */
782 if (num_registered_fb > 0)
783 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
784 if (num_registered_fb > 1)
785 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
786#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
787 cpufreq_save_default_governor();
788 cpufreq_set_conservative_governor();
789 cpufreq_set_conservative_governor_param("up_threshold",
790 SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
791
792 cpufreq_set_conservative_governor_param("down_threshold",
793 SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
794
795 cpufreq_set_conservative_governor_param("freq_step",
796 SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
797#endif
798}
799
800static void enterprise_panel_late_resume(struct early_suspend *h)
801{
802 unsigned i;
803
804#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
805 cpufreq_restore_default_governor();
806#endif
807 for (i = 0; i < num_registered_fb; i++)
808 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
809}
810#endif
811
812int __init enterprise_panel_init(void)
813{
814 int err;
815 struct resource __maybe_unused *res;
816 struct board_info board_info;
817
818 tegra_get_board_info(&board_info);
819
820 BUILD_BUG_ON(ARRAY_SIZE(enterprise_bl_output_measured_a03) != 256);
821 BUILD_BUG_ON(ARRAY_SIZE(enterprise_bl_output_measured_a02) != 256);
822
823 if (board_info.fab >= BOARD_FAB_A03) {
824 enterprise_disp1_backlight_data.clk_div = 0x1D;
825 bl_output = enterprise_bl_output_measured_a03;
826 } else
827 bl_output = enterprise_bl_output_measured_a02;
828
829 enterprise_dsi.chip_id = tegra_get_chipid();
830 enterprise_dsi.chip_rev = tegra_get_revision();
831
832#if defined(CONFIG_TEGRA_NVMAP)
833 enterprise_carveouts[1].base = tegra_carveout_start;
834 enterprise_carveouts[1].size = tegra_carveout_size;
835#endif
836
837 tegra_gpio_enable(enterprise_hdmi_hpd);
838 gpio_request(enterprise_hdmi_hpd, "hdmi_hpd");
839 gpio_direction_input(enterprise_hdmi_hpd);
840
841 tegra_gpio_enable(enterprise_lcd_2d_3d);
842 gpio_request(enterprise_lcd_2d_3d, "lcd_2d_3d");
843 gpio_direction_output(enterprise_lcd_2d_3d, 0);
844 enterprise_stereo_set_mode(enterprise_stereo.mode_2d_3d);
845
846 tegra_gpio_enable(enterprise_lcd_swp_pl);
847 gpio_request(enterprise_lcd_swp_pl, "lcd_swp_pl");
848 gpio_direction_output(enterprise_lcd_swp_pl, 0);
849 enterprise_stereo_set_orientation(enterprise_stereo.orientation);
850
851#if !(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
852 tegra_gpio_enable(enterprise_lcd_te);
853 gpio_request(enterprise_lcd_swp_pl, "lcd_te");
854 gpio_direction_input(enterprise_lcd_te);
855#endif
856
857#ifdef CONFIG_HAS_EARLYSUSPEND
858 enterprise_panel_early_suspender.suspend = enterprise_panel_early_suspend;
859 enterprise_panel_early_suspender.resume = enterprise_panel_late_resume;
860 enterprise_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
861 register_early_suspend(&enterprise_panel_early_suspender);
862#endif
863
864#ifdef CONFIG_TEGRA_GRHOST
865 err = nvhost_device_register(&tegra_grhost_device);
866 if (err)
867 return err;
868#endif
869
870 err = platform_add_devices(enterprise_gfx_devices,
871 ARRAY_SIZE(enterprise_gfx_devices));
872
873#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
874 res = nvhost_get_resource_byname(&enterprise_disp1_device,
875 IORESOURCE_MEM, "fbmem");
876 res->start = tegra_fb_start;
877 res->end = tegra_fb_start + tegra_fb_size - 1;
878#endif
879
880 /* Copy the bootloader fb to the fb. */
881 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
882 min(tegra_fb_size, tegra_bootloader_fb_size));
883
884#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
885 if (!err)
886 err = nvhost_device_register(&enterprise_disp1_device);
887
888 res = nvhost_get_resource_byname(&enterprise_disp2_device,
889 IORESOURCE_MEM, "fbmem");
890 res->start = tegra_fb2_start;
891 res->end = tegra_fb2_start + tegra_fb2_size - 1;
892 if (!err)
893 err = nvhost_device_register(&enterprise_disp2_device);
894#endif
895
896#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
897 if (!err)
898 err = nvhost_device_register(&nvavp_device);
899#endif
900
901 if (!err)
902 err = platform_add_devices(enterprise_bl_devices,
903 ARRAY_SIZE(enterprise_bl_devices));
904 return err;
905}
diff --git a/arch/arm/mach-tegra/board-enterprise-pinmux.c b/arch/arm/mach-tegra/board-enterprise-pinmux.c
new file mode 100644
index 00000000000..8d18e3296af
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-pinmux.c
@@ -0,0 +1,568 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-pinmux.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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 <mach/pinmux.h>
20#include "board.h"
21#include "board-enterprise.h"
22#include "gpio-names.h"
23
24#define DEFAULT_DRIVE(_name) \
25 { \
26 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
27 .hsm = TEGRA_HSM_DISABLE, \
28 .schmitt = TEGRA_SCHMITT_ENABLE, \
29 .drive = TEGRA_DRIVE_DIV_1, \
30 .pull_down = TEGRA_PULL_31, \
31 .pull_up = TEGRA_PULL_31, \
32 .slew_rising = TEGRA_SLEW_SLOWEST, \
33 .slew_falling = TEGRA_SLEW_SLOWEST, \
34 }
35/* Setting the drive strength of pins
36 * hsm: Enable High speed mode (ENABLE/DISABLE)
37 * Schimit: Enable/disable schimit (ENABLE/DISABLE)
38 * drive: low power mode (DIV_1, DIV_2, DIV_4, DIV_8)
39 * pulldn_drive - drive down (falling edge) - Driver Output Pull-Down drive
40 * strength code. Value from 0 to 31.
41 * pullup_drive - drive up (rising edge) - Driver Output Pull-Up drive
42 * strength code. Value from 0 to 31.
43 * pulldn_slew - Driver Output Pull-Up slew control code - 2bit code
44 * code 11 is least slewing of signal. code 00 is highest
45 * slewing of the signal.
46 * Value - FASTEST, FAST, SLOW, SLOWEST
47 * pullup_slew - Driver Output Pull-Down slew control code -
48 * code 11 is least slewing of signal. code 00 is highest
49 * slewing of the signal.
50 * Value - FASTEST, FAST, SLOW, SLOWEST
51 */
52#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
53 { \
54 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
55 .hsm = TEGRA_HSM_##_hsm, \
56 .schmitt = TEGRA_SCHMITT_##_schmitt, \
57 .drive = TEGRA_DRIVE_##_drive, \
58 .pull_down = TEGRA_PULL_##_pulldn_drive, \
59 .pull_up = TEGRA_PULL_##_pullup_drive, \
60 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
61 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
62 }
63
64/* !!!FIXME!!!! POPULATE THIS TABLE */
65static __initdata struct tegra_drive_pingroup_config enterprise_drive_pinmux[] = {
66 /* DEFAULT_DRIVE(<pin_group>), */
67 /* SET_DRIVE(ATA, DISABLE, DISABLE, DIV_1, 31, 31, FAST, FAST) */
68
69 /* All I2C pins are driven to maximum drive strength */
70 /* GEN1 I2C */
71 SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
72
73 /* GEN2 I2C */
74 SET_DRIVE(AT5, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
75
76 /* CAM I2C */
77 SET_DRIVE(GME, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
78
79 /* DDC I2C */
80 SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
81
82 /* PWR_I2C */
83 SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
84
85 /* UART3 */
86 SET_DRIVE(UART3, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
87};
88
89#define DEFAULT_PINMUX(_pingroup, _mux, _pupd, _tri, _io) \
90 { \
91 .pingroup = TEGRA_PINGROUP_##_pingroup, \
92 .func = TEGRA_MUX_##_mux, \
93 .pupd = TEGRA_PUPD_##_pupd, \
94 .tristate = TEGRA_TRI_##_tri, \
95 .io = TEGRA_PIN_##_io, \
96 .lock = TEGRA_PIN_LOCK_DEFAULT, \
97 .od = TEGRA_PIN_OD_DEFAULT, \
98 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
99 }
100
101#define I2C_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _od) \
102 { \
103 .pingroup = TEGRA_PINGROUP_##_pingroup, \
104 .func = TEGRA_MUX_##_mux, \
105 .pupd = TEGRA_PUPD_##_pupd, \
106 .tristate = TEGRA_TRI_##_tri, \
107 .io = TEGRA_PIN_##_io, \
108 .lock = TEGRA_PIN_LOCK_##_lock, \
109 .od = TEGRA_PIN_OD_##_od, \
110 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
111 }
112
113#define CEC_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _od) \
114 { \
115 .pingroup = TEGRA_PINGROUP_##_pingroup, \
116 .func = TEGRA_MUX_##_mux, \
117 .pupd = TEGRA_PUPD_##_pupd, \
118 .tristate = TEGRA_TRI_##_tri, \
119 .io = TEGRA_PIN_##_io, \
120 .lock = TEGRA_PIN_LOCK_##_lock, \
121 .od = TEGRA_PIN_OD_##_od, \
122 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
123 }
124
125#define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
126 { \
127 .pingroup = TEGRA_PINGROUP_##_pingroup, \
128 .func = TEGRA_MUX_##_mux, \
129 .pupd = TEGRA_PUPD_##_pupd, \
130 .tristate = TEGRA_TRI_##_tri, \
131 .io = TEGRA_PIN_##_io, \
132 .lock = TEGRA_PIN_LOCK_##_lock, \
133 .od = TEGRA_PIN_OD_DEFAULT, \
134 .ioreset = TEGRA_PIN_IO_RESET_##_ioreset \
135 }
136
137static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
138 /* SDMMC1 pinmux */
139 DEFAULT_PINMUX(SDMMC1_CLK, SDMMC1, NORMAL, NORMAL, INPUT),
140 DEFAULT_PINMUX(SDMMC1_CMD, SDMMC1, PULL_UP, NORMAL, INPUT),
141 DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, PULL_UP, NORMAL, INPUT),
142 DEFAULT_PINMUX(SDMMC1_DAT2, SDMMC1, PULL_UP, NORMAL, INPUT),
143 DEFAULT_PINMUX(SDMMC1_DAT1, SDMMC1, PULL_UP, NORMAL, INPUT),
144 DEFAULT_PINMUX(SDMMC1_DAT0, SDMMC1, PULL_UP, NORMAL, INPUT),
145
146 /* SDMMC3 pinmux */
147 DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT),
148 DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, PULL_UP, NORMAL, INPUT),
149 DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, PULL_UP, NORMAL, INPUT),
150 DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, PULL_UP, NORMAL, INPUT),
151 DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, PULL_UP, NORMAL, INPUT),
152 DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, PULL_UP, NORMAL, INPUT),
153
154 /* SDMMC4 pinmux */
155 DEFAULT_PINMUX(SDMMC4_CLK, SDMMC4, NORMAL, NORMAL, INPUT),
156 DEFAULT_PINMUX(SDMMC4_CMD, SDMMC4, PULL_UP, NORMAL, INPUT),
157 DEFAULT_PINMUX(SDMMC4_DAT0, SDMMC4, PULL_UP, NORMAL, INPUT),
158 DEFAULT_PINMUX(SDMMC4_DAT1, SDMMC4, PULL_UP, NORMAL, INPUT),
159 DEFAULT_PINMUX(SDMMC4_DAT2, SDMMC4, PULL_UP, NORMAL, INPUT),
160 DEFAULT_PINMUX(SDMMC4_DAT3, SDMMC4, PULL_UP, NORMAL, INPUT),
161 DEFAULT_PINMUX(SDMMC4_DAT4, SDMMC4, PULL_UP, NORMAL, INPUT),
162 DEFAULT_PINMUX(SDMMC4_DAT5, SDMMC4, PULL_UP, NORMAL, INPUT),
163 DEFAULT_PINMUX(SDMMC4_DAT6, SDMMC4, PULL_UP, NORMAL, INPUT),
164 DEFAULT_PINMUX(SDMMC4_DAT7, SDMMC4, PULL_UP, NORMAL, INPUT),
165 DEFAULT_PINMUX(SDMMC4_RST_N, RSVD1, PULL_DOWN, NORMAL, INPUT),
166
167 /* I2C1 pinmux */
168 I2C_PINMUX(GEN1_I2C_SCL, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
169 I2C_PINMUX(GEN1_I2C_SDA, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
170
171 /* I2C2 pinmux */
172 I2C_PINMUX(GEN2_I2C_SCL, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
173 I2C_PINMUX(GEN2_I2C_SDA, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
174
175 /* I2C3 pinmux */
176 I2C_PINMUX(CAM_I2C_SCL, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
177 I2C_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
178
179 /* I2C4 pinmux */
180 I2C_PINMUX(DDC_SCL, I2C4, PULL_UP,NORMAL, INPUT, DISABLE, DISABLE),
181 I2C_PINMUX(DDC_SDA, I2C4, PULL_UP,NORMAL, INPUT, DISABLE, DISABLE),
182
183 /* Power I2C pinmux */
184 I2C_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
185 I2C_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
186
187 DEFAULT_PINMUX(ULPI_DATA0, ULPI, NORMAL, NORMAL, INPUT),
188 DEFAULT_PINMUX(ULPI_DATA1, ULPI, NORMAL, NORMAL, INPUT),
189 DEFAULT_PINMUX(ULPI_DATA2, ULPI, NORMAL, NORMAL, INPUT),
190 DEFAULT_PINMUX(ULPI_DATA3, ULPI, NORMAL, NORMAL, INPUT),
191 DEFAULT_PINMUX(ULPI_DATA4, ULPI, NORMAL, NORMAL, INPUT),
192 DEFAULT_PINMUX(ULPI_DATA5, ULPI, NORMAL, NORMAL, INPUT),
193 DEFAULT_PINMUX(ULPI_DATA6, ULPI, NORMAL, NORMAL, INPUT),
194 DEFAULT_PINMUX(ULPI_DATA7, ULPI, NORMAL, NORMAL, INPUT),
195 DEFAULT_PINMUX(ULPI_CLK, ULPI, NORMAL, NORMAL, INPUT),
196 DEFAULT_PINMUX(ULPI_DIR, ULPI, NORMAL, NORMAL, OUTPUT),
197 DEFAULT_PINMUX(ULPI_NXT, ULPI, NORMAL, NORMAL, OUTPUT),
198 DEFAULT_PINMUX(ULPI_STP, ULPI, NORMAL, NORMAL, INPUT),
199 DEFAULT_PINMUX(DAP3_FS, I2S2, NORMAL, NORMAL, INPUT),
200 DEFAULT_PINMUX(DAP3_DIN, I2S2, NORMAL, NORMAL, INPUT),
201 DEFAULT_PINMUX(DAP3_DOUT, I2S2, NORMAL, NORMAL, INPUT),
202 DEFAULT_PINMUX(DAP3_SCLK, I2S2, NORMAL, NORMAL, INPUT),
203 DEFAULT_PINMUX(GPIO_PV2, RSVD1, NORMAL, NORMAL, OUTPUT),
204 DEFAULT_PINMUX(GPIO_PV3, RSVD1, NORMAL, NORMAL, OUTPUT),
205 DEFAULT_PINMUX(LCD_PWR1, DISPLAYA, NORMAL, NORMAL, OUTPUT),
206 DEFAULT_PINMUX(LCD_PWR2, DISPLAYA, NORMAL, NORMAL, INPUT),
207 DEFAULT_PINMUX(LCD_CS0_N, DISPLAYA, NORMAL, NORMAL, INPUT),
208 DEFAULT_PINMUX(LCD_DC0, DISPLAYA, NORMAL, NORMAL, INPUT),
209 DEFAULT_PINMUX(LCD_DE, DISPLAYA, NORMAL, NORMAL, INPUT),
210 DEFAULT_PINMUX(LCD_D0, DISPLAYA, NORMAL, NORMAL, OUTPUT),
211 DEFAULT_PINMUX(LCD_D1, DISPLAYA, NORMAL, NORMAL, OUTPUT),
212 DEFAULT_PINMUX(LCD_D2, DISPLAYA, NORMAL, NORMAL, INPUT),
213 DEFAULT_PINMUX(LCD_D3, DISPLAYA, NORMAL, NORMAL, OUTPUT),
214 DEFAULT_PINMUX(LCD_D4, DISPLAYA, NORMAL, NORMAL, INPUT),
215 DEFAULT_PINMUX(LCD_D5, DISPLAYA, NORMAL, NORMAL, INPUT),
216 DEFAULT_PINMUX(LCD_D6, RSVD1, NORMAL, NORMAL, INPUT),
217 DEFAULT_PINMUX(LCD_D7, RSVD1, NORMAL, NORMAL, OUTPUT),
218 DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
219 DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
220 DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
221 DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
222 DEFAULT_PINMUX(LCD_D13, DISPLAYA, NORMAL, NORMAL, INPUT),
223 DEFAULT_PINMUX(LCD_D14, DISPLAYA, NORMAL, NORMAL, INPUT),
224 DEFAULT_PINMUX(LCD_D15, DISPLAYA, NORMAL, NORMAL, INPUT),
225 DEFAULT_PINMUX(LCD_D16, DISPLAYA, NORMAL, NORMAL, INPUT),
226 DEFAULT_PINMUX(LCD_D17, DISPLAYA, NORMAL, NORMAL, INPUT),
227 DEFAULT_PINMUX(LCD_D18, DISPLAYA, NORMAL, NORMAL, INPUT),
228 DEFAULT_PINMUX(LCD_D19, DISPLAYA, NORMAL, NORMAL, INPUT),
229 DEFAULT_PINMUX(LCD_D20, DISPLAYA, NORMAL, NORMAL, INPUT),
230 DEFAULT_PINMUX(LCD_D21, DISPLAYA, NORMAL, NORMAL, INPUT),
231 DEFAULT_PINMUX(LCD_D22, RSVD1, NORMAL, NORMAL, INPUT),
232 DEFAULT_PINMUX(LCD_D23, DISPLAYA, NORMAL, NORMAL, INPUT),
233 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
234 DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, OUTPUT),
235 DEFAULT_PINMUX(LCD_DC1, DISPLAYA, NORMAL, NORMAL, INPUT),
236 DEFAULT_PINMUX(VI_D0, RSVD1, NORMAL, NORMAL, INPUT),
237 DEFAULT_PINMUX(VI_D1, SDMMC2, NORMAL, NORMAL, INPUT),
238 DEFAULT_PINMUX(VI_D2, SDMMC2, NORMAL, NORMAL, INPUT),
239 DEFAULT_PINMUX(VI_D3, SDMMC2, NORMAL, NORMAL, INPUT),
240 DEFAULT_PINMUX(VI_D4, VI, NORMAL, NORMAL, OUTPUT),
241 DEFAULT_PINMUX(VI_D5, SDMMC2, NORMAL, NORMAL, INPUT),
242 DEFAULT_PINMUX(VI_D7, SDMMC2, NORMAL, NORMAL, INPUT),
243 DEFAULT_PINMUX(VI_D10, RSVD1, NORMAL, NORMAL, INPUT),
244 DEFAULT_PINMUX(VI_MCLK, VI, PULL_UP, NORMAL, INPUT),
245
246 DEFAULT_PINMUX(UART2_RXD, IRDA, NORMAL, NORMAL, INPUT),
247 DEFAULT_PINMUX(UART2_TXD, IRDA, NORMAL, NORMAL, OUTPUT),
248 DEFAULT_PINMUX(UART2_RTS_N, UARTB, NORMAL, NORMAL, OUTPUT),
249 DEFAULT_PINMUX(UART2_CTS_N, UARTB, NORMAL, NORMAL, INPUT),
250 DEFAULT_PINMUX(UART3_TXD, UARTC, NORMAL, NORMAL, OUTPUT),
251 DEFAULT_PINMUX(UART3_RXD, UARTC, NORMAL, NORMAL, INPUT),
252 DEFAULT_PINMUX(UART3_CTS_N, UARTC, NORMAL, NORMAL, INPUT),
253 DEFAULT_PINMUX(UART3_RTS_N, UARTC, NORMAL, NORMAL, OUTPUT),
254 DEFAULT_PINMUX(GPIO_PU0, UARTA, NORMAL, NORMAL, OUTPUT),
255 DEFAULT_PINMUX(GPIO_PU1, UARTA, NORMAL, NORMAL, INPUT),
256 DEFAULT_PINMUX(GPIO_PU2, UARTA, NORMAL, NORMAL, INPUT),
257 DEFAULT_PINMUX(GPIO_PU3, UARTA, NORMAL, NORMAL, OUTPUT),
258 DEFAULT_PINMUX(GPIO_PU4, PWM1, NORMAL, NORMAL, OUTPUT),
259 DEFAULT_PINMUX(GPIO_PU5, PWM2, NORMAL, NORMAL, INPUT),
260 DEFAULT_PINMUX(GPIO_PU6, PWM3, NORMAL, NORMAL, INPUT),
261 DEFAULT_PINMUX(DAP4_FS, I2S3, NORMAL, NORMAL, INPUT),
262 DEFAULT_PINMUX(DAP4_DIN, I2S3, NORMAL, NORMAL, INPUT),
263 DEFAULT_PINMUX(DAP4_DOUT, I2S3, NORMAL, NORMAL, INPUT),
264 DEFAULT_PINMUX(DAP4_SCLK, I2S3, NORMAL, NORMAL, INPUT),
265 DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
266 DEFAULT_PINMUX(GMI_AD9, NAND, NORMAL, NORMAL, OUTPUT),
267 DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
268 DEFAULT_PINMUX(GMI_A16, UARTD, NORMAL, NORMAL, OUTPUT),
269 DEFAULT_PINMUX(GMI_A17, UARTD, NORMAL, NORMAL, INPUT),
270 DEFAULT_PINMUX(GMI_A18, UARTD, NORMAL, NORMAL, INPUT),
271 DEFAULT_PINMUX(GMI_A19, UARTD, NORMAL, NORMAL, OUTPUT),
272 DEFAULT_PINMUX(CAM_MCLK, VI_ALT2, NORMAL, NORMAL, INPUT),
273 DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, NORMAL, INPUT),
274 DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, NORMAL, INPUT),
275 DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, NORMAL, INPUT),
276 DEFAULT_PINMUX(GPIO_PBB7, I2S4, NORMAL, NORMAL, INPUT),
277 DEFAULT_PINMUX(GPIO_PCC2, I2S4, NORMAL, NORMAL, INPUT),
278 DEFAULT_PINMUX(JTAG_RTCK, RTCK, NORMAL, NORMAL, OUTPUT),
279 DEFAULT_PINMUX(KB_ROW0, KBC, PULL_UP, NORMAL, INPUT),
280 DEFAULT_PINMUX(KB_ROW1, KBC, PULL_UP, NORMAL, INPUT),
281 DEFAULT_PINMUX(KB_ROW2, KBC, PULL_UP, NORMAL, INPUT),
282 DEFAULT_PINMUX(KB_ROW3, KBC, PULL_UP, NORMAL, INPUT),
283 DEFAULT_PINMUX(KB_ROW10, KBC, NORMAL, NORMAL, INPUT),
284 DEFAULT_PINMUX(KB_ROW12, KBC, NORMAL, NORMAL, INPUT),
285 DEFAULT_PINMUX(KB_COL0, KBC, PULL_UP, NORMAL, INPUT),
286 DEFAULT_PINMUX(KB_COL1, KBC, PULL_UP, NORMAL, INPUT),
287 DEFAULT_PINMUX(KB_COL2, KBC, PULL_UP, NORMAL, INPUT),
288 DEFAULT_PINMUX(KB_COL3, KBC, PULL_UP, NORMAL, INPUT),
289 DEFAULT_PINMUX(KB_COL4, KBC, PULL_UP, NORMAL, INPUT),
290 DEFAULT_PINMUX(KB_COL5, KBC, PULL_UP, NORMAL, INPUT),
291 DEFAULT_PINMUX(GPIO_PV0, RSVD, PULL_UP, NORMAL, INPUT),
292 DEFAULT_PINMUX(CLK_32K_OUT, BLINK, PULL_DOWN, TRISTATE, OUTPUT),
293 DEFAULT_PINMUX(SYS_CLK_REQ, SYSCLK, NORMAL, NORMAL, OUTPUT),
294 DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT),
295 DEFAULT_PINMUX(DAP1_FS, I2S0, NORMAL, NORMAL, INPUT),
296 DEFAULT_PINMUX(DAP1_DIN, I2S0, NORMAL, NORMAL, INPUT),
297 DEFAULT_PINMUX(DAP1_DOUT, I2S0, NORMAL, NORMAL, INPUT),
298 DEFAULT_PINMUX(DAP1_SCLK, I2S0, NORMAL, NORMAL, INPUT),
299 DEFAULT_PINMUX(CLK1_REQ, DAP, NORMAL, NORMAL, INPUT),
300 DEFAULT_PINMUX(CLK1_OUT, EXTPERIPH1, NORMAL, NORMAL, INPUT),
301#if 0 /* For HDA realtek Codec */
302 DEFAULT_PINMUX(SPDIF_IN, DAP2, PULL_DOWN, NORMAL, INPUT),
303#else
304 DEFAULT_PINMUX(SPDIF_IN, SPDIF, NORMAL, NORMAL, INPUT),
305#endif
306#if 0 /* For HDA realtek Codec */
307 DEFAULT_PINMUX(DAP2_FS, HDA, PULL_DOWN, NORMAL, INPUT),
308 DEFAULT_PINMUX(DAP2_DIN, HDA, PULL_DOWN, NORMAL, INPUT),
309 DEFAULT_PINMUX(DAP2_DOUT, HDA, PULL_DOWN, NORMAL, INPUT),
310 DEFAULT_PINMUX(DAP2_SCLK, HDA, PULL_DOWN, NORMAL, INPUT),
311#else
312 DEFAULT_PINMUX(DAP2_FS, I2S1, NORMAL, NORMAL, INPUT),
313 DEFAULT_PINMUX(DAP2_DIN, I2S1, NORMAL, NORMAL, INPUT),
314 DEFAULT_PINMUX(DAP2_DOUT, I2S1, NORMAL, NORMAL, INPUT),
315 DEFAULT_PINMUX(DAP2_SCLK, I2S1, NORMAL, NORMAL, INPUT),
316#endif
317 DEFAULT_PINMUX(SPI2_CS1_N, SPI2, PULL_UP, NORMAL, INPUT),
318 DEFAULT_PINMUX(SPI1_MOSI, SPI1, NORMAL, NORMAL, INPUT),
319 DEFAULT_PINMUX(SPI1_SCK, SPI1, NORMAL, NORMAL, INPUT),
320 DEFAULT_PINMUX(SPI1_MISO, SPI1, NORMAL, NORMAL, INPUT),
321 DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
322 DEFAULT_PINMUX(PEX_L0_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
323 DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
324 DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT),
325 DEFAULT_PINMUX(PEX_L1_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
326 DEFAULT_PINMUX(PEX_L1_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
327 DEFAULT_PINMUX(PEX_L1_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
328 DEFAULT_PINMUX(PEX_L2_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
329 DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
330 DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
331 CEC_PINMUX(HDMI_CEC, CEC, NORMAL, TRISTATE, OUTPUT, DEFAULT, DISABLE),
332 DEFAULT_PINMUX(HDMI_INT, RSVD0, NORMAL, TRISTATE, INPUT),
333
334 /* Gpios */
335 /* SDMMC1 CD gpio */
336 DEFAULT_PINMUX(GMI_IORDY, RSVD1, PULL_UP, NORMAL, INPUT),
337 /* SDMMC1 WP gpio */
338 DEFAULT_PINMUX(VI_D11, RSVD1, PULL_UP, NORMAL, INPUT),
339
340 /* Touch panel GPIO */
341 /* Touch IRQ */
342 DEFAULT_PINMUX(GMI_AD12, NAND, NORMAL, NORMAL, INPUT),
343
344 /* Touch RESET */
345 DEFAULT_PINMUX(GMI_AD14, NAND, NORMAL, NORMAL, INPUT),
346
347 DEFAULT_PINMUX(GMI_AD15, NAND, PULL_UP, TRISTATE, INPUT),
348
349 /* Power rails GPIO */
350 DEFAULT_PINMUX(KB_ROW8, KBC, PULL_UP, NORMAL, INPUT),
351
352 VI_PINMUX(VI_D6, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
353 VI_PINMUX(VI_D8, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
354 VI_PINMUX(VI_D9, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
355 VI_PINMUX(VI_PCLK, RSVD1, PULL_UP, TRISTATE, INPUT, DISABLE, ENABLE),
356 VI_PINMUX(VI_HSYNC, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
357 VI_PINMUX(VI_VSYNC, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
358};
359
360static __initdata struct tegra_pingroup_config enterprise_pinmux_a03[] = {
361 DEFAULT_PINMUX(LCD_PWR0, DISPLAYA, NORMAL, NORMAL, OUTPUT),
362 DEFAULT_PINMUX(LCD_D10, DISPLAYA, NORMAL, NORMAL, OUTPUT),
363};
364
365static __initdata struct tegra_pingroup_config enterprise_unused_pinmux_common[] = {
366 DEFAULT_PINMUX(CLK2_OUT, EXTPERIPH2, PULL_DOWN, TRISTATE, OUTPUT),
367 DEFAULT_PINMUX(CLK2_REQ, DAP, PULL_DOWN, TRISTATE, OUTPUT),
368 DEFAULT_PINMUX(CLK3_OUT, EXTPERIPH3, PULL_DOWN, TRISTATE, OUTPUT),
369 DEFAULT_PINMUX(CLK3_REQ, DEV3, PULL_DOWN, TRISTATE, OUTPUT),
370 DEFAULT_PINMUX(CLK_32K_OUT, BLINK, PULL_DOWN, TRISTATE, OUTPUT),
371 DEFAULT_PINMUX(GPIO_PBB4, VGP4, PULL_DOWN, TRISTATE, OUTPUT),
372 DEFAULT_PINMUX(GPIO_PBB5, VGP5, PULL_DOWN, TRISTATE, OUTPUT),
373 DEFAULT_PINMUX(GPIO_PBB6, VGP6, PULL_DOWN, TRISTATE, OUTPUT),
374 DEFAULT_PINMUX(GMI_AD0, GMI, NORMAL, TRISTATE, OUTPUT),
375 DEFAULT_PINMUX(GMI_AD1, GMI, NORMAL, TRISTATE, OUTPUT),
376 DEFAULT_PINMUX(GMI_AD2, GMI, NORMAL, TRISTATE, OUTPUT),
377 DEFAULT_PINMUX(GMI_AD3, GMI, NORMAL, TRISTATE, OUTPUT),
378 DEFAULT_PINMUX(GMI_AD4, GMI, NORMAL, TRISTATE, OUTPUT),
379 DEFAULT_PINMUX(GMI_AD5, GMI, NORMAL, TRISTATE, OUTPUT),
380 DEFAULT_PINMUX(GMI_AD6, GMI, NORMAL, TRISTATE, OUTPUT),
381 DEFAULT_PINMUX(GMI_AD7, GMI, NORMAL, TRISTATE, OUTPUT),
382 DEFAULT_PINMUX(GMI_AD11, GMI, PULL_DOWN, TRISTATE, OUTPUT),
383 DEFAULT_PINMUX(GMI_CS0_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
384 DEFAULT_PINMUX(GMI_CS2_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
385 DEFAULT_PINMUX(GMI_CS3_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
386 DEFAULT_PINMUX(GMI_CS6_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
387 DEFAULT_PINMUX(GMI_CS7_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
388 DEFAULT_PINMUX(GMI_CLK, GMI, NORMAL, TRISTATE, OUTPUT),
389 DEFAULT_PINMUX(GMI_DQS, RSVD3, PULL_DOWN, TRISTATE, OUTPUT),
390 DEFAULT_PINMUX(GMI_RST_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
391 DEFAULT_PINMUX(GMI_WAIT, GMI, PULL_DOWN, TRISTATE, OUTPUT),
392 DEFAULT_PINMUX(GMI_WP_N, GMI, PULL_DOWN, TRISTATE, OUTPUT),
393 DEFAULT_PINMUX(KB_ROW6, KBC, PULL_DOWN, TRISTATE, OUTPUT),
394 DEFAULT_PINMUX(KB_ROW7, KBC, PULL_DOWN, TRISTATE, OUTPUT),
395 DEFAULT_PINMUX(KB_ROW9, KBC, PULL_DOWN, TRISTATE, OUTPUT),
396 DEFAULT_PINMUX(KB_ROW11, KBC, PULL_DOWN, TRISTATE, OUTPUT),
397 DEFAULT_PINMUX(KB_ROW13, KBC, PULL_DOWN, TRISTATE, OUTPUT),
398 DEFAULT_PINMUX(KB_ROW14, KBC, PULL_DOWN, TRISTATE, OUTPUT),
399 DEFAULT_PINMUX(KB_ROW15, KBC, PULL_DOWN, TRISTATE, OUTPUT),
400 DEFAULT_PINMUX(LCD_PCLK, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
401 DEFAULT_PINMUX(LCD_WR_N, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
402 DEFAULT_PINMUX(LCD_HSYNC, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
403 DEFAULT_PINMUX(LCD_VSYNC, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
404 DEFAULT_PINMUX(LCD_SCK, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
405 DEFAULT_PINMUX(LCD_SDOUT, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
406 DEFAULT_PINMUX(LCD_SDIN, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
407 DEFAULT_PINMUX(CRT_HSYNC, CRT, PULL_DOWN, TRISTATE, OUTPUT),
408 DEFAULT_PINMUX(CRT_VSYNC, CRT, PULL_DOWN, TRISTATE, OUTPUT),
409 DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, PULL_DOWN, TRISTATE, OUTPUT),
410 DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, PULL_DOWN, TRISTATE, OUTPUT),
411 DEFAULT_PINMUX(SDMMC3_DAT6, SDMMC3, PULL_DOWN, TRISTATE, OUTPUT),
412 DEFAULT_PINMUX(SDMMC3_DAT7, SDMMC3, PULL_DOWN, TRISTATE, OUTPUT),
413 DEFAULT_PINMUX(SPDIF_OUT, SPDIF, PULL_DOWN, TRISTATE, OUTPUT),
414 DEFAULT_PINMUX(SPI1_CS0_N, SPI1, PULL_DOWN, TRISTATE, OUTPUT),
415 DEFAULT_PINMUX(SPI2_SCK, SPI2, PULL_DOWN, TRISTATE, OUTPUT),
416 DEFAULT_PINMUX(SPI2_CS0_N, SPI2, PULL_DOWN, TRISTATE, OUTPUT),
417 DEFAULT_PINMUX(SPI2_MOSI, SPI2, PULL_DOWN, TRISTATE, OUTPUT),
418 DEFAULT_PINMUX(SPI2_MISO, SPI2, PULL_DOWN, TRISTATE, OUTPUT),
419};
420
421static __initdata struct tegra_pingroup_config enterprise_unused_pinmux_a02[] = {
422 DEFAULT_PINMUX(LCD_D10, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
423 DEFAULT_PINMUX(LCD_PWR0, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
424};
425
426static struct tegra_gpio_table gpio_table[] = {
427 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
428};
429
430struct pin_info_low_power_mode {
431 char name[16];
432 int gpio_nr;
433 bool is_gpio;
434 bool is_input;
435 int value; /* Value if it is output*/
436};
437
438#define PIN_GPIO_LPM(_name, _gpio, _is_input, _value) \
439 { \
440 .name = _name, \
441 .gpio_nr = _gpio, \
442 .is_gpio = true, \
443 .is_input = _is_input, \
444 .value = _value, \
445 }
446static __initdata struct pin_info_low_power_mode enterprise_unused_gpio_pins_common[] = {
447 PIN_GPIO_LPM("CLK2_OUT", TEGRA_GPIO_PW5, 0, 0),
448 PIN_GPIO_LPM("CLK2_REQ", TEGRA_GPIO_PCC5, 0, 0),
449 PIN_GPIO_LPM("CLK3_OUT", TEGRA_GPIO_PEE0, 0, 0),
450 PIN_GPIO_LPM("CLK3_REQ", TEGRA_GPIO_PEE1, 0, 0),
451 PIN_GPIO_LPM("CLK_32K_OUT", TEGRA_GPIO_PA0, 0, 0),
452 PIN_GPIO_LPM("GPIO_PBB4", TEGRA_GPIO_PBB4, 0, 0),
453 PIN_GPIO_LPM("GPIO_PBB5", TEGRA_GPIO_PBB5, 0, 0),
454 PIN_GPIO_LPM("GPIO_PBB6", TEGRA_GPIO_PBB6, 0, 0),
455 PIN_GPIO_LPM("GMI_AD0", TEGRA_GPIO_PG0, 0, 0),
456 PIN_GPIO_LPM("GMI_AD1", TEGRA_GPIO_PG1, 0, 0),
457 PIN_GPIO_LPM("GMI_AD2", TEGRA_GPIO_PG2, 0, 0),
458 PIN_GPIO_LPM("GMI_AD3", TEGRA_GPIO_PG3, 0, 0),
459 PIN_GPIO_LPM("GMI_AD4", TEGRA_GPIO_PG4, 0, 0),
460 PIN_GPIO_LPM("GMI_AD5", TEGRA_GPIO_PG5, 0, 0),
461 PIN_GPIO_LPM("GMI_AD6", TEGRA_GPIO_PG6, 0, 0),
462 PIN_GPIO_LPM("GMI_AD7", TEGRA_GPIO_PG7, 0, 0),
463 PIN_GPIO_LPM("GMI_AD11", TEGRA_GPIO_PH3, 0, 0),
464 PIN_GPIO_LPM("GMI_CS0_N", TEGRA_GPIO_PJ0, 0, 0),
465 PIN_GPIO_LPM("GMI_CS2_N", TEGRA_GPIO_PK3, 0, 0),
466 PIN_GPIO_LPM("GMI_CS3_N", TEGRA_GPIO_PK4, 0, 0),
467 PIN_GPIO_LPM("GMI_CS6_N", TEGRA_GPIO_PI3, 0, 0),
468 PIN_GPIO_LPM("GMI_CS7_N", TEGRA_GPIO_PI6, 0, 0),
469 PIN_GPIO_LPM("GMI_ADV", TEGRA_GPIO_PK0, 0, 0),
470 PIN_GPIO_LPM("GMI_CLK", TEGRA_GPIO_PK1, 0, 0),
471 PIN_GPIO_LPM("GMI_DQS", TEGRA_GPIO_PI2, 0, 0),
472 PIN_GPIO_LPM("GMI_RST_N", TEGRA_GPIO_PI4, 0, 0),
473 PIN_GPIO_LPM("GMI_WAIT", TEGRA_GPIO_PI7, 0, 0),
474 PIN_GPIO_LPM("GMI_WP_N", TEGRA_GPIO_PC7, 0, 0),
475 PIN_GPIO_LPM("KB_ROW6", TEGRA_GPIO_PR6, 0, 0),
476 PIN_GPIO_LPM("KB_ROW7", TEGRA_GPIO_PR7, 0, 0),
477 PIN_GPIO_LPM("KB_ROW9", TEGRA_GPIO_PS1, 0, 0),
478 PIN_GPIO_LPM("KB_ROW11", TEGRA_GPIO_PS3, 0, 0),
479 PIN_GPIO_LPM("KB_ROW13", TEGRA_GPIO_PS5, 0, 0),
480 PIN_GPIO_LPM("KB_ROW14", TEGRA_GPIO_PS6, 0, 0),
481 PIN_GPIO_LPM("KB_ROW15", TEGRA_GPIO_PS7, 0, 0),
482 PIN_GPIO_LPM("LCD_PCLK", TEGRA_GPIO_PB3, 0, 0),
483 PIN_GPIO_LPM("LCD_WR_N", TEGRA_GPIO_PZ3, 0, 0),
484 PIN_GPIO_LPM("LCD_HSYNC", TEGRA_GPIO_PJ3, 0, 0),
485 PIN_GPIO_LPM("LCD_VSYNC", TEGRA_GPIO_PJ4, 0, 0),
486 PIN_GPIO_LPM("LCD_SCK", TEGRA_GPIO_PZ4, 0, 0),
487 PIN_GPIO_LPM("LCD_SDOUT", TEGRA_GPIO_PN5, 0, 0),
488 PIN_GPIO_LPM("LCD_SDIN", TEGRA_GPIO_PZ2, 0, 0),
489 PIN_GPIO_LPM("CRT_HSYNC", TEGRA_GPIO_PV6, 0, 0),
490 PIN_GPIO_LPM("CRT_VSYNC", TEGRA_GPIO_PV7, 0, 0),
491 PIN_GPIO_LPM("SDMMC3_DAT4", TEGRA_GPIO_PD1, 0, 0),
492 PIN_GPIO_LPM("SDMMC3_DAT5", TEGRA_GPIO_PD0, 0, 0),
493 PIN_GPIO_LPM("SDMMC3_DAT6", TEGRA_GPIO_PD3, 0, 0),
494 PIN_GPIO_LPM("SDMMC3_DAT7", TEGRA_GPIO_PD4, 0, 0),
495 PIN_GPIO_LPM("SPDIF_OUT", TEGRA_GPIO_PK5, 0, 0),
496 PIN_GPIO_LPM("SPI1_CS0_N", TEGRA_GPIO_PX6, 0, 0),
497 PIN_GPIO_LPM("SPI2_SCK", TEGRA_GPIO_PX2, 0, 0),
498 PIN_GPIO_LPM("SPI2_CS0_N", TEGRA_GPIO_PX3, 0, 0),
499 PIN_GPIO_LPM("SPI2_MOSI", TEGRA_GPIO_PX0, 0, 0),
500 PIN_GPIO_LPM("SPI2_MISO", TEGRA_GPIO_PX1, 0, 0),
501};
502
503static __initdata struct pin_info_low_power_mode enterprise_unused_gpio_pins_a02[] = {
504 PIN_GPIO_LPM("LCD_D10", TEGRA_GPIO_PF2, 0, 0),
505 PIN_GPIO_LPM("LCD_PWR0", TEGRA_GPIO_PB2, 0, 0),
506};
507
508static void enterprise_set_unused_pin_gpio(struct pin_info_low_power_mode *lpm_pin_info,
509 int list_count)
510{
511 int i;
512 struct pin_info_low_power_mode *pin_info;
513 int ret;
514
515 for (i = 0; i < list_count; ++i) {
516 pin_info = (struct pin_info_low_power_mode *)(lpm_pin_info + i);
517 if (!pin_info->is_gpio)
518 continue;
519
520 ret = gpio_request(pin_info->gpio_nr, pin_info->name);
521 if (ret < 0) {
522 pr_err("%s() Error in gpio_request() for gpio %d\n",
523 __func__, pin_info->gpio_nr);
524 continue;
525 }
526 if (pin_info->is_input)
527 ret = gpio_direction_input(pin_info->gpio_nr);
528 else
529 ret = gpio_direction_output(pin_info->gpio_nr,
530 pin_info->value);
531 if (ret < 0) {
532 pr_err("%s() Error in setting gpio %d to in/out\n",
533 __func__, pin_info->gpio_nr);
534 gpio_free(pin_info->gpio_nr);
535 continue;
536 }
537 tegra_gpio_enable(pin_info->gpio_nr);
538 }
539}
540
541int __init enterprise_pinmux_init(void)
542{
543 struct board_info board_info;
544 tegra_get_board_info(&board_info);
545
546 tegra_pinmux_config_table(enterprise_pinmux_common,
547 ARRAY_SIZE(enterprise_pinmux_common));
548 tegra_drive_pinmux_config_table(enterprise_drive_pinmux,
549 ARRAY_SIZE(enterprise_drive_pinmux));
550 tegra_pinmux_config_table(enterprise_unused_pinmux_common,
551 ARRAY_SIZE(enterprise_unused_pinmux_common));
552
553 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
554 enterprise_set_unused_pin_gpio(enterprise_unused_gpio_pins_common,
555 ARRAY_SIZE(enterprise_unused_gpio_pins_common));
556
557 if (board_info.fab < BOARD_FAB_A03) {
558 tegra_pinmux_config_table(enterprise_unused_pinmux_a02,
559 ARRAY_SIZE(enterprise_unused_pinmux_a02));
560 enterprise_set_unused_pin_gpio(enterprise_unused_gpio_pins_a02,
561 ARRAY_SIZE(enterprise_unused_gpio_pins_a02));
562 } else {
563 tegra_pinmux_config_table(enterprise_pinmux_a03,
564 ARRAY_SIZE(enterprise_pinmux_a03));
565 }
566
567 return 0;
568}
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
new file mode 100644
index 00000000000..02792f44f45
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -0,0 +1,838 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-power.c
3 *
4 * Copyright (C) 2011 NVIDIA, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20#include <linux/i2c.h>
21#include <linux/pda_power.h>
22#include <linux/platform_device.h>
23#include <linux/resource.h>
24#include <linux/regulator/machine.h>
25#include <linux/regulator/fixed.h>
26#include <linux/mfd/tps80031.h>
27#include <linux/regulator/tps80031-regulator.h>
28#include <linux/tps80031-charger.h>
29#include <linux/gpio.h>
30#include <linux/io.h>
31#include <linux/cpumask.h>
32#include <linux/platform_data/tegra_bpc_mgmt.h>
33#include <linux/regulator/driver.h>
34#include <linux/regulator/gpio-regulator.h>
35
36#include <asm/mach-types.h>
37
38#include <mach/edp.h>
39#include <mach/iomap.h>
40#include <mach/irqs.h>
41#include <mach/pinmux.h>
42
43#include "gpio-names.h"
44#include "board.h"
45#include "board-enterprise.h"
46#include "pm.h"
47#include "wakeups-t3.h"
48#include "tegra3_tsensor.h"
49
50#define PMC_CTRL 0x0
51#define PMC_CTRL_INTR_LOW (1 << 17)
52
53#define PMC_DPD_PADS_ORIDE 0x01c
54#define PMC_DPD_PADS_ORIDE_BLINK (1 << 20)
55
56/************************ TPS80031 based regulator ****************/
57static struct regulator_consumer_supply tps80031_vio_supply_a02[] = {
58 REGULATOR_SUPPLY("vio_1v8", NULL),
59 REGULATOR_SUPPLY("avdd_osc", NULL),
60 REGULATOR_SUPPLY("vddio_sys", NULL),
61 REGULATOR_SUPPLY("vddio_uart", NULL),
62 REGULATOR_SUPPLY("pwrdet_uart", NULL),
63 REGULATOR_SUPPLY("vddio_lcd", NULL),
64 REGULATOR_SUPPLY("pwrdet_lcd", NULL),
65 REGULATOR_SUPPLY("vddio_audio", NULL),
66 REGULATOR_SUPPLY("pwrdet_audio", NULL),
67 REGULATOR_SUPPLY("vddio_bb", NULL),
68 REGULATOR_SUPPLY("pwrdet_bb", NULL),
69 REGULATOR_SUPPLY("vddio_gmi", NULL),
70 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
71 REGULATOR_SUPPLY("vddio_cam", NULL),
72 REGULATOR_SUPPLY("pwrdet_cam", NULL),
73 REGULATOR_SUPPLY("vddio_sdmmc1", NULL),
74 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
75 REGULATOR_SUPPLY("vddio_sdmmc4", NULL),
76 REGULATOR_SUPPLY("pwrdet_sdmmc4", NULL),
77 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
78 REGULATOR_SUPPLY("vddio_gps", NULL),
79 REGULATOR_SUPPLY("vdd_lcd_buffered", NULL),
80 REGULATOR_SUPPLY("vddio_nand", NULL),
81 REGULATOR_SUPPLY("pwrdet_nand", NULL),
82 REGULATOR_SUPPLY("vddio_sd", NULL),
83 REGULATOR_SUPPLY("vdd_bat", NULL),
84 REGULATOR_SUPPLY("vdd_io", NULL),
85 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
86};
87
88static struct regulator_consumer_supply tps80031_vio_supply_a03[] = {
89 REGULATOR_SUPPLY("vio_1v8", NULL),
90 REGULATOR_SUPPLY("vddio_sys", NULL),
91 REGULATOR_SUPPLY("vddio_uart", NULL),
92 REGULATOR_SUPPLY("pwrdet_uart", NULL),
93 REGULATOR_SUPPLY("vddio_lcd", NULL),
94 REGULATOR_SUPPLY("pwrdet_lcd", NULL),
95 REGULATOR_SUPPLY("vddio_audio", NULL),
96 REGULATOR_SUPPLY("pwrdet_audio", NULL),
97 REGULATOR_SUPPLY("vddio_bb", NULL),
98 REGULATOR_SUPPLY("pwrdet_bb", NULL),
99 REGULATOR_SUPPLY("vddio_gmi", NULL),
100 REGULATOR_SUPPLY("vddio_cam", NULL),
101 REGULATOR_SUPPLY("pwrdet_cam", NULL),
102 REGULATOR_SUPPLY("vddio_sdmmc1", NULL),
103 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
104 REGULATOR_SUPPLY("vddio_sdmmc4", NULL),
105 REGULATOR_SUPPLY("pwrdet_sdmmc4", NULL),
106 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
107 REGULATOR_SUPPLY("vddio_gps", NULL),
108 REGULATOR_SUPPLY("vdd_lcd_buffered", NULL),
109 REGULATOR_SUPPLY("vddio_nand", NULL),
110 REGULATOR_SUPPLY("pwrdet_nand", NULL),
111 REGULATOR_SUPPLY("vddio_sd", NULL),
112 REGULATOR_SUPPLY("vdd_bat", NULL),
113 REGULATOR_SUPPLY("vdd_io", NULL),
114 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
115};
116
117static struct regulator_consumer_supply tps80031_smps1_supply_common[] = {
118 REGULATOR_SUPPLY("vdd_cpu", NULL),
119};
120
121static struct regulator_consumer_supply tps80031_smps2_supply_common[] = {
122 REGULATOR_SUPPLY("vdd_core", NULL),
123};
124
125static struct regulator_consumer_supply tps80031_smps3_supply_common[] = {
126 REGULATOR_SUPPLY("en_vddio_ddr_1v2", NULL),
127 REGULATOR_SUPPLY("vddio_ddr", NULL),
128 REGULATOR_SUPPLY("vdd_lpddr", NULL),
129 REGULATOR_SUPPLY("ddr_comp_pu", NULL),
130};
131
132static struct regulator_consumer_supply tps80031_smps4_supply_a02[] = {
133 REGULATOR_SUPPLY("vddio_sdmmc_2v85", NULL),
134 REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
135};
136
137static struct regulator_consumer_supply tps80031_smps4_supply_a03[] = {
138 REGULATOR_SUPPLY("vddio_sdmmc_2v85", NULL),
139 REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
140 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
141 REGULATOR_SUPPLY("vddf_core_emmc", NULL),
142};
143
144static struct regulator_consumer_supply tps80031_vana_supply_common[] = {
145 REGULATOR_SUPPLY("unused_vana", NULL),
146};
147
148static struct regulator_consumer_supply tps80031_ldo1_supply_a02[] = {
149 REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
150 REGULATOR_SUPPLY("pwrdet_mipi", NULL),
151};
152
153static struct regulator_consumer_supply tps80031_ldo1_supply_a03[] = {
154 REGULATOR_SUPPLY("vdd_ddr_hs", NULL),
155};
156
157static struct regulator_consumer_supply tps80031_ldo2_supply_common[] = {
158 REGULATOR_SUPPLY("vdd_rtc", NULL),
159};
160
161static struct regulator_consumer_supply tps80031_ldo3_supply_common[] = {
162 REGULATOR_SUPPLY("vdd_vbrtr", NULL),
163};
164
165static struct regulator_consumer_supply tps80031_ldo4_supply_a02[] = {
166 REGULATOR_SUPPLY("avdd_lcd", NULL),
167};
168
169static struct regulator_consumer_supply tps80031_ldo4_supply_a03[] = {
170 REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
171 REGULATOR_SUPPLY("avdd_hsic", NULL),
172 REGULATOR_SUPPLY("pwrdet_mipi", NULL),
173};
174
175static struct regulator_consumer_supply tps80031_ldo5_supply_common[] = {
176 REGULATOR_SUPPLY("vdd_sensor", NULL),
177 REGULATOR_SUPPLY("vdd_compass", NULL),
178 REGULATOR_SUPPLY("vdd_als", NULL),
179 REGULATOR_SUPPLY("vdd_gyro", NULL),
180 REGULATOR_SUPPLY("vdd_touch", NULL),
181 REGULATOR_SUPPLY("vdd_proxim_diode", NULL),
182};
183
184static struct regulator_consumer_supply tps80031_ldo6_supply_a02[] = {
185 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
186 REGULATOR_SUPPLY("vddf_core_emmc", NULL),
187};
188
189static struct regulator_consumer_supply tps80031_ldo6_supply_a03[] = {
190 REGULATOR_SUPPLY("avdd_osc", NULL),
191 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
192};
193
194static struct regulator_consumer_supply tps80031_ldo7_supply_a02[] = {
195 REGULATOR_SUPPLY("vdd_plla_p_c_s", NULL),
196 REGULATOR_SUPPLY("vdd_pllm", NULL),
197 REGULATOR_SUPPLY("vdd_pllu_d", NULL),
198 REGULATOR_SUPPLY("vdd_pllx", NULL),
199};
200
201static struct regulator_consumer_supply tps80031_ldo7_supply_a03[] = {
202 REGULATOR_SUPPLY("avdd_lcd", NULL),
203};
204
205static struct regulator_consumer_supply tps80031_ldoln_supply_a02[] = {
206 REGULATOR_SUPPLY("vdd_ddr_hs", NULL),
207};
208
209static struct regulator_consumer_supply tps80031_ldoln_supply_a03[] = {
210 REGULATOR_SUPPLY("vdd_plla_p_c_s", NULL),
211 REGULATOR_SUPPLY("vdd_pllm", NULL),
212 REGULATOR_SUPPLY("vdd_pllu_d", NULL),
213 REGULATOR_SUPPLY("vdd_pllx", NULL),
214};
215
216static struct regulator_consumer_supply tps80031_ldousb_supply_a02[] = {
217 REGULATOR_SUPPLY("unused_ldousb", NULL),
218};
219
220static struct regulator_consumer_supply tps80031_ldousb_supply_a03[] = {
221 REGULATOR_SUPPLY("avdd_usb_hdmi_3v3", NULL),
222 REGULATOR_SUPPLY("avdd_usb", NULL),
223 REGULATOR_SUPPLY("avdd_hdmi", NULL),
224 REGULATOR_SUPPLY("vdd", "4-004c"),
225};
226
227static struct regulator_consumer_supply tps80031_vbus_supply_common[] = {
228 REGULATOR_SUPPLY("usb_vbus", NULL),
229};
230
231static struct regulator_consumer_supply tps80031_battery_charge_supply[] = {
232 REGULATOR_SUPPLY("usb_bat_chg", NULL),
233};
234
235#define TPS_PDATA_INIT(_id, _sname, _minmv, _maxmv, _supply_reg, _always_on, \
236 _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, \
237 _flags, _ectrl, _delay) \
238 static struct tps80031_regulator_platform_data pdata_##_id##_##_sname = { \
239 .regulator = { \
240 .constraints = { \
241 .min_uV = (_minmv)*1000, \
242 .max_uV = (_maxmv)*1000, \
243 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
244 REGULATOR_MODE_STANDBY), \
245 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
246 REGULATOR_CHANGE_STATUS | \
247 REGULATOR_CHANGE_VOLTAGE), \
248 .always_on = _always_on, \
249 .boot_on = _boot_on, \
250 .apply_uV = _apply_uv, \
251 }, \
252 .num_consumer_supplies = \
253 ARRAY_SIZE(tps80031_##_id##_supply_##_sname), \
254 .consumer_supplies = tps80031_##_id##_supply_##_sname, \
255 .supply_regulator = _supply_reg, \
256 }, \
257 .init_uV = _init_uV * 1000, \
258 .init_enable = _init_enable, \
259 .init_apply = _init_apply, \
260 .flags = _flags, \
261 .ext_ctrl_flag = _ectrl, \
262 .delay_us = _delay, \
263 }
264
265TPS_PDATA_INIT(vio, a02, 600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
266TPS_PDATA_INIT(vio, a03, 600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
267TPS_PDATA_INIT(smps1, common, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ2 | PWR_OFF_ON_SLEEP, 0);
268TPS_PDATA_INIT(smps2, common, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
269TPS_PDATA_INIT(smps3, common, 600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
270TPS_PDATA_INIT(smps4, a02, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
271TPS_PDATA_INIT(smps4, a03, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
272TPS_PDATA_INIT(ldo1, a02, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, 0, 0);
273TPS_PDATA_INIT(ldo1, a03, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
274TPS_PDATA_INIT(ldo2, common, 1000, 3300, 0, 1, 1, 1, 1000, 1, 1, 0, 0, 0);
275TPS_PDATA_INIT(ldo3, common, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_OFF_ON_SLEEP, 0);
276TPS_PDATA_INIT(ldo4, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
277TPS_PDATA_INIT(ldo4, a03, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, 0, 0);
278TPS_PDATA_INIT(ldo5, common, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
279TPS_PDATA_INIT(ldo6, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
280TPS_PDATA_INIT(ldo6, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
281TPS_PDATA_INIT(ldo7, a02, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
282TPS_PDATA_INIT(ldo7, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
283TPS_PDATA_INIT(ldoln, a02, 1000, 3300, tps80031_rails(SMPS3), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
284TPS_PDATA_INIT(ldoln, a03, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
285TPS_PDATA_INIT(ldousb, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, USBLDO_INPUT_VSYS, PWR_OFF_ON_SLEEP, 0);
286TPS_PDATA_INIT(ldousb, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, USBLDO_INPUT_VSYS, PWR_OFF_ON_SLEEP, 0);
287TPS_PDATA_INIT(vana, common, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
288TPS_PDATA_INIT(vbus, common, 0, 5000, 0, 0, 0, 0, -1, 0, 0, (VBUS_SW_ONLY | VBUS_DISCHRG_EN_PDN), 0, 100000);
289
290static struct tps80031_rtc_platform_data rtc_data = {
291 .irq = ENT_TPS80031_IRQ_BASE + TPS80031_INT_RTC_ALARM,
292 .time = {
293 .tm_year = 2011,
294 .tm_mon = 0,
295 .tm_mday = 1,
296 .tm_hour = 1,
297 .tm_min = 2,
298 .tm_sec = 3,
299 },
300};
301
302int battery_charger_init(void *board_data)
303{
304 int ret;
305 ret = gpio_request(TEGRA_GPIO_PF6, "lcd_d14-bat_charge");
306 if (ret < 0) {
307 pr_err("%s() The gpio_request for battery"
308 " charger fails\n", __func__);
309 }
310 gpio_direction_output(TEGRA_GPIO_PF6, 1);
311 tegra_gpio_enable(TEGRA_GPIO_PF6);
312 return 0;
313}
314
315static struct tps80031_charger_platform_data bcharger_pdata = {
316 .max_charge_volt_mV = 4100,
317 .max_charge_current_mA = 1000,
318 .charging_term_current_mA = 100,
319 .watch_time_sec = 100,
320 .irq_base = ENT_TPS80031_IRQ_BASE,
321 .consumer_supplies = tps80031_battery_charge_supply,
322 .num_consumer_supplies = ARRAY_SIZE(tps80031_battery_charge_supply),
323 .board_init = battery_charger_init,
324 .board_data = NULL,
325};
326
327static struct tps80031_bg_platform_data battery_gauge_data = {
328 .irq_base = ENT_TPS80031_IRQ_BASE,
329 .battery_present = 1,
330};
331
332#define TPS_RTC() \
333 { \
334 .id = 0, \
335 .name = "rtc_tps80031", \
336 .platform_data = &rtc_data, \
337 }
338
339#define TPS_REG(_id, _data, _sname) \
340 { \
341 .id = TPS80031_ID_##_id, \
342 .name = "tps80031-regulator", \
343 .platform_data = &pdata_##_data##_##_sname, \
344 }
345#define TPS_BATTERY() \
346 { \
347 .name = "tps80031-charger", \
348 .platform_data = &bcharger_pdata, \
349 }
350#define TPS_BATTERY_GAUGE() \
351 { \
352 .name = "tps80031-battery-gauge", \
353 .platform_data = &battery_gauge_data, \
354 }
355#define TPS_GPADC() \
356 { \
357 .name = "tps80031-gpadc", \
358 }
359
360#define TPS80031_DEVS_COMMON \
361 TPS_REG(SMPS1, smps1, common), \
362 TPS_REG(SMPS2, smps2, common), \
363 TPS_REG(SMPS3, smps3, common), \
364 TPS_REG(VANA, vana, common), \
365 TPS_REG(LDO2, ldo2, common), \
366 TPS_REG(LDO3, ldo3, common), \
367 TPS_REG(LDO5, ldo5, common), \
368 TPS_REG(VBUS, vbus, common), \
369 TPS_RTC(), \
370 TPS_BATTERY(), \
371 TPS_BATTERY_GAUGE(), \
372 TPS_GPADC()
373
374
375static struct tps80031_subdev_info tps80031_devs_a02[] = {
376 TPS80031_DEVS_COMMON,
377 TPS_REG(VIO, vio, a02),
378 TPS_REG(SMPS4, smps4, a02),
379 TPS_REG(LDO1, ldo1, a02),
380 TPS_REG(LDO4, ldo4, a02),
381 TPS_REG(LDO6, ldo6, a02),
382 TPS_REG(LDO7, ldo7, a02),
383 TPS_REG(LDOLN, ldoln, a02),
384 TPS_REG(LDOUSB, ldousb, a02),
385
386};
387
388static struct tps80031_subdev_info tps80031_devs_a03[] = {
389 TPS80031_DEVS_COMMON,
390 TPS_REG(VIO, vio, a03),
391 TPS_REG(SMPS4, smps4, a03),
392 TPS_REG(LDO1, ldo1, a03),
393 TPS_REG(LDO4, ldo4, a03),
394 TPS_REG(LDO6, ldo6, a03),
395 TPS_REG(LDO7, ldo7, a03),
396 TPS_REG(LDOLN, ldoln, a03),
397 TPS_REG(LDOUSB, ldousb, a03),
398
399};
400
401struct tps80031_clk32k_init_data clk32k_idata[] = {
402 {
403 .clk32k_nr = TPS80031_CLOCK32K_G,
404 .enable = true,
405 .ext_ctrl_flag = 0,
406 },
407 {
408 .clk32k_nr = TPS80031_CLOCK32K_AUDIO,
409 .enable = true,
410 .ext_ctrl_flag = 0,
411 },
412};
413
414static struct tps80031_platform_data tps_platform = {
415 .irq_base = ENT_TPS80031_IRQ_BASE,
416 .gpio_base = ENT_TPS80031_GPIO_BASE,
417 .clk32k_init_data = clk32k_idata,
418 .clk32k_init_data_size = ARRAY_SIZE(clk32k_idata),
419 .use_power_off = true,
420};
421
422static struct i2c_board_info __initdata enterprise_regulators[] = {
423 {
424 I2C_BOARD_INFO("tps80031", 0x4A),
425 .irq = INT_EXTERNAL_PMU,
426 .platform_data = &tps_platform,
427 },
428};
429
430/************************ GPIO based fixed regulator ****************/
431/* REGEN1 from PMU*/
432static struct regulator_consumer_supply fixed_reg_pmu_5v15_en_supply[] = {
433 REGULATOR_SUPPLY("vdd_5v15", NULL),
434};
435
436/* REGEN2 from PMU*/
437static struct regulator_consumer_supply fixed_reg_pmu_3v3_en_supply[] = {
438 REGULATOR_SUPPLY("avdd_usb_hdmi_3v3", NULL),
439 REGULATOR_SUPPLY("avdd_usb", NULL),
440 REGULATOR_SUPPLY("avdd_hdmi", NULL),
441 REGULATOR_SUPPLY("vdd", "4-004c"),
442};
443
444/* SYSEN from PMU*/
445static struct regulator_consumer_supply fixed_reg_pmu_hdmi_5v0_en_supply[] = {
446 REGULATOR_SUPPLY("hdmi_5v0", NULL),
447};
448
449/* LCD-D16 (GPIO M0) from T30*/
450static struct regulator_consumer_supply fixed_reg_vdd_fuse_en_supply[] = {
451 REGULATOR_SUPPLY("vdd_fuse", NULL),
452};
453
454/* LCD-D17 (GPIO M1) from T30*/
455static struct regulator_consumer_supply gpio_reg_sdmmc3_vdd_sel_supply[] = {
456 REGULATOR_SUPPLY("vddio_sdmmc3_2v85_1v8", NULL),
457 REGULATOR_SUPPLY("sdmmc3_compu_pu", NULL),
458 REGULATOR_SUPPLY("vddio_sdmmc3", NULL),
459 REGULATOR_SUPPLY("vsys_3v7", NULL),
460};
461
462/* LCD-D23 (GPIO M7) from T30*/
463/* 2-0036 is dev_name of ar0832 in Enterprise A01*/
464/* 2-0032 is alternative dev_name of ar0832 Enterprise A01*/
465/* 2-0010 is dev_name of ov9726 */
466/* 2-0070 is dev_name of PCA9546 in Enterprise A02*/
467/* 6-0036 is dev_name of ar0832 in Enterprise A02 */
468/* 7-0036 is dev_name of ar0832 in Enterprise A02 */
469static struct regulator_consumer_supply fixed_reg_cam_ldo_2v8_en_supply[] = {
470 REGULATOR_SUPPLY("vaa", "2-0036"),
471 REGULATOR_SUPPLY("vaa", "2-0032"),
472 REGULATOR_SUPPLY("avdd", "2-0010"),
473 REGULATOR_SUPPLY("vdd_2v8_cam", NULL),
474 REGULATOR_SUPPLY("vcc", "2-0070"),
475 REGULATOR_SUPPLY("vaa", "6-0036"),
476 REGULATOR_SUPPLY("vaa", "7-0036"),
477};
478
479/* LCD-D9 (GPIO F1) from T30*/
480/* 2-0036 is dev_name of ar0832 in Enterprise A01*/
481/* 2-0032 is alternative dev_name of ar0832 Enterprise A01*/
482/* 2-0010 is dev_name of ov9726 */
483/* 2-0033 is dev_name of tps61050 */
484/* 2-0070 is dev_name of PCA9546 in Enterprise A02*/
485/* 6-0036 is dev_name of ar0832 in Enterprise A02 */
486/* 7-0036 is dev_name of ar0832 in Enterprise A02 */
487static struct regulator_consumer_supply fixed_reg_cam_ldo_1v8_en_supply[] = {
488 REGULATOR_SUPPLY("vdd", "2-0036"),
489 REGULATOR_SUPPLY("vdd", "2-0032"),
490 REGULATOR_SUPPLY("dovdd", "2-0010"),
491 REGULATOR_SUPPLY("vdd_1v8_cam", NULL),
492 REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
493 REGULATOR_SUPPLY("vcc_i2c", "2-0070"),
494 REGULATOR_SUPPLY("vdd", "6-0036"),
495 REGULATOR_SUPPLY("vdd", "7-0036"),
496};
497
498/* LCD-D10 (GPIO F2) from T30*/
499static struct regulator_consumer_supply fixed_reg_vdd_sdmmc3_2v85_en_supply[] = {
500 REGULATOR_SUPPLY("en_vdd_sdmmc3", NULL),
501 REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.2"),
502};
503
504/* LCD_PWR0 (GPIO B2) from T30*/
505static struct regulator_consumer_supply fixed_reg_lcd_1v8_en_supply[] = {
506 REGULATOR_SUPPLY("lcd_vddio_en", NULL),
507};
508
509static struct gpio_regulator_state gpio_reg_sdmmc3_vdd_sel_states[] = {
510 {
511 .gpios = 0,
512 .value = 2850000,
513 },
514 {
515 .gpios = 1,
516 .value = 1800000,
517 },
518};
519
520static struct gpio gpio_reg_sdmmc3_vdd_sel_gpios[] = {
521 {
522 .gpio = TEGRA_GPIO_PM1,
523 .flags = 0,
524 .label = "sdmmc3_vdd_sel",
525 },
526};
527
528/* Macro for defining gpio regulator device data */
529#define GPIO_REG(_id, _name, _input_supply, _active_high, \
530 _boot_state, _delay_us, _minmv, _maxmv) \
531 static struct regulator_init_data ri_data_##_name = \
532 { \
533 .supply_regulator = _input_supply, \
534 .num_consumer_supplies = \
535 ARRAY_SIZE(gpio_reg_##_name##_supply), \
536 .consumer_supplies = gpio_reg_##_name##_supply, \
537 .constraints = { \
538 .name = "gpio_reg_"#_name, \
539 .min_uV = (_minmv)*1000, \
540 .max_uV = (_maxmv)*1000, \
541 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
542 REGULATOR_MODE_STANDBY), \
543 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
544 REGULATOR_CHANGE_STATUS | \
545 REGULATOR_CHANGE_VOLTAGE), \
546 }, \
547 }; \
548 static struct gpio_regulator_config gpio_reg_##_name##_pdata = \
549 { \
550 .supply_name = _input_supply, \
551 .enable_gpio = -EINVAL, \
552 .enable_high = _active_high, \
553 .enabled_at_boot = _boot_state, \
554 .startup_delay = _delay_us, \
555 .gpios = gpio_reg_##_name##_gpios, \
556 .nr_gpios = ARRAY_SIZE(gpio_reg_##_name##_gpios), \
557 .states = gpio_reg_##_name##_states, \
558 .nr_states = ARRAY_SIZE(gpio_reg_##_name##_states), \
559 .type = REGULATOR_VOLTAGE, \
560 .init_data = &ri_data_##_name, \
561 }; \
562 static struct platform_device gpio_reg_##_name##_dev = { \
563 .name = "gpio-regulator", \
564 .id = _id, \
565 .dev = { \
566 .platform_data = &gpio_reg_##_name##_pdata, \
567 }, \
568 }
569
570GPIO_REG(4, sdmmc3_vdd_sel, tps80031_rails(SMPS4),
571 true, false, 0, 1000, 3300);
572
573/* Macro for defining fixed regulator sub device data */
574#define FIXED_REG(_id, _name, _input_supply, _gpio_nr, _active_high, \
575 _millivolts, _boot_state) \
576 static struct regulator_init_data ri_data_##_name = \
577 { \
578 .supply_regulator = _input_supply, \
579 .num_consumer_supplies = \
580 ARRAY_SIZE(fixed_reg_##_name##_supply), \
581 .consumer_supplies = fixed_reg_##_name##_supply, \
582 .constraints = { \
583 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
584 REGULATOR_MODE_STANDBY), \
585 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
586 REGULATOR_CHANGE_STATUS | \
587 REGULATOR_CHANGE_VOLTAGE), \
588 }, \
589 }; \
590 static struct fixed_voltage_config fixed_reg_##_name##_pdata = \
591 { \
592 .supply_name = "fixed_reg_"#_name, \
593 .microvolts = _millivolts * 1000, \
594 .gpio = _gpio_nr, \
595 .enable_high = _active_high, \
596 .enabled_at_boot = _boot_state, \
597 .init_data = &ri_data_##_name, \
598 }; \
599 static struct platform_device fixed_reg_##_name##_dev = { \
600 .name = "reg-fixed-voltage", \
601 .id = _id, \
602 .dev = { \
603 .platform_data = &fixed_reg_##_name##_pdata, \
604 }, \
605 }
606
607FIXED_REG(0, pmu_5v15_en, NULL,
608 ENT_TPS80031_GPIO_REGEN1, true, 5000, 0 );
609FIXED_REG(2, pmu_hdmi_5v0_en, "fixed_reg_pmu_5v15_en",
610 ENT_TPS80031_GPIO_SYSEN, true, 5000, 0);
611FIXED_REG(3, vdd_fuse_en, "fixed_reg_pmu_3v3_en",
612 TEGRA_GPIO_PM0, true, 3300, 0);
613FIXED_REG(5, cam_ldo_2v8_en, NULL,
614 TEGRA_GPIO_PM7, true, 2800, 0);
615FIXED_REG(6, cam_ldo_1v8_en, NULL,
616 TEGRA_GPIO_PF1, true, 1800, 0);
617
618/* Enterprise A02- specific */
619FIXED_REG(1, pmu_3v3_en, "fixed_reg_pmu_5v15_en",
620 ENT_TPS80031_GPIO_REGEN2, true, 3300, 0);
621
622/* Enterprise A03+ specific */
623FIXED_REG(7, vdd_sdmmc3_2v85_en, NULL,
624 TEGRA_GPIO_PF2, true, 2850, 0);
625FIXED_REG(8, lcd_1v8_en, NULL,
626 TEGRA_GPIO_PB2, true, 1800, 0);
627
628#define ADD_FIXED_REG(_name) (&fixed_reg_##_name##_dev)
629
630#define FIXED_REGS_COMMON \
631 ADD_FIXED_REG(pmu_5v15_en), \
632 ADD_FIXED_REG(pmu_hdmi_5v0_en), \
633 ADD_FIXED_REG(vdd_fuse_en), \
634 ADD_FIXED_REG(cam_ldo_2v8_en), \
635 ADD_FIXED_REG(cam_ldo_1v8_en)
636
637static struct platform_device *fixed_regs_devices_a02[] = {
638 FIXED_REGS_COMMON,
639 ADD_FIXED_REG(pmu_3v3_en),
640};
641
642static struct platform_device *fixed_regs_devices_a03[] = {
643 FIXED_REGS_COMMON,
644 ADD_FIXED_REG(vdd_sdmmc3_2v85_en),
645 ADD_FIXED_REG(lcd_1v8_en),
646};
647
648#define ADD_GPIO_REG(_name) (&gpio_reg_##_name##_dev)
649static struct platform_device *gpio_regs_devices[] = {
650 ADD_GPIO_REG(sdmmc3_vdd_sel),
651};
652
653static int __init enterprise_fixed_regulator_init(void)
654{
655 int i;
656 struct board_info board_info;
657 struct platform_device **fixed_regs_devices;
658 int nfixreg_devs;
659
660 tegra_get_board_info(&board_info);
661
662 if (board_info.fab < BOARD_FAB_A03) {
663 fixed_regs_devices = fixed_regs_devices_a02;
664 nfixreg_devs = ARRAY_SIZE(fixed_regs_devices_a02);
665 } else {
666 fixed_regs_devices = fixed_regs_devices_a03;
667 nfixreg_devs = ARRAY_SIZE(fixed_regs_devices_a03);
668 }
669
670 for (i = 0; i < nfixreg_devs; ++i) {
671 struct fixed_voltage_config *fixed_reg_pdata =
672 fixed_regs_devices[i]->dev.platform_data;
673 if (fixed_reg_pdata->gpio < TEGRA_NR_GPIOS)
674 tegra_gpio_enable(fixed_reg_pdata->gpio);
675 }
676 return platform_add_devices(fixed_regs_devices, nfixreg_devs);
677}
678
679static int __init enterprise_gpio_regulator_init(void)
680{
681 int i, j;
682
683 for (i = 0; i < ARRAY_SIZE(gpio_regs_devices); ++i) {
684 struct gpio_regulator_config *gpio_reg_pdata =
685 gpio_regs_devices[i]->dev.platform_data;
686 for (j = 0; j < gpio_reg_pdata->nr_gpios; ++j) {
687 if (gpio_reg_pdata->gpios[j].gpio < TEGRA_NR_GPIOS)
688 tegra_gpio_enable(gpio_reg_pdata->gpios[j].gpio);
689 }
690 }
691 return platform_add_devices(gpio_regs_devices,
692 ARRAY_SIZE(gpio_regs_devices));
693}
694
695static int __init enterprise_regulators_fixed_gpio_init(void)
696{
697 int ret;
698
699 if (!machine_is_tegra_enterprise())
700 return 0;
701
702 ret = enterprise_fixed_regulator_init();
703 if (ret)
704 return ret;
705
706 ret = enterprise_gpio_regulator_init();
707 return ret;
708}
709subsys_initcall_sync(enterprise_regulators_fixed_gpio_init);
710
711int __init enterprise_regulator_init(void)
712{
713 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
714 u32 pmc_ctrl;
715 u32 pmc_dpd_pads;
716 struct board_info board_info;
717
718 tegra_get_board_info(&board_info);
719
720 /* configure the power management controller to trigger PMU
721 * interrupts when low */
722
723 pmc_ctrl = readl(pmc + PMC_CTRL);
724 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
725
726 pmc_dpd_pads = readl(pmc + PMC_DPD_PADS_ORIDE);
727 writel(pmc_dpd_pads & ~PMC_DPD_PADS_ORIDE_BLINK , pmc + PMC_DPD_PADS_ORIDE);
728
729 /* Disable battery charging if power adapter is connected. */
730 if (get_power_supply_type() == POWER_SUPPLY_TYPE_MAINS) {
731 bcharger_pdata.num_consumer_supplies = 0;
732 bcharger_pdata.consumer_supplies = NULL;
733 battery_gauge_data.battery_present = 0;
734 }
735
736 if (board_info.fab < BOARD_FAB_A03) {
737 tps_platform.num_subdevs = ARRAY_SIZE(tps80031_devs_a02);
738 tps_platform.subdevs = tps80031_devs_a02;
739 } else {
740 tps_platform.num_subdevs = ARRAY_SIZE(tps80031_devs_a03);
741 tps_platform.subdevs = tps80031_devs_a03;
742 }
743
744 i2c_register_board_info(4, enterprise_regulators, 1);
745 return 0;
746}
747
748static void enterprise_board_suspend(int lp_state, enum suspend_stage stg)
749{
750 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
751 tegra_console_uart_suspend();
752}
753
754static void enterprise_board_resume(int lp_state, enum resume_stage stg)
755{
756 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
757 tegra_console_uart_resume();
758}
759
760static struct tegra_suspend_platform_data enterprise_suspend_data = {
761 .cpu_timer = 2000,
762 .cpu_off_timer = 200,
763 .suspend_mode = TEGRA_SUSPEND_LP0,
764 .core_timer = 0x7e7e,
765 .core_off_timer = 0,
766 .corereq_high = true,
767 .sysclkreq_high = true,
768 .board_suspend = enterprise_board_suspend,
769 .board_resume = enterprise_board_resume,
770};
771
772static void enterprise_init_deep_sleep_mode(void)
773{
774 struct board_info bi;
775 tegra_get_board_info(&bi);
776
777 if (bi.board_id == BOARD_E1205 && bi.fab == BOARD_FAB_A01)
778 enterprise_suspend_data.suspend_mode = TEGRA_SUSPEND_LP1;
779
780 if ((bi.board_id == BOARD_E1205 && (bi.sku & BOARD_SKU_VF_BIT) == 0) ||
781 (bi.board_id == BOARD_E1197 && (bi.sku & BOARD_SKU_VF_BIT)))
782 enterprise_suspend_data.cpu_timer = 8000;
783}
784
785int __init enterprise_suspend_init(void)
786{
787 enterprise_init_deep_sleep_mode();
788 tegra_init_suspend(&enterprise_suspend_data);
789 return 0;
790}
791
792#ifdef CONFIG_TEGRA_EDP_LIMITS
793
794int __init enterprise_edp_init(void)
795{
796 unsigned int regulator_mA;
797
798 regulator_mA = get_maximum_cpu_current_supported();
799 if (!regulator_mA) {
800 regulator_mA = 2500; /* regular AP30 */
801 }
802 pr_info("%s: CPU regulator %d mA\n", __func__, regulator_mA);
803
804 tegra_init_cpu_edp_limits(regulator_mA);
805 tegra_init_system_edp_limits(TEGRA_BPC_CPU_PWR_LIMIT);
806 return 0;
807}
808#endif
809
810static struct tegra_bpc_mgmt_platform_data bpc_mgmt_platform_data = {
811 .gpio_trigger = TEGRA_BPC_TRIGGER,
812 .bpc_mgmt_timeout = TEGRA_BPC_TIMEOUT,
813};
814
815static struct platform_device enterprise_bpc_mgmt_device = {
816 .name = "tegra-bpc-mgmt",
817 .id = -1,
818 .dev = {
819 .platform_data = &bpc_mgmt_platform_data,
820 },
821};
822
823void __init enterprise_bpc_mgmt_init(void)
824{
825 int int_gpio = TEGRA_GPIO_TO_IRQ(TEGRA_BPC_TRIGGER);
826
827 tegra_gpio_enable(TEGRA_BPC_TRIGGER);
828
829#ifdef CONFIG_SMP
830 cpumask_setall(&(bpc_mgmt_platform_data.affinity_mask));
831 irq_set_affinity_hint(int_gpio,
832 &(bpc_mgmt_platform_data.affinity_mask));
833 irq_set_affinity(int_gpio, &(bpc_mgmt_platform_data.affinity_mask));
834#endif
835 platform_device_register(&enterprise_bpc_mgmt_device);
836
837 return;
838}
diff --git a/arch/arm/mach-tegra/board-enterprise-sdhci.c b/arch/arm/mach-tegra/board-enterprise-sdhci.c
new file mode 100644
index 00000000000..af1a9ea3dd5
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-sdhci.c
@@ -0,0 +1,269 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-sdhci.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation.
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/resource.h>
18#include <linux/platform_device.h>
19#include <linux/wlan_plat.h>
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/mmc/host.h>
25
26#include <asm/mach-types.h>
27#include <mach/irqs.h>
28#include <mach/iomap.h>
29#include <mach/sdhci.h>
30
31#include "gpio-names.h"
32#include "board.h"
33
34
35#define ENTERPRISE_WLAN_PWR TEGRA_GPIO_PV2
36#define ENTERPRISE_WLAN_RST TEGRA_GPIO_PV3
37#define ENTERPRISE_WLAN_WOW TEGRA_GPIO_PU6
38#define ENTERPRISE_SD_CD TEGRA_GPIO_PI5
39
40static void (*wifi_status_cb)(int card_present, void *dev_id);
41static void *wifi_status_cb_devid;
42static int enterprise_wifi_status_register(void (*callback)(int , void *), void *);
43
44static int enterprise_wifi_reset(int on);
45static int enterprise_wifi_power(int on);
46static int enterprise_wifi_set_carddetect(int val);
47
48static struct wifi_platform_data enterprise_wifi_control = {
49 .set_power = enterprise_wifi_power,
50 .set_reset = enterprise_wifi_reset,
51 .set_carddetect = enterprise_wifi_set_carddetect,
52};
53
54static struct resource wifi_resource[] = {
55 [0] = {
56 .name = "bcm4329_wlan_irq",
57 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
58 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
59 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
60 },
61};
62
63static struct platform_device enterprise_wifi_device = {
64 .name = "bcm4329_wlan",
65 .id = 1,
66 .num_resources = 1,
67 .resource = wifi_resource,
68 .dev = {
69 .platform_data = &enterprise_wifi_control,
70 },
71};
72
73static struct resource sdhci_resource0[] = {
74 [0] = {
75 .start = INT_SDMMC1,
76 .end = INT_SDMMC1,
77 .flags = IORESOURCE_IRQ,
78 },
79 [1] = {
80 .start = TEGRA_SDMMC1_BASE,
81 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
82 .flags = IORESOURCE_MEM,
83 },
84};
85
86static struct resource sdhci_resource2[] = {
87 [0] = {
88 .start = INT_SDMMC3,
89 .end = INT_SDMMC3,
90 .flags = IORESOURCE_IRQ,
91 },
92 [1] = {
93 .start = TEGRA_SDMMC3_BASE,
94 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
95 .flags = IORESOURCE_MEM,
96 },
97};
98
99static struct resource sdhci_resource3[] = {
100 [0] = {
101 .start = INT_SDMMC4,
102 .end = INT_SDMMC4,
103 .flags = IORESOURCE_IRQ,
104 },
105 [1] = {
106 .start = TEGRA_SDMMC4_BASE,
107 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
108 .flags = IORESOURCE_MEM,
109 },
110};
111
112static struct embedded_sdio_data embedded_sdio_data0 = {
113 .cccr = {
114 .sdio_vsn = 2,
115 .multi_block = 1,
116 .low_speed = 0,
117 .wide_bus = 0,
118 .high_power = 1,
119 .high_speed = 1,
120 },
121 .cis = {
122 .vendor = 0x02d0,
123 .device = 0x4329,
124 },
125};
126
127static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
128 .mmc_data = {
129 .register_status_notify = enterprise_wifi_status_register,
130 .embedded_sdio = &embedded_sdio_data0,
131 /* FIXME need to revert the built_in change
132 once we use get the signal strength fix of
133 bcmdhd driver from broadcom for bcm4329 chipset*/
134 .built_in = 0,
135 },
136 .cd_gpio = -1,
137 .wp_gpio = -1,
138 .power_gpio = -1,
139 .max_clk_limit = 45000000,
140};
141
142static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
143 .cd_gpio = -1,
144 .wp_gpio = -1,
145 .power_gpio = -1,
146};
147
148static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
149 .cd_gpio = -1,
150 .wp_gpio = -1,
151 .power_gpio = -1,
152 .is_8bit = 1,
153 .mmc_data = {
154 .built_in = 1,
155 }
156};
157
158static struct platform_device tegra_sdhci_device0 = {
159 .name = "sdhci-tegra",
160 .id = 0,
161 .resource = sdhci_resource0,
162 .num_resources = ARRAY_SIZE(sdhci_resource0),
163 .dev = {
164 .platform_data = &tegra_sdhci_platform_data0,
165 },
166};
167
168static struct platform_device tegra_sdhci_device2 = {
169 .name = "sdhci-tegra",
170 .id = 2,
171 .resource = sdhci_resource2,
172 .num_resources = ARRAY_SIZE(sdhci_resource2),
173 .dev = {
174 .platform_data = &tegra_sdhci_platform_data2,
175 },
176};
177
178static struct platform_device tegra_sdhci_device3 = {
179 .name = "sdhci-tegra",
180 .id = 3,
181 .resource = sdhci_resource3,
182 .num_resources = ARRAY_SIZE(sdhci_resource3),
183 .dev = {
184 .platform_data = &tegra_sdhci_platform_data3,
185 },
186};
187
188static int enterprise_wifi_status_register(
189 void (*callback)(int card_present, void *dev_id),
190 void *dev_id)
191{
192 if (wifi_status_cb)
193 return -EAGAIN;
194 wifi_status_cb = callback;
195 wifi_status_cb_devid = dev_id;
196 return 0;
197}
198
199static int enterprise_wifi_set_carddetect(int val)
200{
201 pr_debug("%s: %d\n", __func__, val);
202 if (wifi_status_cb)
203 wifi_status_cb(val, wifi_status_cb_devid);
204 else
205 pr_warning("%s: Nobody to notify\n", __func__);
206 return 0;
207}
208
209static int enterprise_wifi_power(int on)
210{
211 pr_debug("%s: %d\n", __func__, on);
212 gpio_set_value(ENTERPRISE_WLAN_PWR, on);
213 mdelay(100);
214 gpio_set_value(ENTERPRISE_WLAN_RST, on);
215 mdelay(200);
216
217 return 0;
218}
219
220static int enterprise_wifi_reset(int on)
221{
222 pr_debug("%s: do nothing\n", __func__);
223 return 0;
224}
225
226static int __init enterprise_wifi_init(void)
227{
228 int rc;
229
230 rc = gpio_request(ENTERPRISE_WLAN_PWR, "wlan_power");
231 if (rc)
232 pr_err("WLAN_PWR gpio request failed:%d\n", rc);
233 rc = gpio_request(ENTERPRISE_WLAN_RST, "wlan_rst");
234 if (rc)
235 pr_err("WLAN_RST gpio request failed:%d\n", rc);
236 rc = gpio_request(ENTERPRISE_WLAN_WOW, "bcmsdh_sdmmc");
237 if (rc)
238 pr_err("WLAN_WOW gpio request failed:%d\n", rc);
239
240 tegra_gpio_enable(ENTERPRISE_WLAN_PWR);
241 tegra_gpio_enable(ENTERPRISE_WLAN_RST);
242 tegra_gpio_enable(ENTERPRISE_WLAN_WOW);
243
244 rc = gpio_direction_output(ENTERPRISE_WLAN_PWR, 0);
245 if (rc)
246 pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
247 gpio_direction_output(ENTERPRISE_WLAN_RST, 0);
248 if (rc)
249 pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
250 rc = gpio_direction_input(ENTERPRISE_WLAN_WOW);
251 if (rc)
252 pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
253
254 platform_device_register(&enterprise_wifi_device);
255 return 0;
256}
257
258int __init enterprise_sdhci_init(void)
259{
260 platform_device_register(&tegra_sdhci_device3);
261
262 tegra_gpio_enable(ENTERPRISE_SD_CD);
263 tegra_sdhci_platform_data2.cd_gpio = ENTERPRISE_SD_CD;
264 platform_device_register(&tegra_sdhci_device2);
265
266 platform_device_register(&tegra_sdhci_device0);
267 enterprise_wifi_init();
268 return 0;
269}
diff --git a/arch/arm/mach-tegra/board-enterprise-sensors.c b/arch/arm/mach-tegra/board-enterprise-sensors.c
new file mode 100644
index 00000000000..f775c2bd3b3
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-sensors.c
@@ -0,0 +1,673 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-sensors.c
3 *
4 * Copyright (c) 2011, NVIDIA CORPORATION, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/i2c.h>
35#include <linux/delay.h>
36#include <linux/i2c/pca954x.h>
37#include <linux/nct1008.h>
38#include <linux/err.h>
39#include <linux/mpu.h>
40#include <linux/platform_data/ina230.h>
41#include <linux/regulator/consumer.h>
42#include <linux/slab.h>
43#include <mach/gpio.h>
44#include <media/ar0832_main.h>
45#include <media/tps61050.h>
46#include <media/ov9726.h>
47#include <mach/edp.h>
48#include <mach/thermal.h>
49#include "cpu-tegra.h"
50#include "gpio-names.h"
51#include "board-enterprise.h"
52#include "board.h"
53
54static int nct_get_temp(void *_data, long *temp)
55{
56 struct nct1008_data *data = _data;
57 return nct1008_thermal_get_temp(data, temp);
58}
59
60static int nct_get_temp_low(void *_data, long *temp)
61{
62 struct nct1008_data *data = _data;
63 return nct1008_thermal_get_temp_low(data, temp);
64}
65
66static int nct_set_limits(void *_data,
67 long lo_limit_milli,
68 long hi_limit_milli)
69{
70 struct nct1008_data *data = _data;
71 return nct1008_thermal_set_limits(data,
72 lo_limit_milli,
73 hi_limit_milli);
74}
75
76static int nct_set_alert(void *_data,
77 void (*alert_func)(void *),
78 void *alert_data)
79{
80 struct nct1008_data *data = _data;
81 return nct1008_thermal_set_alert(data, alert_func, alert_data);
82}
83
84static int nct_set_shutdown_temp(void *_data, long shutdown_temp)
85{
86 struct nct1008_data *data = _data;
87 return nct1008_thermal_set_shutdown_temp(data,
88 shutdown_temp);
89}
90
91static void nct1008_probe_callback(struct nct1008_data *data)
92{
93 struct tegra_thermal_device *thermal_device;
94
95 thermal_device = kzalloc(sizeof(struct tegra_thermal_device),
96 GFP_KERNEL);
97 if (!thermal_device) {
98 pr_err("unable to allocate thermal device\n");
99 return;
100 }
101
102 thermal_device->name = "nct1008";
103 thermal_device->data = data;
104 thermal_device->offset = TDIODE_OFFSET;
105 thermal_device->get_temp = nct_get_temp;
106 thermal_device->get_temp_low = nct_get_temp_low;
107 thermal_device->set_limits = nct_set_limits;
108 thermal_device->set_alert = nct_set_alert;
109 thermal_device->set_shutdown_temp = nct_set_shutdown_temp;
110
111 tegra_thermal_set_device(thermal_device);
112}
113
114static struct nct1008_platform_data enterprise_nct1008_pdata = {
115 .supported_hwrev = true,
116 .ext_range = true,
117 .conv_rate = 0x08,
118 .offset = 8, /* 4 * 2C. Bug 844025 - 1C for device accuracies */
119 .probe_callback = nct1008_probe_callback,
120};
121
122static struct i2c_board_info enterprise_i2c4_nct1008_board_info[] = {
123 {
124 I2C_BOARD_INFO("nct1008", 0x4C),
125 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PH7),
126 .platform_data = &enterprise_nct1008_pdata,
127 }
128};
129
130static void enterprise_nct1008_init(void)
131{
132 int ret;
133
134 tegra_gpio_enable(TEGRA_GPIO_PH7);
135 ret = gpio_request(TEGRA_GPIO_PH7, "temp_alert");
136 if (ret < 0) {
137 pr_err("%s: gpio_request failed %d\n", __func__, ret);
138 return;
139 }
140
141 ret = gpio_direction_input(TEGRA_GPIO_PH7);
142 if (ret < 0) {
143 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
144 gpio_free(TEGRA_GPIO_PH7);
145 return;
146 }
147
148 i2c_register_board_info(4, enterprise_i2c4_nct1008_board_info,
149 ARRAY_SIZE(enterprise_i2c4_nct1008_board_info));
150}
151
152/* MPU board file definition */
153#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
154#define MPU_GYRO_NAME "mpu3050"
155#endif
156#if (MPU_GYRO_TYPE == MPU_TYPE_MPU6050)
157#define MPU_GYRO_NAME "mpu6050"
158#endif
159static struct mpu_platform_data mpu_gyro_data = {
160 .int_config = 0x10,
161 .level_shifter = 0,
162 .orientation = MPU_GYRO_ORIENTATION, /* Located in board_[platformname].h */
163};
164
165#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
166static struct ext_slave_platform_data mpu_accel_data = {
167 .address = MPU_ACCEL_ADDR,
168 .irq = 0,
169 .adapt_num = MPU_ACCEL_BUS_NUM,
170 .bus = EXT_SLAVE_BUS_SECONDARY,
171 .orientation = MPU_ACCEL_ORIENTATION, /* Located in board_[platformname].h */
172};
173#endif
174
175static struct ext_slave_platform_data mpu_compass_data = {
176 .address = MPU_COMPASS_ADDR,
177 .irq = 0,
178 .adapt_num = MPU_COMPASS_BUS_NUM,
179 .bus = EXT_SLAVE_BUS_PRIMARY,
180 .orientation = MPU_COMPASS_ORIENTATION, /* Located in board_[platformname].h */
181};
182
183static struct i2c_board_info __initdata inv_mpu_i2c2_board_info[] = {
184 {
185 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
186 .irq = TEGRA_GPIO_TO_IRQ(MPU_GYRO_IRQ_GPIO),
187 .platform_data = &mpu_gyro_data,
188 },
189#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
190 {
191 I2C_BOARD_INFO(MPU_ACCEL_NAME, MPU_ACCEL_ADDR),
192#if MPU_ACCEL_IRQ_GPIO
193 .irq = TEGRA_GPIO_TO_IRQ(MPU_ACCEL_IRQ_GPIO),
194#endif
195 .platform_data = &mpu_accel_data,
196 },
197#endif
198 {
199 I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
200#if MPU_COMPASS_IRQ_GPIO
201 .irq = TEGRA_GPIO_TO_IRQ(MPU_COMPASS_IRQ_GPIO),
202#endif
203 .platform_data = &mpu_compass_data,
204 },
205};
206
207static void mpuirq_init(void)
208{
209 int ret = 0;
210
211 pr_info("*** MPU START *** mpuirq_init...\n");
212
213#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
214#if MPU_ACCEL_IRQ_GPIO
215 /* ACCEL-IRQ assignment */
216 tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
217 ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
218 if (ret < 0) {
219 pr_err("%s: gpio_request failed %d\n", __func__, ret);
220 return;
221 }
222
223 ret = gpio_direction_input(MPU_ACCEL_IRQ_GPIO);
224 if (ret < 0) {
225 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
226 gpio_free(MPU_ACCEL_IRQ_GPIO);
227 return;
228 }
229#endif
230#endif
231
232 /* MPU-IRQ assignment */
233 tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
234 ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
235 if (ret < 0) {
236 pr_err("%s: gpio_request failed %d\n", __func__, ret);
237 return;
238 }
239
240 ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO);
241 if (ret < 0) {
242 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
243 gpio_free(MPU_GYRO_IRQ_GPIO);
244 return;
245 }
246 pr_info("*** MPU END *** mpuirq_init...\n");
247
248 i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c2_board_info,
249 ARRAY_SIZE(inv_mpu_i2c2_board_info));
250}
251
252static inline void enterprise_msleep(u32 t)
253{
254 /*
255 If timer value is between ( 10us - 20ms),
256 usleep_range() is recommended.
257 Please read Documentation/timers/timers-howto.txt.
258 */
259 usleep_range(t*1000, t*1000 + 500);
260}
261
262static struct i2c_board_info enterprise_i2c0_isl_board_info[] = {
263 {
264 I2C_BOARD_INFO("isl29028", 0x44),
265 }
266};
267
268static void enterprise_isl_init(void)
269{
270 i2c_register_board_info(0, enterprise_i2c0_isl_board_info,
271 ARRAY_SIZE(enterprise_i2c0_isl_board_info));
272}
273
274enum CAMERA_INDEX {
275 CAM_REAR_LEFT,
276 CAM_REAR_RIGHT,
277 CAM_FRONT,
278 NUM_OF_CAM
279};
280
281struct enterprise_power_rail {
282 struct regulator *cam_reg;
283 struct regulator *csi_reg;
284};
285
286static struct enterprise_power_rail ent_vicsi_pwr[NUM_OF_CAM];
287
288static int enterprise_cam_pwr(enum CAMERA_INDEX cam, bool pwr_on)
289{
290 struct enterprise_power_rail *reg_cam = &ent_vicsi_pwr[cam];
291 int ret = 0;
292
293 /*
294 * SW must turn on 1.8V first then 2.8V
295 * SW must turn off 2.8V first then 1.8V
296 */
297 if (pwr_on) {
298 if (reg_cam->csi_reg == NULL) {
299 reg_cam->csi_reg = regulator_get(NULL,
300 "avdd_dsi_csi");
301 if (IS_ERR_OR_NULL(reg_cam->csi_reg)) {
302 pr_err("%s: csi pwr err\n", __func__);
303 ret = PTR_ERR(reg_cam->csi_reg);
304 goto enterprise_cam_pwr_fail;
305 }
306 }
307
308 ret = regulator_enable(reg_cam->csi_reg);
309 if (ret) {
310 pr_err("%s: enable csi pwr err\n", __func__);
311 goto enterprise_cam_pwr_fail;
312 }
313
314 if (reg_cam->cam_reg == NULL) {
315 reg_cam->cam_reg = regulator_get(NULL,
316 "vddio_cam");
317 if (IS_ERR_OR_NULL(reg_cam->cam_reg)) {
318 pr_err("%s: vddio pwr err\n", __func__);
319 ret = PTR_ERR(reg_cam->cam_reg);
320 regulator_disable(reg_cam->csi_reg);
321 goto enterprise_cam_pwr_fail;
322 }
323 }
324
325 ret = regulator_enable(reg_cam->cam_reg);
326 if (ret) {
327 pr_err("%s: enable vddio pwr err\n", __func__);
328 regulator_disable(reg_cam->csi_reg);
329 goto enterprise_cam_pwr_fail;
330 }
331 } else {
332 if (reg_cam->cam_reg)
333 regulator_disable(reg_cam->cam_reg);
334
335 if (reg_cam->csi_reg)
336 regulator_disable(reg_cam->csi_reg);
337 }
338 return 0;
339
340enterprise_cam_pwr_fail:
341 if (!IS_ERR_OR_NULL(reg_cam->cam_reg))
342 regulator_put(reg_cam->cam_reg);
343 reg_cam->cam_reg = NULL;
344
345 if (!IS_ERR_OR_NULL(reg_cam->csi_reg))
346 regulator_put(reg_cam->csi_reg);
347 reg_cam->csi_reg = NULL;
348
349 return ret;
350}
351
352static int enterprise_ar0832_ri_power_on(int is_stereo)
353{
354 int ret = 0;
355
356 pr_info("%s: ++\n", __func__);
357 ret = enterprise_cam_pwr(CAM_REAR_RIGHT, true);
358
359 /* Release Reset */
360 if (is_stereo) {
361 gpio_set_value(CAM1_RST_L_GPIO, 1);
362 gpio_set_value(CAM2_RST_L_GPIO, 1);
363 } else
364 gpio_set_value(CAM1_RST_L_GPIO, 1);
365 /*
366 It takes 2400 EXTCLK for ar0832 to be ready for I2c.
367 EXTCLK is 10 ~ 24MHz. 1 ms should be enough to cover
368 at least 2400 EXTCLK within frequency range.
369 */
370 enterprise_msleep(1);
371
372 return ret;
373}
374
375static int enterprise_ar0832_le_power_on(int is_stereo)
376{
377 int ret = 0;
378
379 pr_info("%s: ++\n", __func__);
380 ret = enterprise_cam_pwr(CAM_REAR_LEFT, true);
381
382 /* Release Reset */
383 gpio_set_value(CAM2_RST_L_GPIO, 1);
384
385 /*
386 It takes 2400 EXTCLK for ar0832 to be ready for I2c.
387 EXTCLK is 10 ~ 24MHz. 1 ms should be enough to cover
388 at least 2400 EXTCLK within frequency range.
389 */
390 enterprise_msleep(1);
391
392 /* CSI B is shared between Front camera and Rear Left camera */
393 gpio_set_value(CAM_CSI_MUX_SEL_GPIO, 1);
394
395 return ret;
396}
397
398static int enterprise_ar0832_ri_power_off(int is_stereo)
399{
400 int ret;
401
402 pr_info("%s: ++\n", __func__);
403 ret = enterprise_cam_pwr(CAM_REAR_RIGHT, false);
404
405 /* Assert Reset */
406 if (is_stereo) {
407 gpio_set_value(CAM1_RST_L_GPIO, 0);
408 gpio_set_value(CAM2_RST_L_GPIO, 0);
409 } else
410 gpio_set_value(CAM1_RST_L_GPIO, 0);
411
412 return ret;
413}
414
415static int enterprise_ar0832_le_power_off(int is_stereo)
416{
417 int ret;
418
419 pr_info("%s: ++\n", __func__);
420 ret = enterprise_cam_pwr(CAM_REAR_LEFT, false);
421
422 /* Assert Reset */
423 gpio_set_value(CAM2_RST_L_GPIO, 0);
424
425 return ret;
426}
427
428static int enterprise_ov9726_power_on(void)
429{
430 pr_info("ov9726 power on\n");
431
432 /* switch mipi mux to front camera */
433 gpio_set_value(CAM_CSI_MUX_SEL_GPIO, CAM_CSI_MUX_SEL_FRONT);
434 enterprise_cam_pwr(CAM_FRONT, true);
435
436 return 0;
437}
438
439static int enterprise_ov9726_power_off(void)
440{
441 pr_info("ov9726 power off\n");
442
443 enterprise_cam_pwr(CAM_FRONT, false);
444
445 return 0;
446}
447
448struct ov9726_platform_data enterprise_ov9726_data = {
449 .power_on = enterprise_ov9726_power_on,
450 .power_off = enterprise_ov9726_power_off,
451 .gpio_rst = CAM3_RST_L_GPIO,
452 .rst_low_active = true,
453 .gpio_pwdn = CAM3_PWDN_GPIO,
454 .pwdn_low_active = false,
455};
456
457static struct nvc_torch_pin_state enterprise_tps61050_pinstate = {
458 .mask = 0x0008, /*VGP3*/
459 .values = 0x0008,
460};
461
462static struct tps61050_platform_data enterprise_tps61050_pdata = {
463 .dev_name = "torch",
464 .pinstate = &enterprise_tps61050_pinstate,
465};
466
467
468struct enterprise_cam_gpio {
469 int gpio;
470 const char *label;
471 int value;
472};
473
474#define TEGRA_CAMERA_GPIO(_gpio, _label, _value) \
475 { \
476 .gpio = _gpio, \
477 .label = _label, \
478 .value = _value, \
479 }
480
481static struct enterprise_cam_gpio enterprise_cam_gpio_data[] = {
482 [0] = TEGRA_CAMERA_GPIO(CAM_CSI_MUX_SEL_GPIO, "cam_csi_sel", 1),
483 [1] = TEGRA_CAMERA_GPIO(CAM1_RST_L_GPIO, "cam1_rst_lo", 0),
484 [2] = TEGRA_CAMERA_GPIO(CAM2_RST_L_GPIO, "cam2_rst_lo", 0),
485 [3] = TEGRA_CAMERA_GPIO(CAM3_RST_L_GPIO, "cam3_rst_lo", 0),
486 [4] = TEGRA_CAMERA_GPIO(CAM3_PWDN_GPIO, "cam3_pwdn", 1),
487 [5] = TEGRA_CAMERA_GPIO(CAM_FLASH_EN_GPIO, "flash_en", 1),
488 [6] = TEGRA_CAMERA_GPIO(CAM_I2C_MUX_RST_EXP, "cam_i2c_mux_rst", 1),
489};
490
491static struct pca954x_platform_mode enterprise_pca954x_modes[] = {
492 { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = true, },
493 { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = true, },
494 { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = true, },
495 { .adap_id = PCA954x_I2C_BUS3, .deselect_on_exit = true, },
496};
497
498static struct pca954x_platform_data enterprise_pca954x_data = {
499 .modes = enterprise_pca954x_modes,
500 .num_modes = ARRAY_SIZE(enterprise_pca954x_modes),
501};
502
503static struct ar0832_platform_data enterprise_ar0832_ri_data = {
504 .power_on = enterprise_ar0832_ri_power_on,
505 .power_off = enterprise_ar0832_ri_power_off,
506 .id = "right",
507};
508
509static struct ar0832_platform_data enterprise_ar0832_le_data = {
510 .power_on = enterprise_ar0832_le_power_on,
511 .power_off = enterprise_ar0832_le_power_off,
512 .id = "left",
513};
514
515static const struct i2c_board_info enterprise_i2c2_boardinfo[] = {
516 {
517 I2C_BOARD_INFO("pca9546", 0x70),
518 .platform_data = &enterprise_pca954x_data,
519 },
520 {
521 I2C_BOARD_INFO("tps61050", 0x33),
522 .platform_data = &enterprise_tps61050_pdata,
523 },
524 {
525 I2C_BOARD_INFO("ov9726", OV9726_I2C_ADDR >> 1),
526 .platform_data = &enterprise_ov9726_data,
527 },
528};
529
530/*
531 * Since ar0832 driver should support multiple devices, slave
532 * address should be changed after it is open. Default slave
533 * address of ar0832 is 0x36. It will be changed to alternate
534 * address defined below when device is open.
535 */
536static struct i2c_board_info ar0832_i2c2_boardinfo[] = {
537 {
538 /* 0x36: alternative slave address */
539 I2C_BOARD_INFO("ar0832", 0x36),
540 .platform_data = &enterprise_ar0832_ri_data,
541 },
542 {
543 /* 0x32: alternative slave address */
544 I2C_BOARD_INFO("ar0832", 0x32),
545 .platform_data = &enterprise_ar0832_le_data,
546 },
547 {
548 I2C_BOARD_INFO("tps61050", 0x33),
549 .platform_data = &enterprise_tps61050_pdata,
550 },
551 {
552 I2C_BOARD_INFO("ov9726", OV9726_I2C_ADDR >> 1),
553 .platform_data = &enterprise_ov9726_data,
554 },
555};
556
557static struct i2c_board_info enterprise_i2c6_boardinfo[] = {
558 {
559 I2C_BOARD_INFO("ar0832", 0x36),
560 .platform_data = &enterprise_ar0832_le_data,
561 },
562};
563
564static struct i2c_board_info enterprise_i2c7_boardinfo[] = {
565 {
566 I2C_BOARD_INFO("ar0832", 0x36),
567 .platform_data = &enterprise_ar0832_ri_data,
568 },
569};
570
571static int enterprise_cam_init(void)
572{
573 int ret;
574 int i;
575 struct board_info bi;
576 struct board_info cam_bi;
577 bool i2c_mux = false;
578
579 pr_info("%s:++\n", __func__);
580 memset(ent_vicsi_pwr, 0, sizeof(ent_vicsi_pwr));
581 for (i = 0; i < ARRAY_SIZE(enterprise_cam_gpio_data); i++) {
582 ret = gpio_request(enterprise_cam_gpio_data[i].gpio,
583 enterprise_cam_gpio_data[i].label);
584 if (ret < 0) {
585 pr_err("%s: gpio_request failed for gpio #%d\n",
586 __func__, i);
587 goto fail_free_gpio;
588 }
589 gpio_direction_output(enterprise_cam_gpio_data[i].gpio,
590 enterprise_cam_gpio_data[i].value);
591 gpio_export(enterprise_cam_gpio_data[i].gpio, false);
592 tegra_gpio_enable(enterprise_cam_gpio_data[i].gpio);
593 }
594
595 tegra_get_board_info(&bi);
596 tegra_get_camera_board_info(&cam_bi);
597
598 if (bi.board_id == BOARD_E1205) {
599 if (bi.fab == BOARD_FAB_A00 || bi.fab == BOARD_FAB_A01)
600 i2c_mux = false;
601 else if (bi.fab == BOARD_FAB_A02)
602 i2c_mux = true;
603 } else if (bi.board_id == BOARD_E1197) {
604 if (cam_bi.fab == BOARD_FAB_A00)
605 i2c_mux = false;
606 else if (cam_bi.fab == BOARD_FAB_A01)
607 i2c_mux = true;
608 }
609
610 if (!i2c_mux)
611 i2c_register_board_info(2, ar0832_i2c2_boardinfo,
612 ARRAY_SIZE(ar0832_i2c2_boardinfo));
613 else {
614 i2c_register_board_info(2, enterprise_i2c2_boardinfo,
615 ARRAY_SIZE(enterprise_i2c2_boardinfo));
616 /*
617 * Right camera is on PCA954x's I2C BUS1,
618 * Left camera is on BUS0
619 */
620 i2c_register_board_info(PCA954x_I2C_BUS0, enterprise_i2c6_boardinfo,
621 ARRAY_SIZE(enterprise_i2c6_boardinfo));
622 i2c_register_board_info(PCA954x_I2C_BUS1, enterprise_i2c7_boardinfo,
623 ARRAY_SIZE(enterprise_i2c7_boardinfo));
624 }
625 return 0;
626
627fail_free_gpio:
628 pr_err("%s enterprise_cam_init failed!\n", __func__);
629 while (i--)
630 gpio_free(enterprise_cam_gpio_data[i].gpio);
631 return ret;
632}
633
634#define ENTERPRISE_INA230_ENABLED 0
635
636#if ENTERPRISE_INA230_ENABLED
637static struct ina230_platform_data ina230_platform = {
638 .rail_name = "VDD_AC_BAT",
639 .current_threshold = TEGRA_CUR_MON_THRESHOLD,
640 .resistor = TEGRA_CUR_MON_RESISTOR,
641 .min_cores_online = TEGRA_CUR_MON_MIN_CORES,
642};
643
644static struct i2c_board_info enterprise_i2c0_ina230_info[] = {
645 {
646 I2C_BOARD_INFO("ina230", 0x42),
647 .platform_data = &ina230_platform,
648 .irq = -1,
649 },
650};
651
652static int __init enterprise_ina230_init(void)
653{
654 return i2c_register_board_info(0, enterprise_i2c0_ina230_info,
655 ARRAY_SIZE(enterprise_i2c0_ina230_info));
656}
657#endif
658
659int __init enterprise_sensors_init(void)
660{
661 int ret;
662
663 enterprise_isl_init();
664 enterprise_nct1008_init();
665 mpuirq_init();
666#if ENTERPRISE_INA230_ENABLED
667 enterprise_ina230_init();
668#endif
669 ret = enterprise_cam_init();
670
671 return ret;
672}
673
diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c
new file mode 100644
index 00000000000..62d58a3bcbd
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise.c
@@ -0,0 +1,1005 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise.c
3 *
4 * Copyright (c) 2011-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/serial_8250.h>
28#include <linux/i2c.h>
29#include <linux/dma-mapping.h>
30#include <linux/delay.h>
31#include <linux/i2c-tegra.h>
32#include <linux/gpio.h>
33#include <linux/input.h>
34#include <linux/platform_data/tegra_usb.h>
35#include <linux/spi/spi.h>
36#include <linux/tegra_uart.h>
37#include <linux/fsl_devices.h>
38#include <linux/i2c/atmel_mxt_ts.h>
39#include <linux/memblock.h>
40
41#include <linux/nfc/pn544.h>
42#include <sound/max98088.h>
43
44#include <mach/clk.h>
45#include <mach/iomap.h>
46#include <mach/irqs.h>
47#include <mach/pinmux.h>
48#include <mach/iomap.h>
49#include <mach/io.h>
50#include <asm/mach-types.h>
51#include <asm/mach/arch.h>
52#include <mach/usb_phy.h>
53#include <mach/i2s.h>
54#include <mach/tegra_asoc_pdata.h>
55#include <mach/thermal.h>
56#include <mach/tegra-bb-power.h>
57#include "board.h"
58#include "clock.h"
59#include "board-enterprise.h"
60#include "baseband-xmm-power.h"
61#include "devices.h"
62#include "gpio-names.h"
63#include "fuse.h"
64#include "pm.h"
65
66/* All units are in millicelsius */
67static struct tegra_thermal_data thermal_data = {
68 .temp_throttle = 85000,
69 .temp_shutdown = 90000,
70 .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */
71#ifdef CONFIG_TEGRA_EDP_LIMITS
72 .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */
73 .hysteresis_edp = 3000,
74#endif
75#ifdef CONFIG_TEGRA_THERMAL_SYSFS
76 .tc1 = 0,
77 .tc2 = 1,
78 .passive_delay = 2000,
79#else
80 .hysteresis_throttle = 1000,
81#endif
82};
83
84/* !!!TODO: Change for enterprise (Taken from Cardhu) */
85static struct tegra_utmip_config utmi_phy_config[] = {
86 [0] = {
87 .hssync_start_delay = 0,
88 .idle_wait_delay = 17,
89 .elastic_limit = 16,
90 .term_range_adj = 6,
91 .xcvr_setup = 15,
92 .xcvr_setup_offset = 0,
93 .xcvr_use_fuses = 1,
94 .xcvr_lsfslew = 2,
95 .xcvr_lsrslew = 2,
96 },
97 [1] = {
98 .hssync_start_delay = 0,
99 .idle_wait_delay = 17,
100 .elastic_limit = 16,
101 .term_range_adj = 6,
102 .xcvr_setup = 15,
103 .xcvr_setup_offset = 0,
104 .xcvr_use_fuses = 1,
105 .xcvr_lsfslew = 2,
106 .xcvr_lsrslew = 2,
107 },
108 [2] = {
109 .hssync_start_delay = 0,
110 .idle_wait_delay = 17,
111 .elastic_limit = 16,
112 .term_range_adj = 6,
113 .xcvr_setup = 8,
114 .xcvr_setup_offset = 0,
115 .xcvr_use_fuses = 1,
116 .xcvr_lsfslew = 2,
117 .xcvr_lsrslew = 2,
118 },
119};
120
121static struct resource enterprise_bcm4329_rfkill_resources[] = {
122 {
123 .name = "bcm4329_nshutdown_gpio",
124 .start = TEGRA_GPIO_PE6,
125 .end = TEGRA_GPIO_PE6,
126 .flags = IORESOURCE_IO,
127 },
128};
129
130static struct platform_device enterprise_bcm4329_rfkill_device = {
131 .name = "bcm4329_rfkill",
132 .id = -1,
133 .num_resources = ARRAY_SIZE(enterprise_bcm4329_rfkill_resources),
134 .resource = enterprise_bcm4329_rfkill_resources,
135};
136
137static struct resource enterprise_bluesleep_resources[] = {
138 [0] = {
139 .name = "gpio_host_wake",
140 .start = TEGRA_GPIO_PS2,
141 .end = TEGRA_GPIO_PS2,
142 .flags = IORESOURCE_IO,
143 },
144 [1] = {
145 .name = "gpio_ext_wake",
146 .start = TEGRA_GPIO_PE7,
147 .end = TEGRA_GPIO_PE7,
148 .flags = IORESOURCE_IO,
149 },
150 [2] = {
151 .name = "host_wake",
152 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2),
153 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2),
154 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
155 },
156};
157
158static struct platform_device enterprise_bluesleep_device = {
159 .name = "bluesleep",
160 .id = -1,
161 .num_resources = ARRAY_SIZE(enterprise_bluesleep_resources),
162 .resource = enterprise_bluesleep_resources,
163};
164
165static void __init enterprise_setup_bluesleep(void)
166{
167 platform_device_register(&enterprise_bluesleep_device);
168 tegra_gpio_enable(TEGRA_GPIO_PS2);
169 tegra_gpio_enable(TEGRA_GPIO_PE7);
170 return;
171}
172
173static __initdata struct tegra_clk_init_table enterprise_clk_init_table[] = {
174 /* name parent rate enabled */
175 { "pll_m", NULL, 0, false},
176 { "hda", "pll_p", 108000000, false},
177 { "hda2codec_2x","pll_p", 48000000, false},
178 { "pwm", "clk_32k", 32768, false},
179 { "blink", "clk_32k", 32768, true},
180 { "i2s0", "pll_a_out0", 0, false},
181 { "i2s1", "pll_a_out0", 0, false},
182 { "i2s2", "pll_a_out0", 0, false},
183 { "i2s3", "pll_a_out0", 0, false},
184 { "spdif_out", "pll_a_out0", 0, false},
185 { "d_audio", "clk_m", 12000000, false},
186 { "dam0", "clk_m", 12000000, false},
187 { "dam1", "clk_m", 12000000, false},
188 { "dam2", "clk_m", 12000000, false},
189 { "audio0", "i2s0_sync", 0, false},
190 { "audio1", "i2s1_sync", 0, false},
191 { "audio2", "i2s2_sync", 0, false},
192 { "audio3", "i2s3_sync", 0, false},
193 { "vi", "pll_p", 0, false},
194 { "vi_sensor", "pll_p", 0, false},
195 { NULL, NULL, 0, 0},
196};
197
198static struct tegra_i2c_platform_data enterprise_i2c1_platform_data = {
199 .adapter_nr = 0,
200 .bus_count = 1,
201 .bus_clk_rate = { 100000, 0 },
202 .scl_gpio = {TEGRA_GPIO_PC4, 0},
203 .sda_gpio = {TEGRA_GPIO_PC5, 0},
204 .arb_recovery = arb_lost_recovery,
205};
206
207static struct tegra_i2c_platform_data enterprise_i2c2_platform_data = {
208 .adapter_nr = 1,
209 .bus_count = 1,
210 .bus_clk_rate = { 100000, 0 },
211 .is_clkon_always = true,
212 .scl_gpio = {TEGRA_GPIO_PT5, 0},
213 .sda_gpio = {TEGRA_GPIO_PT6, 0},
214 .arb_recovery = arb_lost_recovery,
215};
216
217static struct tegra_i2c_platform_data enterprise_i2c3_platform_data = {
218 .adapter_nr = 2,
219 .bus_count = 1,
220 .bus_clk_rate = { 271000, 0 },
221 .scl_gpio = {TEGRA_GPIO_PBB1, 0},
222 .sda_gpio = {TEGRA_GPIO_PBB2, 0},
223 .arb_recovery = arb_lost_recovery,
224};
225
226static struct tegra_i2c_platform_data enterprise_i2c4_platform_data = {
227 .adapter_nr = 3,
228 .bus_count = 1,
229 .bus_clk_rate = { 100000, 0 },
230 .scl_gpio = {TEGRA_GPIO_PV4, 0},
231 .sda_gpio = {TEGRA_GPIO_PV5, 0},
232 .arb_recovery = arb_lost_recovery,
233};
234
235static struct tegra_i2c_platform_data enterprise_i2c5_platform_data = {
236 .adapter_nr = 4,
237 .bus_count = 1,
238 .bus_clk_rate = { 100000, 0 },
239 .scl_gpio = {TEGRA_GPIO_PZ6, 0},
240 .sda_gpio = {TEGRA_GPIO_PZ7, 0},
241 .arb_recovery = arb_lost_recovery,
242};
243
244/* Equalizer filter coefs generated from the MAXIM MAX98088
245 * evkit software tool */
246static struct max98088_eq_cfg max98088_eq_cfg[] = {
247 {
248 .name = "FLAT",
249 .rate = 44100,
250 .band1 = {0x2000, 0xC002, 0x4000, 0x00E9, 0x0000},
251 .band2 = {0x2000, 0xC00F, 0x4000, 0x02BC, 0x0000},
252 .band3 = {0x2000, 0xC0A7, 0x4000, 0x0916, 0x0000},
253 .band4 = {0x2000, 0xC5C2, 0x4000, 0x1A87, 0x0000},
254 .band5 = {0x2000, 0xF6B0, 0x4000, 0x3F51, 0x0000},
255 },
256 {
257 .name = "LOWPASS1K",
258 .rate = 44100,
259 .band1 = {0x205D, 0xC001, 0x3FEF, 0x002E, 0x02E0},
260 .band2 = {0x5B9A, 0xC093, 0x3AB2, 0x088B, 0x1981},
261 .band3 = {0x0D22, 0xC170, 0x26EA, 0x0D79, 0x32CF},
262 .band4 = {0x0894, 0xC612, 0x01B3, 0x1B34, 0x3FFA},
263 .band5 = {0x0815, 0x3FFF, 0xCF78, 0x0000, 0x29B7},
264 },
265 { /* BASS=-12dB, TREBLE=+9dB, Fc=5KHz */
266 .name = "HIBOOST",
267 .rate = 44100,
268 .band1 = {0x0815, 0xC001, 0x3AA4, 0x0003, 0x19A2},
269 .band2 = {0x0815, 0xC103, 0x092F, 0x0B55, 0x3F56},
270 .band3 = {0x0E0A, 0xC306, 0x1E5C, 0x136E, 0x3856},
271 .band4 = {0x2459, 0xF665, 0x0CAA, 0x3F46, 0x3EBB},
272 .band5 = {0x5BBB, 0x3FFF, 0xCEB0, 0x0000, 0x28CA},
273 },
274 { /* BASS=12dB, TREBLE=+12dB */
275 .name = "LOUD12DB",
276 .rate = 44100,
277 .band1 = {0x7FC1, 0xC001, 0x3EE8, 0x0020, 0x0BC7},
278 .band2 = {0x51E9, 0xC016, 0x3C7C, 0x033F, 0x14E9},
279 .band3 = {0x1745, 0xC12C, 0x1680, 0x0C2F, 0x3BE9},
280 .band4 = {0x4536, 0xD7E2, 0x0ED4, 0x31DD, 0x3E42},
281 .band5 = {0x7FEF, 0x3FFF, 0x0BAB, 0x0000, 0x3EED},
282 },
283 {
284 .name = "FLAT",
285 .rate = 16000,
286 .band1 = {0x2000, 0xC004, 0x4000, 0x0141, 0x0000},
287 .band2 = {0x2000, 0xC033, 0x4000, 0x0505, 0x0000},
288 .band3 = {0x2000, 0xC268, 0x4000, 0x115F, 0x0000},
289 .band4 = {0x2000, 0xDA62, 0x4000, 0x33C6, 0x0000},
290 .band5 = {0x2000, 0x4000, 0x4000, 0x0000, 0x0000},
291 },
292 {
293 .name = "LOWPASS1K",
294 .rate = 16000,
295 .band1 = {0x2000, 0xC004, 0x4000, 0x0141, 0x0000},
296 .band2 = {0x5BE8, 0xC3E0, 0x3307, 0x15ED, 0x26A0},
297 .band3 = {0x0F71, 0xD15A, 0x08B3, 0x2BD0, 0x3F67},
298 .band4 = {0x0815, 0x3FFF, 0xCF78, 0x0000, 0x29B7},
299 .band5 = {0x0815, 0x3FFF, 0xCF78, 0x0000, 0x29B7},
300 },
301 { /* BASS=-12dB, TREBLE=+9dB, Fc=2KHz */
302 .name = "HIBOOST",
303 .rate = 16000,
304 .band1 = {0x0815, 0xC001, 0x3BD2, 0x0009, 0x16BF},
305 .band2 = {0x080E, 0xC17E, 0xF653, 0x0DBD, 0x3F43},
306 .band3 = {0x0F80, 0xDF45, 0xEE33, 0x36FE, 0x3D79},
307 .band4 = {0x590B, 0x3FF0, 0xE882, 0x02BD, 0x3B87},
308 .band5 = {0x4C87, 0xF3D0, 0x063F, 0x3ED4, 0x3FB1},
309 },
310 { /* BASS=12dB, TREBLE=+12dB */
311 .name = "LOUD12DB",
312 .rate = 16000,
313 .band1 = {0x7FC1, 0xC001, 0x3D07, 0x0058, 0x1344},
314 .band2 = {0x2DA6, 0xC013, 0x3CF1, 0x02FF, 0x138B},
315 .band3 = {0x18F1, 0xC08E, 0x244D, 0x0863, 0x34B5},
316 .band4 = {0x2BE0, 0xF385, 0x04FD, 0x3EC5, 0x3FCE},
317 .band5 = {0x7FEF, 0x4000, 0x0BAB, 0x0000, 0x3EED},
318 },
319};
320
321
322static struct max98088_pdata enterprise_max98088_pdata = {
323 /* equalizer configuration */
324 .eq_cfg = max98088_eq_cfg,
325 .eq_cfgcnt = ARRAY_SIZE(max98088_eq_cfg),
326
327 /* debounce time */
328 .debounce_time_ms = 200,
329
330 /* microphone configuration */
331 .digmic_left_mode = 1,
332 .digmic_right_mode = 1,
333
334 /* receiver output configuration */
335 .receiver_mode = 0, /* 0 = amplifier, 1 = line output */
336};
337
338static struct pn544_i2c_platform_data nfc_pdata = {
339 .irq_gpio = TEGRA_GPIO_PS4,
340 .ven_gpio = TEGRA_GPIO_PM6,
341 .firm_gpio = 0,
342};
343
344
345static struct i2c_board_info __initdata max98088_board_info = {
346 I2C_BOARD_INFO("max98088", 0x10),
347 .platform_data = &enterprise_max98088_pdata,
348 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_HP_DET),
349};
350
351static struct i2c_board_info __initdata enterprise_codec_aic326x_info = {
352 I2C_BOARD_INFO("aic3262-codec", 0x18),
353 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_HP_DET),
354};
355
356static struct i2c_board_info __initdata nfc_board_info = {
357 I2C_BOARD_INFO("pn544", 0x28),
358 .platform_data = &nfc_pdata,
359 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS4),
360};
361
362static void enterprise_i2c_init(void)
363{
364 tegra_i2c_device1.dev.platform_data = &enterprise_i2c1_platform_data;
365 tegra_i2c_device2.dev.platform_data = &enterprise_i2c2_platform_data;
366 tegra_i2c_device3.dev.platform_data = &enterprise_i2c3_platform_data;
367 tegra_i2c_device4.dev.platform_data = &enterprise_i2c4_platform_data;
368 tegra_i2c_device5.dev.platform_data = &enterprise_i2c5_platform_data;
369
370 platform_device_register(&tegra_i2c_device5);
371 platform_device_register(&tegra_i2c_device4);
372 platform_device_register(&tegra_i2c_device3);
373 platform_device_register(&tegra_i2c_device2);
374 platform_device_register(&tegra_i2c_device1);
375
376 i2c_register_board_info(0, &max98088_board_info, 1);
377 i2c_register_board_info(0, &enterprise_codec_aic326x_info, 1);
378 i2c_register_board_info(0, &nfc_board_info, 1);
379}
380
381static struct platform_device *enterprise_uart_devices[] __initdata = {
382 &tegra_uarta_device,
383 &tegra_uartb_device,
384 &tegra_uartc_device,
385 &tegra_uartd_device,
386 &tegra_uarte_device,
387};
388
389static struct uart_clk_parent uart_parent_clk[] = {
390 [0] = {.name = "clk_m"},
391 [1] = {.name = "pll_p"},
392#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
393 [2] = {.name = "pll_m"},
394#endif
395};
396static struct tegra_uart_platform_data enterprise_uart_pdata;
397static struct tegra_uart_platform_data enterprise_loopback_uart_pdata;
398
399static void __init uart_debug_init(void)
400{
401 unsigned long rate;
402 struct clk *c;
403
404 /* UARTD is the debug port. */
405 pr_info("Selecting UARTD as the debug console\n");
406 enterprise_uart_devices[3] = &debug_uartd_device;
407 debug_uart_port_base = ((struct plat_serial8250_port *)(
408 debug_uartd_device.dev.platform_data))->mapbase;
409 debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
410
411 /* Clock enable for the debug channel */
412 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
413 rate = ((struct plat_serial8250_port *)(
414 debug_uartd_device.dev.platform_data))->uartclk;
415 pr_info("The debug console clock name is %s\n",
416 debug_uart_clk->name);
417 c = tegra_get_clock_by_name("pll_p");
418 if (IS_ERR_OR_NULL(c))
419 pr_err("Not getting the parent clock pll_p\n");
420 else
421 clk_set_parent(debug_uart_clk, c);
422
423 clk_enable(debug_uart_clk);
424 clk_set_rate(debug_uart_clk, rate);
425 } else {
426 pr_err("Not getting the clock %s for debug console\n",
427 debug_uart_clk->name);
428 }
429}
430
431static void __init enterprise_uart_init(void)
432{
433 int i;
434 struct clk *c;
435
436 for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
437 c = tegra_get_clock_by_name(uart_parent_clk[i].name);
438 if (IS_ERR_OR_NULL(c)) {
439 pr_err("Not able to get the clock for %s\n",
440 uart_parent_clk[i].name);
441 continue;
442 }
443 uart_parent_clk[i].parent_clk = c;
444 uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
445 }
446 enterprise_uart_pdata.parent_clk_list = uart_parent_clk;
447 enterprise_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
448 enterprise_loopback_uart_pdata.parent_clk_list = uart_parent_clk;
449 enterprise_loopback_uart_pdata.parent_clk_count =
450 ARRAY_SIZE(uart_parent_clk);
451 enterprise_loopback_uart_pdata.is_loopback = true;
452 tegra_uarta_device.dev.platform_data = &enterprise_uart_pdata;
453 tegra_uartb_device.dev.platform_data = &enterprise_uart_pdata;
454 tegra_uartc_device.dev.platform_data = &enterprise_uart_pdata;
455 tegra_uartd_device.dev.platform_data = &enterprise_uart_pdata;
456 /* UARTE is used for loopback test purpose */
457 tegra_uarte_device.dev.platform_data = &enterprise_loopback_uart_pdata;
458
459 /* Register low speed only if it is selected */
460 if (!is_tegra_debug_uartport_hs())
461 uart_debug_init();
462
463 platform_add_devices(enterprise_uart_devices,
464 ARRAY_SIZE(enterprise_uart_devices));
465}
466
467
468
469static struct resource tegra_rtc_resources[] = {
470 [0] = {
471 .start = TEGRA_RTC_BASE,
472 .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1,
473 .flags = IORESOURCE_MEM,
474 },
475 [1] = {
476 .start = INT_RTC,
477 .end = INT_RTC,
478 .flags = IORESOURCE_IRQ,
479 },
480};
481
482static struct platform_device tegra_rtc_device = {
483 .name = "tegra_rtc",
484 .id = -1,
485 .resource = tegra_rtc_resources,
486 .num_resources = ARRAY_SIZE(tegra_rtc_resources),
487};
488
489static struct platform_device tegra_camera = {
490 .name = "tegra_camera",
491 .id = -1,
492};
493
494static struct tegra_asoc_platform_data enterprise_audio_pdata = {
495 .gpio_spkr_en = -1,
496 .gpio_hp_det = TEGRA_GPIO_HP_DET,
497 .gpio_hp_mute = -1,
498 .gpio_int_mic_en = -1,
499 .gpio_ext_mic_en = -1,
500 .debounce_time_hp = -1,
501 /*defaults for Enterprise board*/
502 .audio_port_id = {
503 [HIFI_CODEC] = 0,
504 [BASEBAND] = 2,
505 [BT_SCO] = 3,
506 },
507 .baseband_param = {
508 .rate = 8000,
509 .channels = 1,
510 },
511};
512
513static struct platform_device enterprise_audio_device = {
514 .name = "tegra-snd-max98088",
515 .id = 0,
516 .dev = {
517 .platform_data = &enterprise_audio_pdata,
518 },
519};
520
521static struct tegra_asoc_platform_data enterprise_audio_aic326x_pdata = {
522 .gpio_spkr_en = -1,
523 .gpio_hp_det = TEGRA_GPIO_HP_DET,
524 .gpio_hp_mute = -1,
525 .gpio_int_mic_en = -1,
526 .gpio_ext_mic_en = -1,
527 /*defaults for Verbier-Enterprise (E1197) board with TI AIC326X codec*/
528 .audio_port_id = {
529 [HIFI_CODEC] = 0,
530 [BASEBAND] = 2,
531 [BT_SCO] = 3,
532 },
533 .baseband_param = {
534 .rate = 8000,
535 .channels = 1,
536 },
537};
538
539static struct platform_device enterprise_audio_aic326x_device = {
540 .name = "tegra-snd-aic326x",
541 .id = 0,
542 .dev = {
543 .platform_data = &enterprise_audio_aic326x_pdata,
544 },
545};
546
547static struct platform_device *enterprise_devices[] __initdata = {
548 &tegra_pmu_device,
549 &tegra_rtc_device,
550 &tegra_udc_device,
551#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
552 &tegra_smmu_device,
553#endif
554 &tegra_wdt_device,
555#if defined(CONFIG_TEGRA_AVP)
556 &tegra_avp_device,
557#endif
558 &tegra_camera,
559 &enterprise_bcm4329_rfkill_device,
560 &tegra_spi_device4,
561 &tegra_hda_device,
562#if defined(CONFIG_CRYPTO_DEV_TEGRA_SE)
563 &tegra_se_device,
564#endif
565#if defined(CONFIG_CRYPTO_DEV_TEGRA_AES)
566 &tegra_aes_device,
567#endif
568};
569
570#define MXT_CONFIG_CRC 0x62F903
571/*
572 * Config converted from memory-mapped cfg-file with
573 * following version information:
574 *
575 *
576 *
577 * FAMILY_ID=128
578 * VARIANT=1
579 * VERSION=32
580 * BUILD=170
581 * VENDOR_ID=255
582 * PRODUCT_ID=TBD
583 * CHECKSUM=0xC189B6
584 *
585 *
586 */
587
588static const u8 config[] = {
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0xFF, 0xFF, 0x32, 0x0A, 0x00, 0x05, 0x01, 0x00,
591 0x00, 0x1E, 0x0A, 0x8B, 0x00, 0x00, 0x13, 0x0B,
592 0x00, 0x10, 0x32, 0x03, 0x03, 0x00, 0x03, 0x01,
593 0x00, 0x0A, 0x0A, 0x0A, 0x0A, 0xBF, 0x03, 0x1B,
594 0x02, 0x00, 0x00, 0x37, 0x37, 0x00, 0x00, 0x00,
595 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0xA9, 0x7F, 0x9A, 0x0E, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x0A,
602 0x0F, 0x14, 0x19, 0x03, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x08, 0x10,
610 0x00
611};
612
613static struct mxt_platform_data atmel_mxt_info = {
614 .x_line = 19,
615 .y_line = 11,
616 .x_size = 960,
617 .y_size = 540,
618 .blen = 0x10,
619 .threshold = 0x32,
620 .voltage = 3300000, /* 3.3V */
621 .orient = 3,
622 .config = config,
623 .config_length = 168,
624 .config_crc = MXT_CONFIG_CRC,
625 .irqflags = IRQF_TRIGGER_FALLING,
626/* .read_chg = &read_chg, */
627 .read_chg = NULL,
628};
629
630static struct i2c_board_info __initdata atmel_i2c_info[] = {
631 {
632 I2C_BOARD_INFO("atmel_mxt_ts", MXT224_I2C_ADDR1),
633 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PH6),
634 .platform_data = &atmel_mxt_info,
635 }
636};
637
638static int __init enterprise_touch_init(void)
639{
640 tegra_gpio_enable(TEGRA_GPIO_PH6);
641 tegra_gpio_enable(TEGRA_GPIO_PF5);
642
643 gpio_request(TEGRA_GPIO_PH6, "atmel-irq");
644 gpio_direction_input(TEGRA_GPIO_PH6);
645
646 gpio_request(TEGRA_GPIO_PF5, "atmel-reset");
647 gpio_direction_output(TEGRA_GPIO_PF5, 0);
648 msleep(1);
649 gpio_set_value(TEGRA_GPIO_PF5, 1);
650 msleep(100);
651
652 i2c_register_board_info(1, atmel_i2c_info, 1);
653
654 return 0;
655}
656
657static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
658 [0] = {
659 .instance = 0,
660 .vbus_gpio = -1,
661 .vbus_reg_supply = "usb_vbus",
662 .vbus_irq = ENT_TPS80031_IRQ_BASE +
663 TPS80031_INT_VBUS_DET,
664 },
665 [1] = {
666 .instance = 1,
667 .vbus_gpio = -1,
668 },
669 [2] = {
670 .instance = 2,
671 .vbus_gpio = -1,
672 },
673};
674
675static struct tegra_uhsic_config uhsic_phy_config = {
676 .enable_gpio = -1,
677 .reset_gpio = -1,
678 .sync_start_delay = 9,
679 .idle_wait_delay = 17,
680 .term_range_adj = 0,
681 .elastic_underrun_limit = 16,
682 .elastic_overrun_limit = 16,
683};
684
685static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = {
686 .phy_type = TEGRA_USB_PHY_TYPE_HSIC,
687 .phy_config = &uhsic_phy_config,
688 .operating_mode = TEGRA_USB_HOST,
689 .power_down_on_bus_suspend = 1,
690 .default_enable = true,
691};
692
693static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
694 [0] = {
695 .phy_config = &utmi_phy_config[0],
696 .operating_mode = TEGRA_USB_HOST,
697 .power_down_on_bus_suspend = 1,
698 .default_enable = false,
699 },
700 [1] = {
701 .phy_config = &utmi_phy_config[1],
702 .operating_mode = TEGRA_USB_HOST,
703 .power_down_on_bus_suspend = 1,
704 .default_enable = false,
705 },
706 [2] = {
707 .phy_config = &utmi_phy_config[2],
708 .operating_mode = TEGRA_USB_HOST,
709 .power_down_on_bus_suspend = 1,
710 .default_enable = false,
711 },
712};
713
714static struct tegra_otg_platform_data tegra_otg_pdata = {
715 .ehci_device = &tegra_ehci1_device,
716 .ehci_pdata = &tegra_ehci_pdata[0],
717};
718
719struct platform_device *tegra_usb_hsic_host_register(void)
720{
721 struct platform_device *pdev;
722 int val;
723
724 pdev = platform_device_alloc(tegra_ehci2_device.name,
725 tegra_ehci2_device.id);
726 if (!pdev)
727 return NULL;
728
729 val = platform_device_add_resources(pdev, tegra_ehci2_device.resource,
730 tegra_ehci2_device.num_resources);
731 if (val)
732 goto error;
733
734 pdev->dev.dma_mask = tegra_ehci2_device.dev.dma_mask;
735 pdev->dev.coherent_dma_mask = tegra_ehci2_device.dev.coherent_dma_mask;
736
737 val = platform_device_add_data(pdev, &tegra_ehci_uhsic_pdata,
738 sizeof(struct tegra_ehci_platform_data));
739 if (val)
740 goto error;
741
742 val = platform_device_add(pdev);
743 if (val)
744 goto error;
745
746 return pdev;
747
748error:
749 pr_err("%s: failed to add the host contoller device\n", __func__);
750 platform_device_put(pdev);
751 return NULL;
752}
753
754void tegra_usb_hsic_host_unregister(struct platform_device *pdev)
755{
756 platform_device_unregister(pdev);
757}
758
759static int enterprise_usb_hsic_postsupend(void)
760{
761 pr_debug("%s\n", __func__);
762#ifdef CONFIG_TEGRA_BB_XMM_POWER
763 baseband_xmm_set_power_status(BBXMM_PS_L2);
764#endif
765 return 0;
766}
767
768static int enterprise_usb_hsic_preresume(void)
769{
770 pr_debug("%s\n", __func__);
771#ifdef CONFIG_TEGRA_BB_XMM_POWER
772 baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
773#endif
774 return 0;
775}
776
777static int enterprise_usb_hsic_phy_ready(void)
778{
779 pr_debug("%s\n", __func__);
780#ifdef CONFIG_TEGRA_BB_XMM_POWER
781 baseband_xmm_set_power_status(BBXMM_PS_L0);
782#endif
783 return 0;
784}
785
786static int enterprise_usb_hsic_phy_off(void)
787{
788 pr_debug("%s\n", __func__);
789#ifdef CONFIG_TEGRA_BB_XMM_POWER
790 baseband_xmm_set_power_status(BBXMM_PS_L3);
791#endif
792 return 0;
793}
794
795static void enterprise_usb_init(void)
796{
797 struct fsl_usb2_platform_data *udc_pdata;
798
799 tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata));
800
801 tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
802 platform_device_register(&tegra_otg_device);
803
804 udc_pdata = tegra_udc_device.dev.platform_data;
805}
806
807static struct platform_device *enterprise_audio_devices[] __initdata = {
808 &tegra_ahub_device,
809 &tegra_dam_device0,
810 &tegra_dam_device1,
811 &tegra_dam_device2,
812 &tegra_i2s_device0,
813 &tegra_i2s_device1,
814 &tegra_i2s_device2,
815 &tegra_i2s_device3,
816 &tegra_spdif_device,
817 &spdif_dit_device,
818 &bluetooth_dit_device,
819 &baseband_dit_device,
820 &tegra_pcm_device,
821 &enterprise_audio_device,
822 &enterprise_audio_aic326x_device,
823};
824
825static void enterprise_audio_init(void)
826{
827 struct board_info board_info;
828
829 tegra_get_board_info(&board_info);
830
831 if (board_info.board_id == BOARD_E1197)
832 enterprise_audio_pdata.audio_port_id[HIFI_CODEC] = 1;
833
834 platform_add_devices(enterprise_audio_devices,
835 ARRAY_SIZE(enterprise_audio_devices));
836}
837
838static void enterprise_gps_init(void)
839{
840 tegra_gpio_enable(TEGRA_GPIO_PE4);
841 tegra_gpio_enable(TEGRA_GPIO_PE5);
842}
843
844static struct baseband_power_platform_data tegra_baseband_power_data = {
845 .baseband_type = BASEBAND_XMM,
846 .modem = {
847 .xmm = {
848 .bb_rst = XMM_GPIO_BB_RST,
849 .bb_on = XMM_GPIO_BB_ON,
850 .ipc_bb_wake = XMM_GPIO_IPC_BB_WAKE,
851 .ipc_ap_wake = XMM_GPIO_IPC_AP_WAKE,
852 .ipc_hsic_active = XMM_GPIO_IPC_HSIC_ACTIVE,
853 .ipc_hsic_sus_req = XMM_GPIO_IPC_HSIC_SUS_REQ,
854 },
855 },
856};
857
858static struct platform_device tegra_baseband_power_device = {
859 .name = "baseband_xmm_power",
860 .id = -1,
861 .dev = {
862 .platform_data = &tegra_baseband_power_data,
863 },
864};
865
866static struct platform_device tegra_baseband_power2_device = {
867 .name = "baseband_xmm_power2",
868 .id = -1,
869 .dev = {
870 .platform_data = &tegra_baseband_power_data,
871 },
872};
873
874#ifdef CONFIG_TEGRA_BB_M7400
875static union tegra_bb_gpio_id m7400_gpio_id = {
876 .m7400 = {
877 .pwr_status = GPIO_BB_RESET,
878 .pwr_on = GPIO_BB_PWRON,
879 .uart_awr = GPIO_BB_APACK,
880 .uart_cwr = GPIO_BB_CPACK,
881 .usb_awr = GPIO_BB_APACK2,
882 .usb_cwr = GPIO_BB_CPACK2,
883 .service = GPIO_BB_RSVD2,
884 .resout2 = GPIO_BB_RSVD1,
885 },
886};
887
888static struct tegra_bb_pdata m7400_pdata = {
889 .id = &m7400_gpio_id,
890 .device = &tegra_ehci2_device,
891 .ehci_register = tegra_usb_hsic_host_register,
892 .ehci_unregister = tegra_usb_hsic_host_unregister,
893 .bb_id = TEGRA_BB_M7400,
894};
895
896static struct platform_device tegra_baseband_m7400_device = {
897 .name = "tegra_baseband_power",
898 .id = -1,
899 .dev = {
900 .platform_data = &m7400_pdata,
901 },
902};
903#endif
904
905static void enterprise_baseband_init(void)
906{
907 int modem_id = tegra_get_modem_id();
908
909 switch (modem_id) {
910 case TEGRA_BB_PH450: /* PH450 ULPI */
911 enterprise_modem_init();
912 break;
913 case TEGRA_BB_XMM6260: /* XMM6260 HSIC */
914 /* xmm baseband - do not switch off phy during suspend */
915 tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0;
916 uhsic_phy_config.postsuspend = enterprise_usb_hsic_postsupend;
917 uhsic_phy_config.preresume = enterprise_usb_hsic_preresume;
918 uhsic_phy_config.usb_phy_ready = enterprise_usb_hsic_phy_ready;
919 uhsic_phy_config.post_phy_off = enterprise_usb_hsic_phy_off;
920 /* enable XMM6260 baseband gpio(s) */
921 tegra_gpio_enable(tegra_baseband_power_data.modem.generic
922 .mdm_reset);
923 tegra_gpio_enable(tegra_baseband_power_data.modem.generic
924 .mdm_on);
925 tegra_gpio_enable(tegra_baseband_power_data.modem.generic
926 .ap2mdm_ack);
927 tegra_gpio_enable(tegra_baseband_power_data.modem.generic
928 .mdm2ap_ack);
929 tegra_gpio_enable(tegra_baseband_power_data.modem.generic
930 .ap2mdm_ack2);
931 tegra_gpio_enable(tegra_baseband_power_data.modem.generic
932 .mdm2ap_ack2);
933 tegra_baseband_power_data.hsic_register =
934 &tegra_usb_hsic_host_register;
935 tegra_baseband_power_data.hsic_unregister =
936 &tegra_usb_hsic_host_unregister;
937 platform_device_register(&tegra_baseband_power_device);
938 platform_device_register(&tegra_baseband_power2_device);
939 break;
940#ifdef CONFIG_TEGRA_BB_M7400
941 case TEGRA_BB_M7400: /* M7400 HSIC */
942 tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0;
943 tegra_ehci2_device.dev.platform_data
944 = &tegra_ehci_uhsic_pdata;
945 platform_device_register(&tegra_baseband_m7400_device);
946 break;
947#endif
948 }
949}
950
951static void enterprise_nfc_init(void)
952{
953 tegra_gpio_enable(TEGRA_GPIO_PS4);
954 tegra_gpio_enable(TEGRA_GPIO_PM6);
955}
956
957static void __init tegra_enterprise_init(void)
958{
959 tegra_thermal_init(&thermal_data);
960 tegra_clk_init_from_table(enterprise_clk_init_table);
961 enterprise_pinmux_init();
962 enterprise_i2c_init();
963 enterprise_uart_init();
964 enterprise_usb_init();
965 platform_add_devices(enterprise_devices, ARRAY_SIZE(enterprise_devices));
966 tegra_ram_console_debug_init();
967 enterprise_regulator_init();
968 enterprise_sdhci_init();
969#ifdef CONFIG_TEGRA_EDP_LIMITS
970 enterprise_edp_init();
971#endif
972 enterprise_kbc_init();
973 enterprise_touch_init();
974 enterprise_audio_init();
975 enterprise_gps_init();
976 enterprise_baseband_init();
977 enterprise_panel_init();
978 enterprise_setup_bluesleep();
979 enterprise_emc_init();
980 enterprise_sensors_init();
981 enterprise_suspend_init();
982 enterprise_bpc_mgmt_init();
983 tegra_release_bootloader_fb();
984 enterprise_nfc_init();
985}
986
987static void __init tegra_enterprise_reserve(void)
988{
989#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM)
990 tegra_reserve(0, SZ_4M, SZ_8M);
991#else
992 tegra_reserve(SZ_128M, SZ_4M, SZ_8M);
993#endif
994 tegra_ram_console_debug_reserve(SZ_1M);
995}
996
997MACHINE_START(TEGRA_ENTERPRISE, "tegra_enterprise")
998 .boot_params = 0x80000100,
999 .map_io = tegra_map_common_io,
1000 .reserve = tegra_enterprise_reserve,
1001 .init_early = tegra_init_early,
1002 .init_irq = tegra_init_irq,
1003 .timer = &tegra_timer,
1004 .init_machine = tegra_enterprise_init,
1005MACHINE_END
diff --git a/arch/arm/mach-tegra/board-enterprise.h b/arch/arm/mach-tegra/board-enterprise.h
new file mode 100644
index 00000000000..f47672091bf
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise.h
@@ -0,0 +1,161 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise.h
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef _MACH_TEGRA_BOARD_ENTERPRISE_H
22#define _MACH_TEGRA_BOARD_ENTERPRISE_H
23
24#include <mach/gpio.h>
25#include <mach/irqs.h>
26#include <linux/mfd/tps80031.h>
27
28/* Processor Board ID */
29#define BOARD_E1205 0x0C05
30#define BOARD_E1197 0x0B61
31#define SKU_BATTERY_SUPPORT 0x1
32
33/* Board Fab version */
34#define BOARD_FAB_A00 0x0
35#define BOARD_FAB_A01 0x1
36#define BOARD_FAB_A02 0x2
37#define BOARD_FAB_A03 0x3
38#define BOARD_FAB_A04 0x4
39
40/* vdd_cpu voltage follower */
41#define BOARD_SKU_VF_BIT 0x0400
42
43int enterprise_charge_init(void);
44int enterprise_sdhci_init(void);
45int enterprise_pinmux_init(void);
46int enterprise_panel_init(void);
47int enterprise_sensors_init(void);
48int touch_init(void);
49int enterprise_kbc_init(void);
50int enterprise_emc_init(void);
51int enterprise_regulator_init(void);
52int enterprise_modem_init(void);
53int enterprise_suspend_init(void);
54int enterprise_edp_init(void);
55void enterprise_bpc_mgmt_init(void);
56
57/* Invensense MPU Definitions */
58#define MPU_TYPE_MPU3050 1
59#define MPU_TYPE_MPU6050 2
60#define MPU_GYRO_TYPE MPU_TYPE_MPU3050
61#define MPU_GYRO_IRQ_GPIO TEGRA_GPIO_PH4
62#define MPU_GYRO_ADDR 0x68
63#define MPU_GYRO_BUS_NUM 0
64#define MPU_GYRO_ORIENTATION { -1, 0, 0, 0, -1, 0, 0, 0, 1 }
65#define MPU_ACCEL_NAME "kxtf9"
66#define MPU_ACCEL_IRQ_GPIO 0 /* DISABLE ACCELIRQ: TEGRA_GPIO_PJ2 */
67#define MPU_ACCEL_ADDR 0x0F
68#define MPU_ACCEL_BUS_NUM 0
69#define MPU_ACCEL_ORIENTATION { 0, 1, 0, -1, 0, 0, 0, 0, 1 }
70#define MPU_COMPASS_NAME "ak8975"
71#define MPU_COMPASS_IRQ_GPIO 0
72#define MPU_COMPASS_ADDR 0x0C
73#define MPU_COMPASS_BUS_NUM 0
74#define MPU_COMPASS_ORIENTATION { 0, 1, 0, -1, 0, 0, 0, 0, 1 }
75
76/* PCA954x I2C bus expander bus addresses */
77#define PCA954x_I2C_BUS_BASE 6
78#define PCA954x_I2C_BUS0 (PCA954x_I2C_BUS_BASE + 0)
79#define PCA954x_I2C_BUS1 (PCA954x_I2C_BUS_BASE + 1)
80#define PCA954x_I2C_BUS2 (PCA954x_I2C_BUS_BASE + 2)
81#define PCA954x_I2C_BUS3 (PCA954x_I2C_BUS_BASE + 3)
82
83/*****************External GPIO tables ******************/
84/* External peripheral gpio base. */
85#define ENT_TPS80031_GPIO_BASE TEGRA_NR_GPIOS
86#define ENT_TPS80031_GPIO_REGEN1 (ENT_TPS80031_GPIO_BASE + TPS80031_GPIO_REGEN1)
87#define ENT_TPS80031_GPIO_REGEN2 (ENT_TPS80031_GPIO_BASE + TPS80031_GPIO_REGEN2)
88#define ENT_TPS80031_GPIO_SYSEN (ENT_TPS80031_GPIO_BASE + TPS80031_GPIO_SYSEN)
89#define ENT_TPS80031_GPIO_END (ENT_TPS80031_GPIO_BASE + TPS80031_GPIO_NR)
90
91/*****************External Interrupt tables ******************/
92/* External peripheral irq base */
93#define ENT_TPS80031_IRQ_BASE TEGRA_NR_IRQS
94#define ENT_TPS80031_IRQ_END (ENT_TPS80031_IRQ_BASE + TPS80031_INT_NR)
95
96/*****************Camera GPIOs ******************/
97#define CAM_CSI_MUX_SEL_GPIO TEGRA_GPIO_PM3
98#define CAM_CSI_MUX_SEL_REAR 1
99#define CAM_CSI_MUX_SEL_FRONT 0
100
101#define CAM1_RST_L_GPIO TEGRA_GPIO_PM5 /*REAR RIGHT*/
102#define CAM2_RST_L_GPIO TEGRA_GPIO_PF4 /*REAR LEFT*/
103#define CAM3_RST_L_GPIO TEGRA_GPIO_PM2 /*FRONT*/
104#define CAM3_RST_L_TRUE 0
105#define CAM3_RST_L_FALSE 1
106#define CAM3_PWDN_GPIO TEGRA_GPIO_PN4 /*FRONT*/
107#define CAM3_PWDN_TRUE 1
108#define CAM3_PWDN_FALSE 0
109#define CAM_FLASH_EN_GPIO TEGRA_GPIO_PBB3
110#define CAM_FLASH_MAX_TORCH_AMP 7
111#define CAM_FLASH_MAX_FLASH_AMP 7
112#define CAM_I2C_MUX_RST_EXP TEGRA_GPIO_PF3 /*I2C Mux Reset*/
113
114/* Audio-related GPIOs */
115#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW3
116
117/* Baseband GPIO addresses */
118
119#define GPIO_BB_RESET TEGRA_GPIO_PE1
120#define GPIO_BB_PWRON TEGRA_GPIO_PE0
121#define GPIO_BB_APACK TEGRA_GPIO_PE3
122#define GPIO_BB_APACK2 TEGRA_GPIO_PE2
123#define GPIO_BB_CPACK TEGRA_GPIO_PU5
124#define GPIO_BB_CPACK2 TEGRA_GPIO_PV0
125#define GPIO_BB_RSVD1 TEGRA_GPIO_PV1
126#define GPIO_BB_RSVD2 TEGRA_GPIO_PU4
127
128#define BB_GPIO_MDM_PWRON_AP2BB TEGRA_GPIO_PE0 /* LCD_D0 */
129#define BB_GPIO_RESET_AP2BB TEGRA_GPIO_PE1 /* LCD_D1 */
130#define BB_GPIO_LCD_PWR1 TEGRA_GPIO_PC1
131#define BB_GPIO_LCD_PWR2 TEGRA_GPIO_PC6
132#define BB_GPIO_HS1_AP2BB TEGRA_GPIO_PE3 /* LCD_D3 */
133#define BB_GPIO_HS1_BB2AP TEGRA_GPIO_PU5
134
135#define XMM_GPIO_BB_ON BB_GPIO_MDM_PWRON_AP2BB
136#define XMM_GPIO_BB_RST BB_GPIO_RESET_AP2BB
137#define XMM_GPIO_IPC_HSIC_ACTIVE BB_GPIO_LCD_PWR1
138#define XMM_GPIO_IPC_HSIC_SUS_REQ BB_GPIO_LCD_PWR2
139#define XMM_GPIO_IPC_BB_WAKE BB_GPIO_HS1_AP2BB
140#define XMM_GPIO_IPC_AP_WAKE BB_GPIO_HS1_BB2AP
141
142#define TDIODE_OFFSET (9000) /* in millicelsius */
143
144/* Battery Peak Current Management */
145#define TEGRA_BPC_TRIGGER TEGRA_GPIO_PR3
146#define TEGRA_BPC_TIMEOUT 100 /* ms */
147#define TEGRA_BPC_CPU_PWR_LIMIT 0 /* in mW, (0 disables) */
148
149#define TEGRA_CUR_MON_THRESHOLD -2000
150#define TEGRA_CUR_MON_RESISTOR 20
151#define TEGRA_CUR_MON_MIN_CORES 2
152
153/* Baseband IDs */
154
155enum tegra_bb_type {
156 TEGRA_BB_PH450 = 1,
157 TEGRA_BB_XMM6260,
158 TEGRA_BB_M7400,
159};
160
161#endif /*_MACH_TEGRA_BOARD_ENTERPRISE_H */
diff --git a/arch/arm/mach-tegra/board-harmony-kbc.c b/arch/arm/mach-tegra/board-harmony-kbc.c
new file mode 100644
index 00000000000..156da22bfec
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-kbc.c
@@ -0,0 +1,375 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-kbc.c
3 * Keys configuration for Nvidia tegra2 harmony platform.
4 *
5 * Copyright (C) 2011 NVIDIA, Inc.
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
19 * 02111-1307, USA
20 */
21
22#include <linux/kernel.h>
23#include <linux/platform_device.h>
24#include <linux/input.h>
25#include <mach/io.h>
26#include <mach/iomap.h>
27#include <mach/kbc.h>
28
29#include "board.h"
30#include "board-harmony.h"
31#include "devices.h"
32
33#define HARMONY_ROW_COUNT 16
34#define HARMONY_COL_COUNT 8
35
36static const u32 kbd_keymap[] = {
37 KEY(0, 0, KEY_RESERVED),
38 KEY(0, 1, KEY_RESERVED),
39 KEY(0, 2, KEY_W),
40 KEY(0, 3, KEY_S),
41 KEY(0, 4, KEY_A),
42 KEY(0, 5, KEY_Z),
43 KEY(0, 6, KEY_RESERVED),
44 KEY(0, 7, KEY_FN),
45
46 KEY(1, 0, KEY_RESERVED),
47 KEY(1, 1, KEY_RESERVED),
48 KEY(1, 2, KEY_RESERVED),
49 KEY(1, 3, KEY_RESERVED),
50 KEY(1, 4, KEY_RESERVED),
51 KEY(1, 5, KEY_RESERVED),
52 KEY(1, 6, KEY_RESERVED),
53 KEY(1, 7, KEY_MENU),
54
55 KEY(2, 0, KEY_RESERVED),
56 KEY(2, 1, KEY_RESERVED),
57 KEY(2, 2, KEY_RESERVED),
58 KEY(2, 3, KEY_RESERVED),
59 KEY(2, 4, KEY_RESERVED),
60 KEY(2, 5, KEY_RESERVED),
61 KEY(2, 6, KEY_LEFTALT),
62 KEY(2, 7, KEY_RIGHTALT),
63
64 KEY(3, 0, KEY_5),
65 KEY(3, 1, KEY_4),
66 KEY(3, 2, KEY_R),
67 KEY(3, 3, KEY_E),
68 KEY(3, 4, KEY_F),
69 KEY(3, 5, KEY_D),
70 KEY(3, 6, KEY_X),
71 KEY(3, 7, KEY_RESERVED),
72
73 KEY(4, 0, KEY_7),
74 KEY(4, 1, KEY_6),
75 KEY(4, 2, KEY_T),
76 KEY(4, 3, KEY_H),
77 KEY(4, 4, KEY_G),
78 KEY(4, 5, KEY_V),
79 KEY(4, 6, KEY_C),
80 KEY(4, 7, KEY_SPACE),
81
82 KEY(5, 0, KEY_9),
83 KEY(5, 1, KEY_8),
84 KEY(5, 2, KEY_U),
85 KEY(5, 3, KEY_Y),
86 KEY(5, 4, KEY_J),
87 KEY(5, 5, KEY_N),
88 KEY(5, 6, KEY_B),
89 KEY(5, 7, KEY_BACKSLASH),
90
91 KEY(6, 0, KEY_MINUS),
92 KEY(6, 1, KEY_0),
93 KEY(6, 2, KEY_O),
94 KEY(6, 3, KEY_I),
95 KEY(6, 4, KEY_L),
96 KEY(6, 5, KEY_K),
97 KEY(6, 6, KEY_COMMA),
98 KEY(6, 7, KEY_M),
99
100 KEY(7, 0, KEY_RESERVED),
101 KEY(7, 1, KEY_EQUAL),
102 KEY(7, 2, KEY_RIGHTBRACE),
103 KEY(7, 3, KEY_ENTER),
104 KEY(7, 4, KEY_RESERVED),
105 KEY(7, 5, KEY_RESERVED),
106 KEY(7, 6, KEY_RESERVED),
107 KEY(7, 7, KEY_MENU),
108
109 KEY(8, 0, KEY_RESERVED),
110 KEY(8, 1, KEY_RESERVED),
111 KEY(8, 2, KEY_RESERVED),
112 KEY(8, 3, KEY_RESERVED),
113 KEY(8, 4, KEY_LEFTSHIFT),
114 KEY(8, 5, KEY_RIGHTSHIFT),
115 KEY(8, 6, KEY_RESERVED),
116 KEY(8, 7, KEY_RESERVED),
117
118 KEY(9, 0, KEY_RESERVED),
119 KEY(9, 1, KEY_RESERVED),
120 KEY(9, 2, KEY_RESERVED),
121 KEY(9, 3, KEY_RESERVED),
122 KEY(9, 4, KEY_RESERVED),
123 KEY(9, 5, KEY_LEFTCTRL),
124 KEY(9, 6, KEY_RESERVED),
125 KEY(9, 7, KEY_RIGHTCTRL),
126
127 KEY(10, 0, KEY_RESERVED),
128 KEY(10, 1, KEY_RESERVED),
129 KEY(10, 2, KEY_RESERVED),
130 KEY(10, 3, KEY_RESERVED),
131 KEY(10, 4, KEY_RESERVED),
132 KEY(10, 5, KEY_RESERVED),
133 KEY(10, 6, KEY_RESERVED),
134 KEY(10, 7, KEY_RESERVED),
135
136 KEY(11, 0, KEY_LEFTBRACE),
137 KEY(11, 1, KEY_P),
138 KEY(11, 2, KEY_APOSTROPHE),
139 KEY(11, 3, KEY_SEMICOLON),
140 KEY(11, 4, KEY_SLASH),
141 KEY(11, 5, KEY_DOT),
142 KEY(11, 6, KEY_RESERVED),
143 KEY(11, 7, KEY_RESERVED),
144
145 KEY(12, 0, KEY_F10),
146 KEY(12, 1, KEY_F9),
147 KEY(12, 2, KEY_BACKSPACE),
148 KEY(12, 3, KEY_3),
149 KEY(12, 4, KEY_2),
150 KEY(12, 5, KEY_UP),
151 KEY(12, 6, KEY_PRINT),
152 KEY(12, 7, KEY_PAUSE),
153
154 KEY(13, 0, KEY_INSERT),
155 KEY(13, 1, KEY_DELETE),
156 KEY(13, 2, KEY_RESERVED),
157 KEY(13, 3, KEY_PAGEUP),
158 KEY(13, 4, KEY_PAGEDOWN),
159 KEY(13, 5, KEY_RIGHT),
160 KEY(13, 6, KEY_DOWN),
161 KEY(13, 7, KEY_LEFT),
162
163 KEY(14, 0, KEY_F11),
164 KEY(14, 1, KEY_F12),
165 KEY(14, 2, KEY_F8),
166 KEY(14, 3, KEY_Q),
167 KEY(14, 4, KEY_F4),
168 KEY(14, 5, KEY_F3),
169 KEY(14, 6, KEY_1),
170 KEY(14, 7, KEY_F7),
171
172 KEY(15, 0, KEY_ESC),
173 KEY(15, 1, KEY_GRAVE),
174 KEY(15, 2, KEY_F5),
175 KEY(15, 3, KEY_TAB),
176 KEY(15, 4, KEY_F1),
177 KEY(15, 5, KEY_F2),
178 KEY(15, 6, KEY_CAPSLOCK),
179 KEY(15, 7, KEY_F6),
180
181 KEY(16, 0, KEY_RESERVED),
182 KEY(16, 1, KEY_RESERVED),
183 KEY(16, 2, KEY_RESERVED),
184 KEY(16, 3, KEY_RESERVED),
185 KEY(16, 4, KEY_RESERVED),
186 KEY(16, 5, KEY_RESERVED),
187 KEY(16, 6, KEY_RESERVED),
188 KEY(16, 7, KEY_RESERVED),
189
190 KEY(17, 0, KEY_RESERVED),
191 KEY(17, 1, KEY_RESERVED),
192 KEY(17, 2, KEY_RESERVED),
193 KEY(17, 3, KEY_RESERVED),
194 KEY(17, 4, KEY_RESERVED),
195 KEY(17, 5, KEY_RESERVED),
196 KEY(17, 6, KEY_RESERVED),
197 KEY(17, 7, KEY_RESERVED),
198
199 KEY(18, 0, KEY_RESERVED),
200 KEY(18, 1, KEY_RESERVED),
201 KEY(18, 2, KEY_RESERVED),
202 KEY(18, 3, KEY_RESERVED),
203 KEY(18, 4, KEY_RESERVED),
204 KEY(18, 5, KEY_RESERVED),
205 KEY(18, 6, KEY_RESERVED),
206 KEY(18, 7, KEY_RESERVED),
207
208 KEY(19, 0, KEY_RESERVED),
209 KEY(19, 1, KEY_RESERVED),
210 KEY(19, 2, KEY_RESERVED),
211 KEY(19, 3, KEY_RESERVED),
212 KEY(19, 4, KEY_RESERVED),
213 KEY(19, 5, KEY_RESERVED),
214 KEY(19, 6, KEY_RESERVED),
215 KEY(19, 7, KEY_RESERVED),
216
217 KEY(20, 0, KEY_7),
218 KEY(20, 1, KEY_RESERVED),
219 KEY(20, 2, KEY_RESERVED),
220 KEY(20, 3, KEY_RESERVED),
221 KEY(20, 4, KEY_RESERVED),
222 KEY(20, 5, KEY_RESERVED),
223 KEY(20, 6, KEY_RESERVED),
224 KEY(20, 7, KEY_RESERVED),
225
226 KEY(21, 0, KEY_9),
227 KEY(21, 1, KEY_8),
228 KEY(21, 2, KEY_4),
229 KEY(21, 3, KEY_RESERVED),
230 KEY(21, 4, KEY_1),
231 KEY(21, 5, KEY_RESERVED),
232 KEY(21, 6, KEY_RESERVED),
233 KEY(21, 7, KEY_RESERVED),
234
235 KEY(22, 0, KEY_RESERVED),
236 KEY(22, 1, KEY_SLASH),
237 KEY(22, 2, KEY_6),
238 KEY(22, 3, KEY_5),
239 KEY(22, 4, KEY_3),
240 KEY(22, 5, KEY_2),
241 KEY(22, 6, KEY_RESERVED),
242 KEY(22, 7, KEY_0),
243
244 KEY(23, 0, KEY_RESERVED),
245 KEY(23, 1, KEY_RESERVED),
246 KEY(23, 2, KEY_RESERVED),
247 KEY(23, 3, KEY_RESERVED),
248 KEY(23, 4, KEY_RESERVED),
249 KEY(23, 5, KEY_RESERVED),
250 KEY(23, 6, KEY_RESERVED),
251 KEY(23, 7, KEY_RESERVED),
252
253 KEY(24, 0, KEY_RESERVED),
254 KEY(24, 1, KEY_RESERVED),
255 KEY(24, 2, KEY_RESERVED),
256 KEY(24, 3, KEY_RESERVED),
257 KEY(24, 4, KEY_RESERVED),
258 KEY(24, 5, KEY_RESERVED),
259 KEY(24, 6, KEY_RESERVED),
260 KEY(24, 7, KEY_RESERVED),
261
262 KEY(25, 0, KEY_RESERVED),
263 KEY(25, 1, KEY_RESERVED),
264 KEY(25, 2, KEY_RESERVED),
265 KEY(25, 3, KEY_RESERVED),
266 KEY(25, 4, KEY_RESERVED),
267 KEY(25, 5, KEY_RESERVED),
268 KEY(25, 6, KEY_RESERVED),
269 KEY(25, 7, KEY_RESERVED),
270
271 KEY(26, 0, KEY_RESERVED),
272 KEY(26, 1, KEY_RESERVED),
273 KEY(26, 2, KEY_RESERVED),
274 KEY(26, 3, KEY_RESERVED),
275 KEY(26, 4, KEY_RESERVED),
276 KEY(26, 5, KEY_RESERVED),
277 KEY(26, 6, KEY_RESERVED),
278 KEY(26, 7, KEY_RESERVED),
279
280 KEY(27, 0, KEY_RESERVED),
281 KEY(27, 1, KEY_KPASTERISK),
282 KEY(27, 2, KEY_RESERVED),
283 KEY(27, 3, KEY_KPMINUS),
284 KEY(27, 4, KEY_KPPLUS),
285 KEY(27, 5, KEY_DOT),
286 KEY(27, 6, KEY_RESERVED),
287 KEY(27, 7, KEY_RESERVED),
288
289 KEY(28, 0, KEY_RESERVED),
290 KEY(28, 1, KEY_RESERVED),
291 KEY(28, 2, KEY_RESERVED),
292 KEY(28, 3, KEY_RESERVED),
293 KEY(28, 4, KEY_RESERVED),
294 KEY(28, 5, KEY_VOLUMEUP),
295 KEY(28, 6, KEY_RESERVED),
296 KEY(28, 7, KEY_RESERVED),
297
298 KEY(29, 0, KEY_RESERVED),
299 KEY(29, 1, KEY_RESERVED),
300 KEY(29, 2, KEY_RESERVED),
301 KEY(29, 3, KEY_HOME),
302 KEY(29, 4, KEY_END),
303 KEY(29, 5, KEY_BRIGHTNESSUP),
304 KEY(29, 6, KEY_VOLUMEDOWN),
305 KEY(29, 7, KEY_BRIGHTNESSDOWN),
306
307 KEY(30, 0, KEY_NUMLOCK),
308 KEY(30, 1, KEY_SCROLLLOCK),
309 KEY(30, 2, KEY_MUTE),
310 KEY(30, 3, KEY_RESERVED),
311 KEY(30, 4, KEY_RESERVED),
312 KEY(30, 5, KEY_RESERVED),
313 KEY(30, 6, KEY_RESERVED),
314 KEY(30, 7, KEY_RESERVED),
315
316 KEY(31, 0, KEY_RESERVED),
317 KEY(31, 1, KEY_RESERVED),
318 KEY(31, 2, KEY_RESERVED),
319 KEY(31, 3, KEY_RESERVED),
320 KEY(31, 4, KEY_QUESTION),
321 KEY(31, 5, KEY_RESERVED),
322 KEY(31, 6, KEY_RESERVED),
323 KEY(31, 7, KEY_RESERVED),
324};
325
326static const struct matrix_keymap_data keymap_data = {
327 .keymap = kbd_keymap,
328 .keymap_size = ARRAY_SIZE(kbd_keymap),
329};
330
331static struct tegra_kbc_wake_key harmony_wake_cfg[] = {
332 [0] = {
333 .row = 1,
334 .col = 7,
335 },
336 [1] = {
337 .row = 15,
338 .col = 0,
339 },
340};
341
342static struct tegra_kbc_platform_data harmony_kbc_platform_data = {
343 .debounce_cnt = 2,
344 .repeat_cnt = 5 * 32,
345 .wakeup = true,
346 .keymap_data = &keymap_data,
347 .use_fn_map = true,
348 .wake_cnt = 2,
349 .wake_cfg = &harmony_wake_cfg[0],
350#ifdef CONFIG_ANDROID
351 .disable_ev_rep = true,
352#endif
353};
354
355int __init harmony_kbc_init(void)
356{
357 struct tegra_kbc_platform_data *data = &harmony_kbc_platform_data;
358 int i;
359 tegra_kbc_device.dev.platform_data = &harmony_kbc_platform_data;
360 pr_info("Registering tegra-kbc\n");
361
362 BUG_ON((KBC_MAX_ROW + KBC_MAX_COL) > KBC_MAX_GPIO);
363 for (i = 0; i < KBC_MAX_ROW; i++) {
364 data->pin_cfg[i].num = i;
365 data->pin_cfg[i].is_row = true;
366 }
367
368 for (i = 0; i < KBC_MAX_COL; i++)
369 data->pin_cfg[i + KBC_MAX_ROW].num = i;
370
371 platform_device_register(&tegra_kbc_device);
372 pr_info("Registering successful tegra-kbc\n");
373 return 0;
374}
375
diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c
new file mode 100644
index 00000000000..c24039652bc
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-panel.c
@@ -0,0 +1,398 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-panel.c
3 *
4 * Copyright (c) 2010-2012, NVIDIA Corporation.
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/delay.h>
18#include <linux/resource.h>
19#include <linux/platform_device.h>
20#include <asm/mach-types.h>
21#include <linux/nvhost.h>
22#include <linux/gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/pwm_backlight.h>
25
26#include <mach/dc.h>
27#include <mach/irqs.h>
28#include <mach/iomap.h>
29#include <mach/nvmap.h>
30#include <mach/tegra_fb.h>
31#include <mach/fb.h>
32
33#include "devices.h"
34#include "gpio-names.h"
35#include "board.h"
36
37#define harmony_bl_enb TEGRA_GPIO_PB5
38#define harmony_lvds_shutdown TEGRA_GPIO_PB2
39#define harmony_en_vdd_pnl TEGRA_GPIO_PC6
40#define harmony_bl_vdd TEGRA_GPIO_PW0
41#define harmony_bl_pwm TEGRA_GPIO_PB4
42#define harmony_hdmi_hpd TEGRA_GPIO_PN7
43
44/* panel power on sequence timing */
45#define harmony_pnl_to_lvds_ms 0
46#define harmony_lvds_to_bl_ms 200
47
48static int harmony_backlight_init(struct device *dev)
49{
50 int ret;
51
52 ret = gpio_request(harmony_bl_enb, "backlight_enb");
53 if (ret < 0)
54 return ret;
55
56 ret = gpio_direction_output(harmony_bl_enb, 1);
57 if (ret < 0)
58 gpio_free(harmony_bl_enb);
59 else
60 tegra_gpio_enable(harmony_bl_enb);
61
62 return ret;
63}
64
65static void harmony_backlight_exit(struct device *dev)
66{
67 gpio_set_value(harmony_bl_enb, 0);
68 gpio_free(harmony_bl_enb);
69 tegra_gpio_disable(harmony_bl_enb);
70}
71
72static int harmony_backlight_notify(struct device *unused, int brightness)
73{
74 gpio_set_value(harmony_en_vdd_pnl, !!brightness);
75 gpio_set_value(harmony_lvds_shutdown, !!brightness);
76 gpio_set_value(harmony_bl_enb, !!brightness);
77 return brightness;
78}
79
80static int harmony_disp1_check_fb(struct device *dev, struct fb_info *info);
81
82static struct platform_pwm_backlight_data harmony_backlight_data = {
83 .pwm_id = 0,
84 .max_brightness = 255,
85 .dft_brightness = 224,
86 .pwm_period_ns = 5000000,
87 .init = harmony_backlight_init,
88 .exit = harmony_backlight_exit,
89 .notify = harmony_backlight_notify,
90 /* Only toggle backlight on fb blank notifications for disp1 */
91 .check_fb = harmony_disp1_check_fb,
92};
93
94static struct platform_device harmony_backlight_device = {
95 .name = "pwm-backlight",
96 .id = -1,
97 .dev = {
98 .platform_data = &harmony_backlight_data,
99 },
100};
101
102static int harmony_panel_enable(void)
103{
104 gpio_set_value(harmony_en_vdd_pnl, 1);
105 mdelay(harmony_pnl_to_lvds_ms);
106 gpio_set_value(harmony_lvds_shutdown, 1);
107 mdelay(harmony_lvds_to_bl_ms);
108 return 0;
109}
110
111static int harmony_panel_disable(void)
112{
113 gpio_set_value(harmony_lvds_shutdown, 0);
114 gpio_set_value(harmony_en_vdd_pnl, 0);
115 return 0;
116}
117
118static int harmony_set_hdmi_power(bool enable)
119{
120 static struct {
121 struct regulator *regulator;
122 const char *name;
123 } regs[] = {
124 { .name = "avdd_hdmi" },
125 { .name = "avdd_hdmi_pll" },
126 };
127 int i;
128
129 for (i = 0; i < ARRAY_SIZE(regs); i++) {
130 if (!regs[i].regulator) {
131 regs[i].regulator = regulator_get(NULL, regs[i].name);
132
133 if (IS_ERR(regs[i].regulator)) {
134 int ret = PTR_ERR(regs[i].regulator);
135 regs[i].regulator = NULL;
136 return ret;
137 }
138 }
139
140 if (enable)
141 regulator_enable(regs[i].regulator);
142 else
143 regulator_disable(regs[i].regulator);
144 }
145
146 return 0;
147}
148
149static int harmony_hdmi_enable(void)
150{
151 return harmony_set_hdmi_power(true);
152}
153
154static int harmony_hdmi_disable(void)
155{
156 return harmony_set_hdmi_power(false);
157}
158
159static struct resource harmony_disp1_resources[] = {
160 {
161 .name = "irq",
162 .start = INT_DISPLAY_GENERAL,
163 .end = INT_DISPLAY_GENERAL,
164 .flags = IORESOURCE_IRQ,
165 },
166 {
167 .name = "regs",
168 .start = TEGRA_DISPLAY_BASE,
169 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
170 .flags = IORESOURCE_MEM,
171 },
172 {
173 .name = "fbmem",
174 .flags = IORESOURCE_MEM,
175 },
176};
177
178static struct resource harmony_disp2_resources[] = {
179 {
180 .name = "irq",
181 .start = INT_DISPLAY_B_GENERAL,
182 .end = INT_DISPLAY_B_GENERAL,
183 .flags = IORESOURCE_IRQ,
184 },
185 {
186 .name = "regs",
187 .start = TEGRA_DISPLAY2_BASE,
188 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
189 .flags = IORESOURCE_MEM,
190 },
191 {
192 .name = "fbmem",
193 .flags = IORESOURCE_MEM,
194 },
195 {
196 .name = "hdmi_regs",
197 .start = TEGRA_HDMI_BASE,
198 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
199 .flags = IORESOURCE_MEM,
200 },
201};
202
203static struct tegra_dc_mode harmony_panel_modes[] = {
204 {
205 .pclk = 42430000,
206 .h_ref_to_sync = 4,
207 .v_ref_to_sync = 2,
208 .h_sync_width = 136,
209 .v_sync_width = 4,
210 .h_back_porch = 138,
211 .v_back_porch = 21,
212 .h_active = 1024,
213 .v_active = 600,
214 .h_front_porch = 34,
215 .v_front_porch = 4,
216 },
217};
218
219static struct tegra_fb_data harmony_fb_data = {
220 .win = 0,
221 .xres = 1024,
222 .yres = 600,
223 .bits_per_pixel = 32,
224 .flags = TEGRA_FB_FLIP_ON_PROBE,
225};
226
227static struct tegra_fb_data harmony_hdmi_fb_data = {
228 .win = 0,
229 .xres = 1280,
230 .yres = 720,
231 .bits_per_pixel = 16,
232};
233
234static struct tegra_dc_out harmony_disp1_out = {
235 .type = TEGRA_DC_OUT_RGB,
236
237 .align = TEGRA_DC_ALIGN_MSB,
238 .order = TEGRA_DC_ORDER_RED_BLUE,
239 .depth = 18,
240 .dither = TEGRA_DC_ORDERED_DITHER,
241
242 .modes = harmony_panel_modes,
243 .n_modes = ARRAY_SIZE(harmony_panel_modes),
244
245 .enable = harmony_panel_enable,
246 .disable = harmony_panel_disable,
247};
248
249static struct tegra_dc_out harmony_disp2_out = {
250 .type = TEGRA_DC_OUT_HDMI,
251 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
252
253 .dcc_bus = 1,
254 .hotplug_gpio = harmony_hdmi_hpd,
255
256 .align = TEGRA_DC_ALIGN_MSB,
257 .order = TEGRA_DC_ORDER_RED_BLUE,
258
259 .enable = harmony_hdmi_enable,
260 .disable = harmony_hdmi_disable,
261};
262
263static struct tegra_dc_platform_data harmony_disp1_pdata = {
264 .flags = TEGRA_DC_FLAG_ENABLED,
265 .default_out = &harmony_disp1_out,
266 .fb = &harmony_fb_data,
267};
268
269static struct tegra_dc_platform_data harmony_disp2_pdata = {
270 .flags = 0,
271 .default_out = &harmony_disp2_out,
272 .fb = &harmony_hdmi_fb_data,
273};
274
275static struct nvhost_device harmony_disp1_device = {
276 .name = "tegradc",
277 .id = 0,
278 .resource = harmony_disp1_resources,
279 .num_resources = ARRAY_SIZE(harmony_disp1_resources),
280 .dev = {
281 .platform_data = &harmony_disp1_pdata,
282 },
283};
284
285static int harmony_disp1_check_fb(struct device *dev, struct fb_info *info)
286{
287 return info->device == &harmony_disp1_device.dev;
288}
289
290static struct nvhost_device harmony_disp2_device = {
291 .name = "tegradc",
292 .id = 1,
293 .resource = harmony_disp2_resources,
294 .num_resources = ARRAY_SIZE(harmony_disp2_resources),
295 .dev = {
296 .platform_data = &harmony_disp2_pdata,
297 },
298};
299
300#if defined(CONFIG_TEGRA_NVMAP)
301static struct nvmap_platform_carveout harmony_carveouts[] = {
302 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
303 [1] = {
304 .name = "generic-0",
305 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
306 .buddy_size = SZ_32K,
307 },
308};
309
310static struct nvmap_platform_data harmony_nvmap_data = {
311 .carveouts = harmony_carveouts,
312 .nr_carveouts = ARRAY_SIZE(harmony_carveouts),
313};
314
315static struct platform_device harmony_nvmap_device = {
316 .name = "tegra-nvmap",
317 .id = -1,
318 .dev = {
319 .platform_data = &harmony_nvmap_data,
320 },
321};
322#endif
323
324static struct platform_device *harmony_gfx_devices[] __initdata = {
325#if defined(CONFIG_TEGRA_NVMAP)
326 &harmony_nvmap_device,
327#endif
328 &tegra_pwfm0_device,
329 &harmony_backlight_device,
330};
331
332int __init harmony_panel_init(void)
333{
334 int err;
335 struct resource *res;
336
337 gpio_request(harmony_en_vdd_pnl, "en_vdd_pnl");
338 gpio_direction_output(harmony_en_vdd_pnl, 1);
339 tegra_gpio_enable(harmony_en_vdd_pnl);
340
341 gpio_request(harmony_bl_vdd, "bl_vdd");
342 gpio_direction_output(harmony_bl_vdd, 1);
343 tegra_gpio_enable(harmony_bl_vdd);
344
345 gpio_request(harmony_lvds_shutdown, "lvds_shdn");
346 gpio_direction_output(harmony_lvds_shutdown, 1);
347 tegra_gpio_enable(harmony_lvds_shutdown);
348
349 gpio_request(harmony_hdmi_hpd, "hdmi_hpd");
350 gpio_direction_input(harmony_hdmi_hpd);
351 tegra_gpio_enable(harmony_hdmi_hpd);
352
353#if defined(CONFIG_TEGRA_NVMAP)
354 harmony_carveouts[1].base = tegra_carveout_start;
355 harmony_carveouts[1].size = tegra_carveout_size;
356#endif
357
358#ifdef CONFIG_TEGRA_GRHOST
359 err = nvhost_device_register(&tegra_grhost_device);
360 if (err)
361 return err;
362#endif
363
364 err = platform_add_devices(harmony_gfx_devices,
365 ARRAY_SIZE(harmony_gfx_devices));
366 if (err)
367 return err;
368
369 res = nvhost_get_resource_byname(&harmony_disp1_device,
370 IORESOURCE_MEM, "fbmem");
371 if (res) {
372 res->start = tegra_fb_start;
373 res->end = tegra_fb_start + tegra_fb_size - 1;
374 }
375
376 res = nvhost_get_resource_byname(&harmony_disp2_device,
377 IORESOURCE_MEM, "fbmem");
378 if (res) {
379 res->start = tegra_fb2_start;
380 res->end = tegra_fb2_start + tegra_fb2_size - 1;
381 }
382
383 /* Copy the bootloader fb to the fb. */
384 if (tegra_bootloader_fb_start)
385 tegra_move_framebuffer(tegra_fb_start,
386 tegra_bootloader_fb_start,
387 min(tegra_fb_size, tegra_bootloader_fb_size));
388 err = nvhost_device_register(&harmony_disp1_device);
389 if (err)
390 return err;
391
392 err = nvhost_device_register(&harmony_disp2_device);
393 if (err)
394 return err;
395
396 return 0;
397}
398
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
new file mode 100644
index 00000000000..2fa64cff58f
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -0,0 +1,180 @@
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 <linux/gpio.h>
19#include <linux/init.h>
20#include <mach/pinmux.h>
21
22#include "gpio-names.h"
23#include "board-harmony.h"
24
25#define DEFAULT_DRIVE(_name) \
26 { \
27 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
28 .hsm = TEGRA_HSM_DISABLE, \
29 .schmitt = TEGRA_SCHMITT_ENABLE, \
30 .drive = TEGRA_DRIVE_DIV_1, \
31 .pull_down = TEGRA_PULL_31, \
32 .pull_up = TEGRA_PULL_31, \
33 .slew_rising = TEGRA_SLEW_SLOWEST, \
34 .slew_falling = TEGRA_SLEW_SLOWEST, \
35 }
36
37static __initdata struct tegra_drive_pingroup_config harmony_drive_pinmux[] = {
38 DEFAULT_DRIVE(SDIO1),
39};
40
41static __initdata struct tegra_pingroup_config harmony_pinmux[] = {
42 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
43 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
44 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
49 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
50 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
51 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
52 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
53 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
54 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
55 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
59 {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
61 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
64 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
68 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
70 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
71 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
73 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
74 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
81 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
85 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
92 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
99 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
100 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
107 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
108 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
122 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
127 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
132 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
137 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
138 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
139 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
140 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
141 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
142 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
143 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
144 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
145 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
146 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
147 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
148 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
149 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
150 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
151 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
152 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
153 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
154 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
155 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
156 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
157 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
158};
159
160static struct tegra_gpio_table gpio_table[] = {
161 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
162 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
163 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
164 { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
165 { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
166 { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
167 { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
168 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
169 { .gpio = TEGRA_GPIO_INT_MIC_EN, .enable = true },
170 { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true },
171};
172
173void __init harmony_pinmux_init(void)
174{
175 tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
176 tegra_drive_pinmux_config_table(harmony_drive_pinmux,
177 ARRAY_SIZE(harmony_drive_pinmux));
178
179 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
180}
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
new file mode 100644
index 00000000000..39473f5d9a3
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -0,0 +1,332 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21
22#include <linux/regulator/machine.h>
23#include <linux/regulator/fixed.h>
24#include <linux/mfd/tps6586x.h>
25#include <linux/io.h>
26
27#include <mach/iomap.h>
28#include <mach/irqs.h>
29
30#include "board-harmony.h"
31#include "pm.h"
32
33#define PMC_CTRL 0x0
34#define PMC_CTRL_INTR_LOW (1 << 17)
35
36static struct regulator_consumer_supply tps658621_sm0_supply[] = {
37 REGULATOR_SUPPLY("vdd_core", NULL),
38};
39
40static struct regulator_consumer_supply tps658621_sm1_supply[] = {
41 REGULATOR_SUPPLY("vdd_cpu", NULL),
42};
43
44static struct regulator_consumer_supply tps658621_sm2_supply[] = {
45 REGULATOR_SUPPLY("vdd_sm2", NULL),
46};
47
48static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
49 REGULATOR_SUPPLY("p_cam_avdd", NULL),
50};
51
52static struct regulator_consumer_supply tps658621_ldo1_supply[] = {
53 REGULATOR_SUPPLY("avdd_pll", NULL),
54};
55
56static struct regulator_consumer_supply tps658621_ldo2_supply[] = {
57 REGULATOR_SUPPLY("vdd_rtc", NULL),
58};
59
60static struct regulator_consumer_supply tps658621_ldo3_supply[] = {
61 REGULATOR_SUPPLY("avdd_usb", NULL),
62 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
63 REGULATOR_SUPPLY("avdd_lvds", NULL),
64};
65
66static struct regulator_consumer_supply tps658621_ldo4_supply[] = {
67 REGULATOR_SUPPLY("avdd_osc", NULL),
68 REGULATOR_SUPPLY("vddio_sys", "panjit_touch"),
69};
70
71static struct regulator_consumer_supply tps658621_ldo5_supply[] = {
72 REGULATOR_SUPPLY("vcore_mmc", "sdhci-tegra.1"),
73 REGULATOR_SUPPLY("vcore_mmc", "sdhci-tegra.3"),
74};
75
76static struct regulator_consumer_supply tps658621_ldo6_supply[] = {
77 REGULATOR_SUPPLY("avdd_vdac", NULL),
78};
79
80static struct regulator_consumer_supply tps658621_ldo7_supply[] = {
81 REGULATOR_SUPPLY("avdd_hdmi", NULL),
82 REGULATOR_SUPPLY("vdd_fuse", NULL),
83};
84
85static struct regulator_consumer_supply tps658621_ldo8_supply[] = {
86 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
87};
88
89static struct regulator_consumer_supply tps658621_ldo9_supply[] = {
90 REGULATOR_SUPPLY("avdd_2v85", NULL),
91 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
92 REGULATOR_SUPPLY("avdd_amp", NULL),
93};
94
95/* regulator supplies power to WWAN - by default disable */
96static struct regulator_consumer_supply vdd_1v5_consumer_supply[] = {
97 REGULATOR_SUPPLY("vdd_1v5", NULL),
98};
99
100static struct regulator_init_data vdd_1v5_initdata = {
101 .consumer_supplies = vdd_1v5_consumer_supply,
102 .num_consumer_supplies = 1,
103 .constraints = {
104 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
105 .always_on = 0,
106 },
107};
108
109static struct fixed_voltage_config vdd_1v5 = {
110 .supply_name = "vdd_1v5",
111 .microvolts = 1500000, /* Enable 1.5V */
112 .gpio = TPS_GPIO_EN_1V5, /* GPIO BASE+0 */
113 .startup_delay = 0,
114 .enable_high = 0,
115 .enabled_at_boot = 0,
116 .init_data = &vdd_1v5_initdata,
117};
118
119/* regulator supplies power to WLAN - enable here, to satisfy SDIO probing */
120static struct regulator_consumer_supply vdd_1v2_consumer_supply[] = {
121 REGULATOR_SUPPLY("vdd_1v2", NULL),
122};
123
124static struct regulator_init_data vdd_1v2_initdata = {
125 .consumer_supplies = vdd_1v2_consumer_supply,
126 .num_consumer_supplies = 1,
127 .constraints = {
128 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
129 .always_on = 1,
130 },
131};
132
133static struct fixed_voltage_config vdd_1v2 = {
134 .supply_name = "vdd_1v2",
135 .microvolts = 1200000, /* Enable 1.2V */
136 .gpio = TPS_GPIO_EN_1V2, /* GPIO BASE+1 */
137 .startup_delay = 0,
138 .enable_high = 1,
139 .enabled_at_boot = 1,
140 .init_data = &vdd_1v2_initdata,
141};
142
143/* regulator supplies power to PLL - enable here */
144static struct regulator_consumer_supply vdd_1v05_consumer_supply[] = {
145 REGULATOR_SUPPLY("vdd_1v05", NULL),
146};
147
148static struct regulator_init_data vdd_1v05_initdata = {
149 .consumer_supplies = vdd_1v05_consumer_supply,
150 .num_consumer_supplies = 1,
151 .constraints = {
152 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
153 .always_on = 1,
154 },
155};
156
157static struct fixed_voltage_config vdd_1v05 = {
158 .supply_name = "vdd_1v05",
159 .microvolts = 1050000, /* Enable 1.05V */
160 .gpio = TPS_GPIO_EN_1V05, /* BASE+2 */
161 .startup_delay = 0,
162 .enable_high = 1,
163 .enabled_at_boot = 0,
164 .init_data = &vdd_1v05_initdata,
165};
166
167/* mode pin for 1.05V regulator - enable here */
168static struct regulator_consumer_supply vdd_1v05_mode_consumer_supply[] = {
169 REGULATOR_SUPPLY("vdd_1v05_mode", NULL),
170};
171
172static struct regulator_init_data vdd_1v05_mode_initdata = {
173 .consumer_supplies = vdd_1v05_mode_consumer_supply,
174 .num_consumer_supplies = 1,
175 .constraints = {
176 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
177 .always_on = 1,
178 },
179};
180
181static struct fixed_voltage_config vdd_1v05_mode = {
182 .supply_name = "vdd_1v05_mode",
183 .microvolts = 1050000, /* Enable 1.05V */
184 .gpio = TPS_GPIO_MODE_1V05, /* BASE+3 */
185 .startup_delay = 0,
186 .enable_high = 1,
187 .enabled_at_boot = 0,
188 .init_data = &vdd_1v05_mode_initdata,
189};
190
191#define REGULATOR_INIT(_id, _minmv, _maxmv) \
192 { \
193 .constraints = { \
194 .min_uV = (_minmv)*1000, \
195 .max_uV = (_maxmv)*1000, \
196 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
197 REGULATOR_MODE_STANDBY), \
198 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
199 REGULATOR_CHANGE_STATUS | \
200 REGULATOR_CHANGE_VOLTAGE), \
201 }, \
202 .num_consumer_supplies = ARRAY_SIZE(tps658621_##_id##_supply),\
203 .consumer_supplies = tps658621_##_id##_supply, \
204 }
205
206static struct regulator_init_data sm0_data = REGULATOR_INIT(sm0, 725, 1500);
207static struct regulator_init_data sm1_data = REGULATOR_INIT(sm1, 725, 1500);
208static struct regulator_init_data sm2_data = REGULATOR_INIT(sm2, 3000, 4550);
209static struct regulator_init_data ldo0_data = REGULATOR_INIT(ldo0, 1250, 3300);
210static struct regulator_init_data ldo1_data = REGULATOR_INIT(ldo1, 725, 1500);
211static struct regulator_init_data ldo2_data = REGULATOR_INIT(ldo2, 725, 1500);
212static struct regulator_init_data ldo3_data = REGULATOR_INIT(ldo3, 1250, 3300);
213static struct regulator_init_data ldo4_data = REGULATOR_INIT(ldo4, 1700, 2475);
214static struct regulator_init_data ldo5_data = REGULATOR_INIT(ldo5, 1250, 3300);
215static struct regulator_init_data ldo6_data = REGULATOR_INIT(ldo6, 1250, 3300);
216static struct regulator_init_data ldo7_data = REGULATOR_INIT(ldo7, 1250, 3300);
217static struct regulator_init_data ldo8_data = REGULATOR_INIT(ldo8, 1250, 3300);
218static struct regulator_init_data ldo9_data = REGULATOR_INIT(ldo9, 1250, 3300);
219
220static struct tps6586x_rtc_platform_data rtc_data = {
221 .irq = TEGRA_NR_IRQS + TPS6586X_INT_RTC_ALM1,
222 .start = {
223 .year = 2009,
224 .month = 1,
225 .day = 1,
226 },
227 .cl_sel = TPS6586X_RTC_CL_SEL_1_5PF /* use lowest (external 20pF cap) */
228};
229
230#define TPS_REG(_id, _data) \
231 { \
232 .id = TPS6586X_ID_##_id, \
233 .name = "tps6586x-regulator", \
234 .platform_data = _data, \
235 }
236
237#define TPS_GPIO_FIXED_REG(_id, _data) \
238 { \
239 .id = _id, \
240 .name = "reg-fixed-voltage", \
241 .platform_data = _data, \
242 }
243
244static struct tps6586x_subdev_info tps_devs[] = {
245 TPS_REG(SM_0, &sm0_data),
246 TPS_REG(SM_1, &sm1_data),
247 TPS_REG(SM_2, &sm2_data),
248 TPS_REG(LDO_0, &ldo0_data),
249 TPS_REG(LDO_1, &ldo1_data),
250 TPS_REG(LDO_2, &ldo2_data),
251 TPS_REG(LDO_3, &ldo3_data),
252 TPS_REG(LDO_4, &ldo4_data),
253 TPS_REG(LDO_5, &ldo5_data),
254 TPS_REG(LDO_6, &ldo6_data),
255 TPS_REG(LDO_7, &ldo7_data),
256 TPS_REG(LDO_8, &ldo8_data),
257 TPS_REG(LDO_9, &ldo9_data),
258 TPS_GPIO_FIXED_REG(0, &vdd_1v5),
259 TPS_GPIO_FIXED_REG(1, &vdd_1v2),
260 TPS_GPIO_FIXED_REG(2, &vdd_1v05),
261 TPS_GPIO_FIXED_REG(3, &vdd_1v05_mode),
262 {
263 .id = 0,
264 .name = "tps6586x-rtc",
265 .platform_data = &rtc_data,
266 },
267};
268
269static struct tps6586x_platform_data tps_platform = {
270 .irq_base = TEGRA_NR_IRQS,
271 .num_subdevs = ARRAY_SIZE(tps_devs),
272 .subdevs = tps_devs,
273 .gpio_base = HARMONY_GPIO_TPS6586X(0),
274 .use_power_off = true,
275};
276
277static struct i2c_board_info __initdata harmony_regulators[] = {
278 {
279 I2C_BOARD_INFO("tps6586x", 0x34),
280 .irq = INT_EXTERNAL_PMU,
281 .platform_data = &tps_platform,
282 },
283};
284
285static void harmony_board_suspend(int lp_state, enum suspend_stage stg)
286{
287 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
288 tegra_console_uart_suspend();
289}
290
291static void harmony_board_resume(int lp_state, enum resume_stage stg)
292{
293 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
294 tegra_console_uart_resume();
295}
296
297static struct tegra_suspend_platform_data harmony_suspend_data = {
298 /*
299 * Check power on time and crystal oscillator start time
300 * for appropriate settings.
301 */
302 .cpu_timer = 5000,
303 .cpu_off_timer = 5000,
304 .suspend_mode = TEGRA_SUSPEND_LP0,
305 .core_timer = 0x7e7e,
306 .core_off_timer = 0x7f,
307 .corereq_high = false,
308 .sysclkreq_high = true,
309 .board_suspend = harmony_board_suspend,
310 .board_resume = harmony_board_resume,
311};
312
313int __init harmony_suspend_init(void)
314{
315 tegra_init_suspend(&harmony_suspend_data);
316 return 0;
317}
318
319int __init harmony_regulator_init(void)
320{
321 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
322 u32 pmc_ctrl;
323
324 /* configure the power management controller to trigger PMU
325 * interrupts when low */
326 pmc_ctrl = readl(pmc + PMC_CTRL);
327 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
328
329 i2c_register_board_info(4, harmony_regulators, 1);
330
331 return 0;
332}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
new file mode 100644
index 00000000000..86e9615f785
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -0,0 +1,507 @@
1/*
2 * arch/arm/mach-tegra/board-harmony.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA, Inc.
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/platform_device.h>
21#include <linux/serial_8250.h>
22#include <linux/clk.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/dma-mapping.h>
26#include <linux/pda_power.h>
27#include <linux/input.h>
28#include <linux/io.h>
29#include <linux/gpio.h>
30#include <linux/gpio_keys.h>
31#include <linux/i2c.h>
32#include <linux/i2c-tegra.h>
33#include <linux/memblock.h>
34#include <linux/delay.h>
35
36#include <sound/wm8903.h>
37
38#include <asm/mach-types.h>
39#include <asm/mach/arch.h>
40#include <asm/mach/time.h>
41#include <asm/setup.h>
42
43#include <mach/tegra_wm8903_pdata.h>
44#include <mach/iomap.h>
45#include <mach/irqs.h>
46#include <mach/sdhci.h>
47#include <mach/nand.h>
48#include <mach/clk.h>
49#include <mach/usb_phy.h>
50
51#include "clock.h"
52#include "board.h"
53#include "board-harmony.h"
54#include "clock.h"
55#include "devices.h"
56#include "gpio-names.h"
57#include "pm.h"
58
59/* NVidia bootloader tags */
60#define ATAG_NVIDIA 0x41000801
61
62#define ATAG_NVIDIA_RM 0x1
63#define ATAG_NVIDIA_DISPLAY 0x2
64#define ATAG_NVIDIA_FRAMEBUFFER 0x3
65#define ATAG_NVIDIA_CHIPSHMOO 0x4
66#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5
67#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000
68#define ATAG_NVIDIA_PRESERVED_MEM_N 2
69#define ATAG_NVIDIA_FORCE_32 0x7fffffff
70
71struct tag_tegra {
72 __u32 bootarg_key;
73 __u32 bootarg_len;
74 char bootarg[1];
75};
76
77static int __init parse_tag_nvidia(const struct tag *tag)
78{
79
80 return 0;
81}
82__tagtable(ATAG_NVIDIA, parse_tag_nvidia);
83
84static struct tegra_utmip_config utmi_phy_config = {
85 .hssync_start_delay = 0,
86 .idle_wait_delay = 17,
87 .elastic_limit = 16,
88 .term_range_adj = 6,
89 .xcvr_setup = 9,
90 .xcvr_lsfslew = 2,
91 .xcvr_lsrslew = 2,
92};
93
94static struct tegra_ehci_platform_data tegra_ehci_pdata = {
95 .phy_config = &utmi_phy_config,
96 .operating_mode = TEGRA_USB_HOST,
97 .power_down_on_bus_suspend = 1,
98};
99
100static struct tegra_nand_chip_parms nand_chip_parms[] = {
101 /* Samsung K5E2G1GACM */
102 [0] = {
103 .vendor_id = 0xEC,
104 .device_id = 0xAA,
105 .read_id_fourth_byte = 0x15,
106 .capacity = 256,
107 .timing = {
108 .trp = 21,
109 .trh = 15,
110 .twp = 21,
111 .twh = 15,
112 .tcs = 31,
113 .twhr = 60,
114 .tcr_tar_trr = 20,
115 .twb = 100,
116 .trp_resp = 30,
117 .tadl = 100,
118 },
119 },
120 /* Hynix H5PS1GB3EFR */
121 [1] = {
122 .vendor_id = 0xAD,
123 .device_id = 0xDC,
124 .read_id_fourth_byte = 0x95,
125 .capacity = 512,
126 .timing = {
127 .trp = 12,
128 .trh = 10,
129 .twp = 12,
130 .twh = 10,
131 .tcs = 20,
132 .twhr = 80,
133 .tcr_tar_trr = 20,
134 .twb = 100,
135 .trp_resp = 20,
136 .tadl = 70,
137 },
138 },
139};
140
141struct tegra_nand_platform harmony_nand_data = {
142 .max_chips = 8,
143 .chip_parms = nand_chip_parms,
144 .nr_chip_parms = ARRAY_SIZE(nand_chip_parms),
145 .wp_gpio = TEGRA_GPIO_PC7,
146};
147
148static struct resource resources_nand[] = {
149 [0] = {
150 .start = INT_NANDFLASH,
151 .end = INT_NANDFLASH,
152 .flags = IORESOURCE_IRQ,
153 },
154};
155
156struct platform_device tegra_nand_device = {
157 .name = "tegra_nand",
158 .id = -1,
159 .num_resources = ARRAY_SIZE(resources_nand),
160 .resource = resources_nand,
161 .dev = {
162 .platform_data = &harmony_nand_data,
163 },
164};
165
166static struct gpio_keys_button harmony_gpio_keys_buttons[] = {
167 {
168 .code = KEY_POWER,
169 .gpio = TEGRA_GPIO_POWERKEY,
170 .active_low = 1,
171 .desc = "Power",
172 .type = EV_KEY,
173 .wakeup = 1,
174 },
175};
176
177static struct gpio_keys_platform_data harmony_gpio_keys = {
178 .buttons = harmony_gpio_keys_buttons,
179 .nbuttons = ARRAY_SIZE(harmony_gpio_keys_buttons),
180};
181
182static struct platform_device harmony_gpio_keys_device = {
183 .name = "gpio-keys",
184 .id = -1,
185 .dev = {
186 .platform_data = &harmony_gpio_keys,
187 }
188};
189
190static void harmony_keys_init(void)
191{
192 int i;
193
194 for (i = 0; i < ARRAY_SIZE(harmony_gpio_keys_buttons); i++)
195 tegra_gpio_enable(harmony_gpio_keys_buttons[i].gpio);
196}
197
198static struct tegra_wm8903_platform_data harmony_audio_pdata = {
199 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
200 .gpio_hp_det = TEGRA_GPIO_HP_DET,
201 .gpio_hp_mute = -1,
202 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
203 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
204};
205
206static struct platform_device harmony_audio_device = {
207 .name = "tegra-snd-wm8903",
208 .id = 0,
209 .dev = {
210 .platform_data = &harmony_audio_pdata,
211 },
212};
213
214static struct tegra_i2c_platform_data harmony_i2c1_platform_data = {
215 .adapter_nr = 0,
216 .bus_count = 1,
217 .bus_clk_rate = { 400000, 0 },
218};
219
220static const struct tegra_pingroup_config i2c2_ddc = {
221 .pingroup = TEGRA_PINGROUP_DDC,
222 .func = TEGRA_MUX_I2C2,
223};
224
225static const struct tegra_pingroup_config i2c2_gen2 = {
226 .pingroup = TEGRA_PINGROUP_PTA,
227 .func = TEGRA_MUX_I2C2,
228};
229
230static struct tegra_i2c_platform_data harmony_i2c2_platform_data = {
231 .adapter_nr = 1,
232 .bus_count = 2,
233 .bus_clk_rate = { 100000, 100000 },
234 .bus_mux = { &i2c2_ddc, &i2c2_gen2 },
235 .bus_mux_len = { 1, 1 },
236};
237
238static struct tegra_i2c_platform_data harmony_i2c3_platform_data = {
239 .adapter_nr = 3,
240 .bus_count = 1,
241 .bus_clk_rate = { 400000, 0 },
242};
243
244static struct tegra_i2c_platform_data harmony_dvc_platform_data = {
245 .adapter_nr = 4,
246 .bus_count = 1,
247 .bus_clk_rate = { 400000, 0 },
248 .is_dvc = true,
249};
250
251static struct wm8903_platform_data harmony_wm8903_pdata = {
252 .irq_active_low = 0,
253 .micdet_cfg = 0,
254 .micdet_delay = 100,
255 .gpio_base = HARMONY_GPIO_WM8903(0),
256 .gpio_cfg = {
257 WM8903_GPIO_NO_CONFIG,
258 WM8903_GPIO_NO_CONFIG,
259 0,
260 WM8903_GPIO_NO_CONFIG,
261 WM8903_GPIO_NO_CONFIG,
262 },
263};
264
265static struct i2c_board_info __initdata wm8903_board_info = {
266 I2C_BOARD_INFO("wm8903", 0x1a),
267 .platform_data = &harmony_wm8903_pdata,
268 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
269};
270
271static void __init harmony_i2c_init(void)
272{
273 tegra_i2c_device1.dev.platform_data = &harmony_i2c1_platform_data;
274 tegra_i2c_device2.dev.platform_data = &harmony_i2c2_platform_data;
275 tegra_i2c_device3.dev.platform_data = &harmony_i2c3_platform_data;
276 tegra_i2c_device4.dev.platform_data = &harmony_dvc_platform_data;
277
278 platform_device_register(&tegra_i2c_device1);
279 platform_device_register(&tegra_i2c_device2);
280 platform_device_register(&tegra_i2c_device3);
281 platform_device_register(&tegra_i2c_device4);
282
283 i2c_register_board_info(0, &wm8903_board_info, 1);
284}
285
286/* OTG gadget device */
287/*static u64 tegra_otg_dmamask = DMA_BIT_MASK(32);
288
289
290static struct resource tegra_otg_resources[] = {
291 [0] = {
292 .start = TEGRA_USB_BASE,
293 .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
294 .flags = IORESOURCE_MEM,
295 },
296 [1] = {
297 .start = INT_USB,
298 .end = INT_USB,
299 .flags = IORESOURCE_IRQ,
300 },
301};
302
303static struct fsl_usb2_platform_data tegra_otg_pdata = {
304 .operating_mode = FSL_USB2_DR_DEVICE,
305 .phy_mode = FSL_USB2_PHY_UTMI,
306};
307
308static struct platform_device tegra_otg = {
309 .name = "fsl-tegra-udc",
310 .id = -1,
311 .dev = {
312 .dma_mask = &tegra_otg_dmamask,
313 .coherent_dma_mask = 0xffffffff,
314 .platform_data = &tegra_otg_pdata,
315 },
316 .resource = tegra_otg_resources,
317 .num_resources = ARRAY_SIZE(tegra_otg_resources),
318};*/
319
320/* PDA power */
321static struct pda_power_pdata pda_power_pdata = {
322};
323
324static struct platform_device pda_power_device = {
325 .name = "pda_power",
326 .id = -1,
327 .dev = {
328 .platform_data = &pda_power_pdata,
329 },
330};
331
332static void harmony_debug_uart_init(void)
333{
334 struct clk *c;
335
336 debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
337 debug_uart_port_base = ((struct plat_serial8250_port *)(
338 debug_uartd_device.dev.platform_data))->mapbase;
339
340 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
341 pr_info("The debug console clock name is %s\n",
342 debug_uart_clk->name);
343 c = tegra_get_clock_by_name("pll_p");
344 if (IS_ERR_OR_NULL(c))
345 pr_err("Not getting the parent clock pll_p\n");
346 else
347 clk_set_parent(debug_uart_clk, c);
348
349 clk_enable(debug_uart_clk);
350 clk_set_rate(debug_uart_clk, clk_get_rate(c));
351 } else {
352 pr_err("Not getting the clock %s for debug console\n",
353 debug_uart_clk->name);
354 }
355 return;
356}
357
358static struct platform_device *harmony_devices[] __initdata = {
359 &debug_uartd_device,
360 &tegra_sdhci_device1,
361 &tegra_sdhci_device2,
362 &tegra_sdhci_device4,
363 &tegra_i2s_device1,
364 &tegra_i2s_device2,
365 &tegra_spdif_device,
366 &tegra_das_device,
367 &spdif_dit_device,
368 &bluetooth_dit_device,
369 &tegra_pcm_device,
370 &harmony_audio_device,
371 &tegra_pmu_device,
372 &tegra_nand_device,
373 &tegra_udc_device,
374 &harmony_gpio_keys_device,
375 &pda_power_device,
376 &tegra_ehci3_device,
377 &tegra_spi_device1,
378 &tegra_spi_device2,
379 &tegra_spi_device3,
380 &tegra_spi_device4,
381 &tegra_gart_device,
382 &tegra_avp_device,
383};
384
385static void __init tegra_harmony_fixup(struct machine_desc *desc,
386 struct tag *tags, char **cmdline, struct meminfo *mi)
387{
388 mi->nr_banks = 2;
389 mi->bank[0].start = PHYS_OFFSET;
390 mi->bank[0].size = 448 * SZ_1M;
391 mi->bank[1].start = SZ_512M;
392 mi->bank[1].size = SZ_512M;
393}
394
395static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
396 /* name parent rate enabled */
397 { "uartd", "pll_p", 216000000, true },
398 { "i2s1", "pll_a_out0", 0, false},
399 { "spdif_out", "pll_a_out0", 0, false},
400 { "sdmmc1", "clk_m", 48000000, true },
401 { "sdmmc2", "clk_m", 48000000, true },
402 { "sdmmc4", "clk_m", 48000000, true },
403 { "ndflash", "pll_p", 108000000, true},
404 { "pwm", "clk_32k", 32768, false},
405 { NULL, NULL, 0, 0},
406};
407
408
409static struct tegra_sdhci_platform_data sdhci_pdata1 = {
410 .cd_gpio = -1,
411 .wp_gpio = -1,
412 .power_gpio = -1,
413};
414
415static struct tegra_sdhci_platform_data sdhci_pdata2 = {
416 .cd_gpio = TEGRA_GPIO_SD2_CD,
417 .wp_gpio = TEGRA_GPIO_SD2_WP,
418 .power_gpio = TEGRA_GPIO_SD2_POWER,
419};
420
421static struct tegra_sdhci_platform_data sdhci_pdata4 = {
422 .cd_gpio = TEGRA_GPIO_SD4_CD,
423 .wp_gpio = TEGRA_GPIO_SD4_WP,
424 .power_gpio = TEGRA_GPIO_SD4_POWER,
425 .is_8bit = 1,
426};
427
428static int __init harmony_wifi_init(void)
429{
430 int gpio_pwr, gpio_rst;
431
432 if (!machine_is_harmony())
433 return 0;
434
435 /* WLAN - Power up (low) and Reset (low) */
436 gpio_pwr = gpio_request(TEGRA_GPIO_WLAN_PWR_LOW, "wlan_pwr");
437 gpio_rst = gpio_request(TEGRA_GPIO_WLAN_RST_LOW, "wlan_rst");
438 if (gpio_pwr < 0 || gpio_rst < 0)
439 pr_warning("Unable to get gpio for WLAN Power and Reset\n");
440 else {
441
442 tegra_gpio_enable(TEGRA_GPIO_WLAN_PWR_LOW);
443 tegra_gpio_enable(TEGRA_GPIO_WLAN_RST_LOW);
444 /* toggle in this order as per spec */
445 gpio_direction_output(TEGRA_GPIO_WLAN_PWR_LOW, 0);
446 gpio_direction_output(TEGRA_GPIO_WLAN_RST_LOW, 0);
447 udelay(5);
448 gpio_direction_output(TEGRA_GPIO_WLAN_PWR_LOW, 1);
449 gpio_direction_output(TEGRA_GPIO_WLAN_RST_LOW, 1);
450 }
451
452 return 0;
453}
454
455/*
456 * subsys_initcall_sync is good synch point to call harmony_wifi_init
457 * This makes sure that the required regulators (LDO3
458 * supply of external PMU and 1.2V regulator) are properly enabled,
459 * and mmc driver has not yet probed for a device on SDIO bus.
460 */
461subsys_initcall_sync(harmony_wifi_init);
462
463static void __init tegra_harmony_init(void)
464{
465 tegra_clk_init_from_table(harmony_clk_init_table);
466
467 harmony_pinmux_init();
468
469 harmony_keys_init();
470
471 harmony_debug_uart_init();
472
473 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
474 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
475 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
476
477 tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata;
478
479 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
480 harmony_i2c_init();
481 harmony_regulator_init();
482 harmony_suspend_init();
483 harmony_panel_init();
484#ifdef CONFIG_KEYBOARD_TEGRA
485 harmony_kbc_init();
486#endif
487 harmony_pcie_init();
488}
489
490void __init tegra_harmony_reserve(void)
491{
492 if (memblock_reserve(0x0, 4096) < 0)
493 pr_warn("Cannot reserve first 4K of memory for safety\n");
494
495 tegra_reserve(SZ_128M, SZ_8M, SZ_16M);
496}
497
498MACHINE_START(HARMONY, "harmony")
499 .boot_params = 0x00000100,
500 .fixup = tegra_harmony_fixup,
501 .map_io = tegra_map_common_io,
502 .reserve = tegra_harmony_reserve,
503 .init_early = tegra_init_early,
504 .init_irq = tegra_init_irq,
505 .timer = &tegra_timer,
506 .init_machine = tegra_harmony_init,
507MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
new file mode 100644
index 00000000000..edd16166990
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -0,0 +1,53 @@
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#define HARMONY_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_))
21#define HARMONY_GPIO_WM8903(_x_) (HARMONY_GPIO_TPS6586X(4) + (_x_))
22
23#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
24#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
25#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PT3
26#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
27#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
28#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
29#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3
30#define TEGRA_GPIO_SPKR_EN HARMONY_GPIO_WM8903(2)
31#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
32#define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PX0
33#define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1
34/* fixed voltage regulator enable/mode gpios */
35#define TPS_GPIO_EN_1V5 (HARMONY_GPIO_TPS6586X(0))
36#define TPS_GPIO_EN_1V2 (HARMONY_GPIO_TPS6586X(1))
37#define TPS_GPIO_EN_1V05 (HARMONY_GPIO_TPS6586X(2))
38#define TPS_GPIO_MODE_1V05 (HARMONY_GPIO_TPS6586X(3))
39
40/* WLAN pwr and reset gpio */
41#define TEGRA_GPIO_WLAN_PWR_LOW TEGRA_GPIO_PK5
42#define TEGRA_GPIO_WLAN_RST_LOW TEGRA_GPIO_PK6
43
44#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2
45
46void harmony_pinmux_init(void);
47int harmony_regulator_init(void);
48int harmony_suspend_init(void);
49int harmony_panel_init(void);
50int harmony_kbc_init(void);
51int harmony_pcie_init(void);
52
53#endif
diff --git a/arch/arm/mach-tegra/board-info.c b/arch/arm/mach-tegra/board-info.c
new file mode 100644
index 00000000000..1bcd0d52bd2
--- /dev/null
+++ b/arch/arm/mach-tegra/board-info.c
@@ -0,0 +1,201 @@
1/*
2 * arch/arm/mach-tegra/board-info.c
3 *
4 * File to contain changes for sku id, serial id, chip id, etc.
5 *
6 * Copyright (c) 2010-2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/proc_fs.h>
24#include <linux/seq_file.h>
25#include "board.h"
26
27/* skuinfo is 18 character long xxx-xxxxx-xxxx-xxx
28 *so buffer size is set to 18+1 */
29#define SKUINFO_BUF_SIZE 19
30/* skuver is 2 character long XX so buffer size is set to 2+1 */
31#define SKUVER_BUF_SIZE 3
32
33/* prodinfo is 18 character long xxx-xxxxx-xxxx-xxx
34 * so buffer size is set to 18+1 */
35#define PRODINFO_BUF_SIZE 19
36/* prodver is 2 character long XX so buffer size is set to 2+1 */
37#define PRODVER_BUF_SIZE 3
38
39static unsigned int board_serial_low;
40static unsigned int board_serial_high;
41static char prodinfo_buffer[PRODINFO_BUF_SIZE];
42static char prodver_buffer[PRODVER_BUF_SIZE];
43static char skuinfo_buffer[SKUINFO_BUF_SIZE];
44static char skuver_buffer[SKUVER_BUF_SIZE];
45
46static int __init sku_info_setup(char *line)
47{
48 memcpy(skuinfo_buffer, line, SKUINFO_BUF_SIZE);
49 return 1;
50}
51
52__setup("nvsku=", sku_info_setup);
53
54static int __init sku_ver_setup(char *line)
55{
56 memcpy(skuver_buffer, line, SKUVER_BUF_SIZE);
57 return 1;
58}
59
60__setup("SkuVer=", sku_ver_setup);
61
62static int __init prod_info_setup(char *line)
63{
64 memcpy(prodinfo_buffer, line, PRODINFO_BUF_SIZE);
65 return 1;
66}
67
68__setup("ProdInfo=", prod_info_setup);
69
70static int __init prod_ver_setup(char *line)
71{
72 memcpy(prodver_buffer, line, PRODVER_BUF_SIZE);
73 return 1;
74}
75
76__setup("ProdVer=", prod_ver_setup);
77
78static int read_skuinfo_proc_show(struct seq_file *m, void *v)
79{
80 seq_printf(m, "%s\n", skuinfo_buffer);
81 return 0;
82}
83
84static int read_skuinfo_proc_open(struct inode *inode, struct file *file)
85{
86 return single_open(file, read_skuinfo_proc_show, NULL);
87}
88
89static const struct file_operations read_skuinfo_proc_fops = {
90 .open = read_skuinfo_proc_open,
91 .read = seq_read,
92 .llseek = seq_lseek,
93 .release = single_release,
94};
95
96static int read_skuver_proc_show(struct seq_file *m, void *v)
97{
98 seq_printf(m, "%s\n", skuver_buffer);
99 return 0;
100}
101
102static int read_skuver_proc_open(struct inode *inode, struct file *file)
103{
104 return single_open(file, read_skuver_proc_show, NULL);
105}
106
107static const struct file_operations read_skuver_proc_fops = {
108 .open = read_skuver_proc_open,
109 .read = seq_read,
110 .llseek = seq_lseek,
111 .release = single_release,
112};
113
114static int read_serialinfo_proc_show(struct seq_file *m, void *v)
115{
116 seq_printf(m, "%013llu\n",
117 (((unsigned long long int)board_serial_high) << 32) |
118 board_serial_low);
119 return 0;
120}
121
122static int read_serialinfo_proc_open(struct inode *inode, struct file *file)
123{
124 return single_open(file, read_serialinfo_proc_show, NULL);
125}
126
127static const struct file_operations read_serialinfo_proc_fops = {
128 .open = read_serialinfo_proc_open,
129 .read = seq_read,
130 .llseek = seq_lseek,
131 .release = single_release,
132};
133
134static int read_prodinfo_proc_show(struct seq_file *m, void *v)
135{
136 seq_printf(m, "%s\n", prodinfo_buffer);
137 return 0;
138}
139
140static int read_prodinfo_proc_open(struct inode *inode, struct file *file)
141{
142 return single_open(file, read_prodinfo_proc_show, NULL);
143}
144
145static const struct file_operations read_prodinfo_proc_fops = {
146 .open = read_prodinfo_proc_open,
147 .read = seq_read,
148 .llseek = seq_lseek,
149 .release = single_release,
150};
151
152static int read_prodver_proc_show(struct seq_file *m, void *v)
153{
154 seq_printf(m, "%s\n", prodver_buffer);
155 return 0;
156}
157
158static int read_prodver_proc_open(struct inode *inode, struct file *file)
159{
160 return single_open(file, read_prodver_proc_show, NULL);
161}
162
163static const struct file_operations read_prodver_proc_fops = {
164 .open = read_prodver_proc_open,
165 .read = seq_read,
166 .llseek = seq_lseek,
167 .release = single_release,
168};
169
170int __init tegra_init_board_info(void)
171{
172 board_serial_low = system_serial_low;
173 board_serial_high = system_serial_high;
174
175 if (!proc_create("board_serial", 0, NULL, &read_serialinfo_proc_fops)) {
176 printk(KERN_ERR "Can't create proc entry for board_serial!\n");
177 return -1;
178 }
179
180 if (!proc_create("skuinfo", 0, NULL, &read_skuinfo_proc_fops)) {
181 printk(KERN_ERR "Can't create proc entry for skuinfo!\n");
182 return -1;
183 }
184
185 if (!proc_create("skuver", 0, NULL, &read_skuver_proc_fops)) {
186 printk(KERN_ERR "Can't create proc entry for skuver!\n");
187 return -1;
188 }
189
190 if (!proc_create("prodinfo", 0, NULL, &read_prodinfo_proc_fops)) {
191 printk(KERN_ERR "Can't create proc entry for prodinfo!\n");
192 return -1;
193 }
194
195 if (!proc_create("prodver", 0, NULL, &read_prodver_proc_fops)) {
196 printk(KERN_ERR "Can't create proc entry for prodver!\n");
197 return -1;
198 }
199
200 return 0;
201}
diff --git a/arch/arm/mach-tegra/board-kai-kbc.c b/arch/arm/mach-tegra/board-kai-kbc.c
new file mode 100644
index 00000000000..5c528640279
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-kbc.c
@@ -0,0 +1,103 @@
1/*
2 * arch/arm/mach-tegra/board-kai-kbc.c
3 * Keys configuration for Nvidia tegra3 kai platform.
4 *
5 * Copyright (C) 2012 NVIDIA, Inc.
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
19 * 02111-1307, USA
20 */
21
22#include <linux/kernel.h>
23#include <linux/platform_device.h>
24#include <linux/input.h>
25#include <linux/device.h>
26#include <linux/gpio.h>
27#include <linux/gpio_keys.h>
28#include <linux/mfd/max77663-core.h>
29#include <linux/gpio_scrollwheel.h>
30
31#include <mach/irqs.h>
32#include <mach/io.h>
33#include <mach/iomap.h>
34#include <mach/kbc.h>
35#include "board.h"
36#include "board-kai.h"
37
38#include "gpio-names.h"
39#include "devices.h"
40
41#define GPIO_KEY(_id, _gpio, _iswake) \
42 { \
43 .code = _id, \
44 .gpio = TEGRA_GPIO_##_gpio, \
45 .active_low = 1, \
46 .desc = #_id, \
47 .type = EV_KEY, \
48 .wakeup = _iswake, \
49 .debounce_interval = 10, \
50 }
51
52#define GPIO_IKEY(_id, _irq, _iswake, _deb) \
53 { \
54 .code = _id, \
55 .gpio = -1, \
56 .irq = _irq, \
57 .desc = #_id, \
58 .type = EV_KEY, \
59 .wakeup = _iswake, \
60 .debounce_interval = _deb, \
61 }
62
63static struct gpio_keys_button kai_keys[] = {
64 [0] = GPIO_KEY(KEY_MENU, PR2, 0),
65 [1] = GPIO_KEY(KEY_BACK, PQ1, 0),
66 [2] = GPIO_KEY(KEY_HOME, PQ0, 0),
67 [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
68 [4] = GPIO_KEY(KEY_VOLUMEUP, PR1, 0),
69 [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR0, 0),
70 [6] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_FALLING, 1, 100),
71 [7] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_1SEC, 1, 3000),
72};
73
74static struct gpio_keys_platform_data kai_keys_platform_data = {
75 .buttons = kai_keys,
76 .nbuttons = ARRAY_SIZE(kai_keys),
77};
78
79static struct platform_device kai_keys_device = {
80 .name = "gpio-keys",
81 .id = 0,
82 .dev = {
83 .platform_data = &kai_keys_platform_data,
84 },
85};
86
87int __init kai_keys_init(void)
88{
89 int i;
90
91 pr_info("Registering gpio keys\n");
92
93 /* Enable gpio mode for other pins */
94 for (i = 0; i < kai_keys_platform_data.nbuttons; i++) {
95 if (kai_keys_platform_data.buttons[i].gpio < 0)
96 continue;
97 tegra_gpio_enable(kai_keys_platform_data.buttons[i].gpio);
98 }
99
100 platform_device_register(&kai_keys_device);
101
102 return 0;
103}
diff --git a/arch/arm/mach-tegra/board-kai-memory.c b/arch/arm/mach-tegra/board-kai-memory.c
new file mode 100644
index 00000000000..5a22cebcfff
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-memory.c
@@ -0,0 +1,877 @@
1/*
2 * Copyright (C) 2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22#include "board.h"
23#include "board-kai.h"
24#include "tegra3_emc.h"
25#include "fuse.h"
26
27
28static const struct tegra_emc_table kai_emc_tables_h5tc4g[] = {
29 {
30 0x32, /* Rev 3.2 */
31 12750, /* SDRAM frequency */
32 {
33 0x00000000, /* EMC_RC */
34 0x00000003, /* EMC_RFC */
35 0x00000000, /* EMC_RAS */
36 0x00000000, /* EMC_RP */
37 0x00000002, /* EMC_R2W */
38 0x0000000a, /* EMC_W2R */
39 0x00000005, /* EMC_R2P */
40 0x0000000b, /* EMC_W2P */
41 0x00000000, /* EMC_RD_RCD */
42 0x00000000, /* EMC_WR_RCD */
43 0x00000003, /* EMC_RRD */
44 0x00000001, /* EMC_REXT */
45 0x00000000, /* EMC_WEXT */
46 0x00000005, /* EMC_WDV */
47 0x00000005, /* EMC_QUSE */
48 0x00000004, /* EMC_QRST */
49 0x00000009, /* EMC_QSAFE */
50 0x0000000b, /* EMC_RDV */
51 0x00000060, /* EMC_REFRESH */
52 0x00000000, /* EMC_BURST_REFRESH_NUM */
53 0x00000018, /* EMC_PRE_REFRESH_REQ_CNT */
54 0x00000002, /* EMC_PDEX2WR */
55 0x00000002, /* EMC_PDEX2RD */
56 0x00000001, /* EMC_PCHG2PDEN */
57 0x00000000, /* EMC_ACT2PDEN */
58 0x00000007, /* EMC_AR2PDEN */
59 0x0000000f, /* EMC_RW2PDEN */
60 0x00000005, /* EMC_TXSR */
61 0x00000005, /* EMC_TXSRDLL */
62 0x00000004, /* EMC_TCKE */
63 0x00000001, /* EMC_TFAW */
64 0x00000000, /* EMC_TRPAB */
65 0x00000004, /* EMC_TCLKSTABLE */
66 0x00000005, /* EMC_TCLKSTOP */
67 0x00000064, /* EMC_TREFBW */
68 0x00000006, /* EMC_QUSE_EXTRA */
69 0x00000004, /* EMC_FBIO_CFG6 */
70 0x00000000, /* EMC_ODT_WRITE */
71 0x00000000, /* EMC_ODT_READ */
72 0x00004288, /* EMC_FBIO_CFG5 */
73 0x007800a4, /* EMC_CFG_DIG_DLL */
74 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
75 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
76 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
77 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
78 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
79 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
80 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
81 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
82 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
83 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
84 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
85 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
86 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
87 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
88 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
89 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
90 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
91 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
92 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
93 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
94 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
95 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
96 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
97 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
98 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
99 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
100 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
101 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
102 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
103 0x000002a0, /* EMC_XM2CMDPADCTRL */
104 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
105 0x00000000, /* EMC_XM2DQPADCTRL2 */
106 0x77fff884, /* EMC_XM2CLKPADCTRL */
107 0x01f1f108, /* EMC_XM2COMPPADCTRL */
108 0x05057404, /* EMC_XM2VTTGENPADCTRL */
109 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
110 0x08000168, /* EMC_XM2QUSEPADCTRL */
111 0x08000000, /* EMC_XM2DQSPADCTRL3 */
112 0x00000802, /* EMC_CTT_TERM_CTRL */
113 0x00000000, /* EMC_ZCAL_INTERVAL */
114 0x00000040, /* EMC_ZCAL_WAIT_CNT */
115 0x000c000c, /* EMC_MRS_WAIT_CNT */
116 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
117 0x00000000, /* EMC_CTT */
118 0x00000000, /* EMC_CTT_DURATION */
119 0x800001c5, /* EMC_DYN_SELF_REF_CONTROL */
120 0x00050001, /* MC_EMEM_ARB_CFG */
121 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
122 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
123 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
124 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
125 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
126 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
127 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
128 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
129 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
130 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
131 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
132 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
133 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
134 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
135 0x000a0502, /* MC_EMEM_ARB_DA_COVERS */
136 0x77e30303, /* MC_EMEM_ARB_MISC0 */
137 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
138 0xe8000000, /* EMC_FBIO_SPARE */
139 0xff00ff00, /* EMC_CFG_RSV */
140 },
141 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
142 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
143 0x00000001, /* EMC_CFG.PERIODIC_QRST */
144 0x80001221, /* Mode Register 0 */
145 0x80100003, /* Mode Register 1 */
146 0x80200008, /* Mode Register 2 */
147 0x00000001, /* EMC_CFG.DYN_SELF_REF */
148 },
149 {
150 0x32, /* Rev 3.2 */
151 25500, /* SDRAM frequency */
152 {
153 0x00000001, /* EMC_RC */
154 0x00000007, /* EMC_RFC */
155 0x00000000, /* EMC_RAS */
156 0x00000000, /* EMC_RP */
157 0x00000002, /* EMC_R2W */
158 0x0000000a, /* EMC_W2R */
159 0x00000005, /* EMC_R2P */
160 0x0000000b, /* EMC_W2P */
161 0x00000000, /* EMC_RD_RCD */
162 0x00000000, /* EMC_WR_RCD */
163 0x00000003, /* EMC_RRD */
164 0x00000001, /* EMC_REXT */
165 0x00000000, /* EMC_WEXT */
166 0x00000005, /* EMC_WDV */
167 0x00000005, /* EMC_QUSE */
168 0x00000004, /* EMC_QRST */
169 0x00000009, /* EMC_QSAFE */
170 0x0000000b, /* EMC_RDV */
171 0x000000c0, /* EMC_REFRESH */
172 0x00000000, /* EMC_BURST_REFRESH_NUM */
173 0x00000030, /* EMC_PRE_REFRESH_REQ_CNT */
174 0x00000002, /* EMC_PDEX2WR */
175 0x00000002, /* EMC_PDEX2RD */
176 0x00000001, /* EMC_PCHG2PDEN */
177 0x00000000, /* EMC_ACT2PDEN */
178 0x00000007, /* EMC_AR2PDEN */
179 0x0000000f, /* EMC_RW2PDEN */
180 0x00000008, /* EMC_TXSR */
181 0x00000008, /* EMC_TXSRDLL */
182 0x00000004, /* EMC_TCKE */
183 0x00000002, /* EMC_TFAW */
184 0x00000000, /* EMC_TRPAB */
185 0x00000004, /* EMC_TCLKSTABLE */
186 0x00000005, /* EMC_TCLKSTOP */
187 0x000000c7, /* EMC_TREFBW */
188 0x00000006, /* EMC_QUSE_EXTRA */
189 0x00000004, /* EMC_FBIO_CFG6 */
190 0x00000000, /* EMC_ODT_WRITE */
191 0x00000000, /* EMC_ODT_READ */
192 0x00004288, /* EMC_FBIO_CFG5 */
193 0x007800a4, /* EMC_CFG_DIG_DLL */
194 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
195 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
196 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
197 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
198 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
199 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
200 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
201 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
202 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
203 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
204 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
205 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
206 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
207 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
208 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
209 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
210 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
211 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
212 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
213 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
214 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
215 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
216 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
217 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
218 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
219 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
220 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
221 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
222 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
223 0x000002a0, /* EMC_XM2CMDPADCTRL */
224 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
225 0x00000000, /* EMC_XM2DQPADCTRL2 */
226 0x77fff884, /* EMC_XM2CLKPADCTRL */
227 0x01f1f108, /* EMC_XM2COMPPADCTRL */
228 0x05057404, /* EMC_XM2VTTGENPADCTRL */
229 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
230 0x08000168, /* EMC_XM2QUSEPADCTRL */
231 0x08000000, /* EMC_XM2DQSPADCTRL3 */
232 0x00000802, /* EMC_CTT_TERM_CTRL */
233 0x00000000, /* EMC_ZCAL_INTERVAL */
234 0x00000040, /* EMC_ZCAL_WAIT_CNT */
235 0x000c000c, /* EMC_MRS_WAIT_CNT */
236 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
237 0x00000000, /* EMC_CTT */
238 0x00000000, /* EMC_CTT_DURATION */
239 0x80000287, /* EMC_DYN_SELF_REF_CONTROL */
240 0x00020001, /* MC_EMEM_ARB_CFG */
241 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
242 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
243 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
244 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
245 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
246 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
247 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
248 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
249 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
250 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
251 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
252 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
253 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
254 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
255 0x000a0502, /* MC_EMEM_ARB_DA_COVERS */
256 0x75e30303, /* MC_EMEM_ARB_MISC0 */
257 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
258 0xe8000000, /* EMC_FBIO_SPARE */
259 0xff00ff00, /* EMC_CFG_RSV */
260 },
261 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
262 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
263 0x00000001, /* EMC_CFG.PERIODIC_QRST */
264 0x80001221, /* Mode Register 0 */
265 0x80100003, /* Mode Register 1 */
266 0x80200008, /* Mode Register 2 */
267 0x00000001, /* EMC_CFG.DYN_SELF_REF */
268 },
269 {
270 0x32, /* Rev 3.2 */
271 51000, /* SDRAM frequency */
272 {
273 0x00000002, /* EMC_RC */
274 0x0000000f, /* EMC_RFC */
275 0x00000001, /* EMC_RAS */
276 0x00000000, /* EMC_RP */
277 0x00000002, /* EMC_R2W */
278 0x0000000a, /* EMC_W2R */
279 0x00000005, /* EMC_R2P */
280 0x0000000b, /* EMC_W2P */
281 0x00000000, /* EMC_RD_RCD */
282 0x00000000, /* EMC_WR_RCD */
283 0x00000003, /* EMC_RRD */
284 0x00000001, /* EMC_REXT */
285 0x00000000, /* EMC_WEXT */
286 0x00000005, /* EMC_WDV */
287 0x00000005, /* EMC_QUSE */
288 0x00000004, /* EMC_QRST */
289 0x00000009, /* EMC_QSAFE */
290 0x0000000b, /* EMC_RDV */
291 0x00000181, /* EMC_REFRESH */
292 0x00000000, /* EMC_BURST_REFRESH_NUM */
293 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
294 0x00000002, /* EMC_PDEX2WR */
295 0x00000002, /* EMC_PDEX2RD */
296 0x00000001, /* EMC_PCHG2PDEN */
297 0x00000000, /* EMC_ACT2PDEN */
298 0x00000007, /* EMC_AR2PDEN */
299 0x0000000f, /* EMC_RW2PDEN */
300 0x00000010, /* EMC_TXSR */
301 0x00000010, /* EMC_TXSRDLL */
302 0x00000004, /* EMC_TCKE */
303 0x00000003, /* EMC_TFAW */
304 0x00000000, /* EMC_TRPAB */
305 0x00000004, /* EMC_TCLKSTABLE */
306 0x00000005, /* EMC_TCLKSTOP */
307 0x0000018e, /* EMC_TREFBW */
308 0x00000006, /* EMC_QUSE_EXTRA */
309 0x00000004, /* EMC_FBIO_CFG6 */
310 0x00000000, /* EMC_ODT_WRITE */
311 0x00000000, /* EMC_ODT_READ */
312 0x00004288, /* EMC_FBIO_CFG5 */
313 0x007800a4, /* EMC_CFG_DIG_DLL */
314 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
315 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
316 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
317 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
318 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
319 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
320 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
321 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
322 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
323 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
324 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
325 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
326 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
327 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
328 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
329 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
330 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
331 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
332 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
333 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
334 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
335 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
336 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
337 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
338 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
339 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
340 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
341 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
342 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
343 0x000002a0, /* EMC_XM2CMDPADCTRL */
344 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
345 0x00000000, /* EMC_XM2DQPADCTRL2 */
346 0x77fff884, /* EMC_XM2CLKPADCTRL */
347 0x01f1f108, /* EMC_XM2COMPPADCTRL */
348 0x05057404, /* EMC_XM2VTTGENPADCTRL */
349 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
350 0x08000168, /* EMC_XM2QUSEPADCTRL */
351 0x08000000, /* EMC_XM2DQSPADCTRL3 */
352 0x00000802, /* EMC_CTT_TERM_CTRL */
353 0x00000000, /* EMC_ZCAL_INTERVAL */
354 0x00000040, /* EMC_ZCAL_WAIT_CNT */
355 0x000c000c, /* EMC_MRS_WAIT_CNT */
356 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
357 0x00000000, /* EMC_CTT */
358 0x00000000, /* EMC_CTT_DURATION */
359 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
360 0x00010001, /* MC_EMEM_ARB_CFG */
361 0xc000000a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
362 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
363 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
364 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
365 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
366 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
367 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
368 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
369 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
370 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
371 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
372 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
373 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
374 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
375 0x000a0502, /* MC_EMEM_ARB_DA_COVERS */
376 0x74e30303, /* MC_EMEM_ARB_MISC0 */
377 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
378 0xe8000000, /* EMC_FBIO_SPARE */
379 0xff00ff00, /* EMC_CFG_RSV */
380 },
381 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
382 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
383 0x00000001, /* EMC_CFG.PERIODIC_QRST */
384 0x80001221, /* Mode Register 0 */
385 0x80100003, /* Mode Register 1 */
386 0x80200008, /* Mode Register 2 */
387 0x00000001, /* EMC_CFG.DYN_SELF_REF */
388 },
389 {
390 0x32, /* Rev 3.2 */
391 102000, /* SDRAM frequency */
392 {
393 0x00000005, /* EMC_RC */
394 0x0000001e, /* EMC_RFC */
395 0x00000003, /* EMC_RAS */
396 0x00000001, /* EMC_RP */
397 0x00000002, /* EMC_R2W */
398 0x0000000a, /* EMC_W2R */
399 0x00000005, /* EMC_R2P */
400 0x0000000b, /* EMC_W2P */
401 0x00000001, /* EMC_RD_RCD */
402 0x00000001, /* EMC_WR_RCD */
403 0x00000003, /* EMC_RRD */
404 0x00000001, /* EMC_REXT */
405 0x00000000, /* EMC_WEXT */
406 0x00000005, /* EMC_WDV */
407 0x00000005, /* EMC_QUSE */
408 0x00000004, /* EMC_QRST */
409 0x00000009, /* EMC_QSAFE */
410 0x0000000b, /* EMC_RDV */
411 0x00000303, /* EMC_REFRESH */
412 0x00000000, /* EMC_BURST_REFRESH_NUM */
413 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
414 0x00000002, /* EMC_PDEX2WR */
415 0x00000002, /* EMC_PDEX2RD */
416 0x00000001, /* EMC_PCHG2PDEN */
417 0x00000000, /* EMC_ACT2PDEN */
418 0x00000007, /* EMC_AR2PDEN */
419 0x0000000f, /* EMC_RW2PDEN */
420 0x00000020, /* EMC_TXSR */
421 0x00000020, /* EMC_TXSRDLL */
422 0x00000004, /* EMC_TCKE */
423 0x00000005, /* EMC_TFAW */
424 0x00000000, /* EMC_TRPAB */
425 0x00000004, /* EMC_TCLKSTABLE */
426 0x00000005, /* EMC_TCLKSTOP */
427 0x0000031c, /* EMC_TREFBW */
428 0x00000006, /* EMC_QUSE_EXTRA */
429 0x00000004, /* EMC_FBIO_CFG6 */
430 0x00000000, /* EMC_ODT_WRITE */
431 0x00000000, /* EMC_ODT_READ */
432 0x00004288, /* EMC_FBIO_CFG5 */
433 0x007800a4, /* EMC_CFG_DIG_DLL */
434 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
435 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
436 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
437 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
438 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
439 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
440 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
441 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
442 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
443 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
444 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
445 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
446 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
447 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
448 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
449 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
450 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
451 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
452 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
453 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
454 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
455 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
456 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
457 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
458 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
459 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
460 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
461 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
462 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
463 0x000002a0, /* EMC_XM2CMDPADCTRL */
464 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
465 0x00000000, /* EMC_XM2DQPADCTRL2 */
466 0x77fff884, /* EMC_XM2CLKPADCTRL */
467 0x01f1f108, /* EMC_XM2COMPPADCTRL */
468 0x05057404, /* EMC_XM2VTTGENPADCTRL */
469 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
470 0x08000168, /* EMC_XM2QUSEPADCTRL */
471 0x08000000, /* EMC_XM2DQSPADCTRL3 */
472 0x00000802, /* EMC_CTT_TERM_CTRL */
473 0x00000000, /* EMC_ZCAL_INTERVAL */
474 0x00000040, /* EMC_ZCAL_WAIT_CNT */
475 0x000c000c, /* EMC_MRS_WAIT_CNT */
476 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
477 0x00000000, /* EMC_CTT */
478 0x00000000, /* EMC_CTT_DURATION */
479 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
480 0x00000001, /* MC_EMEM_ARB_CFG */
481 0xc0000013, /* MC_EMEM_ARB_OUTSTANDING_REQ */
482 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
483 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
484 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
485 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
486 0x00000002, /* MC_EMEM_ARB_TIMING_FAW */
487 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
488 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
489 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
490 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
491 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
492 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
493 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
494 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
495 0x000a0503, /* MC_EMEM_ARB_DA_COVERS */
496 0x74430504, /* MC_EMEM_ARB_MISC0 */
497 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
498 0xe8000000, /* EMC_FBIO_SPARE */
499 0xff00ff00, /* EMC_CFG_RSV */
500 },
501 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
502 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
503 0x00000001, /* EMC_CFG.PERIODIC_QRST */
504 0x80001221, /* Mode Register 0 */
505 0x80100003, /* Mode Register 1 */
506 0x80200008, /* Mode Register 2 */
507 0x00000001, /* EMC_CFG.DYN_SELF_REF */
508 },
509 {
510 0x32, /* Rev 3.2 */
511 204000, /* SDRAM frequency */
512 {
513 0x0000000a, /* EMC_RC */
514 0x0000003d, /* EMC_RFC */
515 0x00000007, /* EMC_RAS */
516 0x00000002, /* EMC_RP */
517 0x00000002, /* EMC_R2W */
518 0x0000000a, /* EMC_W2R */
519 0x00000005, /* EMC_R2P */
520 0x0000000b, /* EMC_W2P */
521 0x00000002, /* EMC_RD_RCD */
522 0x00000002, /* EMC_WR_RCD */
523 0x00000003, /* EMC_RRD */
524 0x00000001, /* EMC_REXT */
525 0x00000000, /* EMC_WEXT */
526 0x00000005, /* EMC_WDV */
527 0x00000005, /* EMC_QUSE */
528 0x00000004, /* EMC_QRST */
529 0x00000009, /* EMC_QSAFE */
530 0x0000000b, /* EMC_RDV */
531 0x00000607, /* EMC_REFRESH */
532 0x00000000, /* EMC_BURST_REFRESH_NUM */
533 0x00000181, /* EMC_PRE_REFRESH_REQ_CNT */
534 0x00000002, /* EMC_PDEX2WR */
535 0x00000002, /* EMC_PDEX2RD */
536 0x00000001, /* EMC_PCHG2PDEN */
537 0x00000000, /* EMC_ACT2PDEN */
538 0x00000007, /* EMC_AR2PDEN */
539 0x0000000f, /* EMC_RW2PDEN */
540 0x00000040, /* EMC_TXSR */
541 0x00000040, /* EMC_TXSRDLL */
542 0x00000004, /* EMC_TCKE */
543 0x0000000a, /* EMC_TFAW */
544 0x00000000, /* EMC_TRPAB */
545 0x00000004, /* EMC_TCLKSTABLE */
546 0x00000005, /* EMC_TCLKSTOP */
547 0x00000638, /* EMC_TREFBW */
548 0x00000006, /* EMC_QUSE_EXTRA */
549 0x00000006, /* EMC_FBIO_CFG6 */
550 0x00000000, /* EMC_ODT_WRITE */
551 0x00000000, /* EMC_ODT_READ */
552 0x00004288, /* EMC_FBIO_CFG5 */
553 0x004400a4, /* EMC_CFG_DIG_DLL */
554 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
555 0x00080000, /* EMC_DLL_XFORM_DQS0 */
556 0x00080000, /* EMC_DLL_XFORM_DQS1 */
557 0x00080000, /* EMC_DLL_XFORM_DQS2 */
558 0x00080000, /* EMC_DLL_XFORM_DQS3 */
559 0x00080000, /* EMC_DLL_XFORM_DQS4 */
560 0x00080000, /* EMC_DLL_XFORM_DQS5 */
561 0x00080000, /* EMC_DLL_XFORM_DQS6 */
562 0x00080000, /* EMC_DLL_XFORM_DQS7 */
563 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
564 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
565 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
566 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
567 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
568 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
569 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
570 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
571 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
572 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
573 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
574 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
575 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
576 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
577 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
578 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
579 0x00080000, /* EMC_DLL_XFORM_DQ0 */
580 0x00080000, /* EMC_DLL_XFORM_DQ1 */
581 0x00080000, /* EMC_DLL_XFORM_DQ2 */
582 0x00080000, /* EMC_DLL_XFORM_DQ3 */
583 0x000002a0, /* EMC_XM2CMDPADCTRL */
584 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
585 0x00000000, /* EMC_XM2DQPADCTRL2 */
586 0x77fff884, /* EMC_XM2CLKPADCTRL */
587 0x01f1f108, /* EMC_XM2COMPPADCTRL */
588 0x05057404, /* EMC_XM2VTTGENPADCTRL */
589 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
590 0x08000168, /* EMC_XM2QUSEPADCTRL */
591 0x08000000, /* EMC_XM2DQSPADCTRL3 */
592 0x00000802, /* EMC_CTT_TERM_CTRL */
593 0x00020000, /* EMC_ZCAL_INTERVAL */
594 0x00000100, /* EMC_ZCAL_WAIT_CNT */
595 0x000c000c, /* EMC_MRS_WAIT_CNT */
596 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
597 0x00000000, /* EMC_CTT */
598 0x00000000, /* EMC_CTT_DURATION */
599 0x80000d22, /* EMC_DYN_SELF_REF_CONTROL */
600 0x00000003, /* MC_EMEM_ARB_CFG */
601 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
602 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
603 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
604 0x00000005, /* MC_EMEM_ARB_TIMING_RC */
605 0x00000002, /* MC_EMEM_ARB_TIMING_RAS */
606 0x00000004, /* MC_EMEM_ARB_TIMING_FAW */
607 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
608 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
609 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
610 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
611 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
612 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
613 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
614 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
615 0x000a0505, /* MC_EMEM_ARB_DA_COVERS */
616 0x74040a06, /* MC_EMEM_ARB_MISC0 */
617 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
618 0xe8000000, /* EMC_FBIO_SPARE */
619 0xff00ff00, /* EMC_CFG_RSV */
620 },
621 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
622 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
623 0x00000001, /* EMC_CFG.PERIODIC_QRST */
624 0x80001221, /* Mode Register 0 */
625 0x80100003, /* Mode Register 1 */
626 0x80200008, /* Mode Register 2 */
627 0x00000001, /* EMC_CFG.DYN_SELF_REF */
628 },
629 {
630 0x32, /* Rev 3.2 */
631 333500, /* SDRAM frequency */
632 {
633 0x0000000f, /* EMC_RC */
634 0x00000063, /* EMC_RFC */
635 0x0000000a, /* EMC_RAS */
636 0x00000003, /* EMC_RP */
637 0x00000003, /* EMC_R2W */
638 0x00000008, /* EMC_W2R */
639 0x00000002, /* EMC_R2P */
640 0x00000009, /* EMC_W2P */
641 0x00000003, /* EMC_RD_RCD */
642 0x00000003, /* EMC_WR_RCD */
643 0x00000002, /* EMC_RRD */
644 0x00000001, /* EMC_REXT */
645 0x00000000, /* EMC_WEXT */
646 0x00000004, /* EMC_WDV */
647 0x00000006, /* EMC_QUSE */
648 0x00000004, /* EMC_QRST */
649 0x0000000a, /* EMC_QSAFE */
650 0x0000000c, /* EMC_RDV */
651 0x000009e9, /* EMC_REFRESH */
652 0x00000000, /* EMC_BURST_REFRESH_NUM */
653 0x0000027a, /* EMC_PRE_REFRESH_REQ_CNT */
654 0x00000001, /* EMC_PDEX2WR */
655 0x00000008, /* EMC_PDEX2RD */
656 0x00000001, /* EMC_PCHG2PDEN */
657 0x00000000, /* EMC_ACT2PDEN */
658 0x00000007, /* EMC_AR2PDEN */
659 0x0000000e, /* EMC_RW2PDEN */
660 0x00000068, /* EMC_TXSR */
661 0x00000200, /* EMC_TXSRDLL */
662 0x00000004, /* EMC_TCKE */
663 0x0000000f, /* EMC_TFAW */
664 0x00000000, /* EMC_TRPAB */
665 0x00000004, /* EMC_TCLKSTABLE */
666 0x00000005, /* EMC_TCLKSTOP */
667 0x00000a2a, /* EMC_TREFBW */
668 0x00000000, /* EMC_QUSE_EXTRA */
669 0x00000006, /* EMC_FBIO_CFG6 */
670 0x00000000, /* EMC_ODT_WRITE */
671 0x00000000, /* EMC_ODT_READ */
672 0x00007088, /* EMC_FBIO_CFG5 */
673 0x002600a4, /* EMC_CFG_DIG_DLL */
674 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
675 0x00014000, /* EMC_DLL_XFORM_DQS0 */
676 0x00014000, /* EMC_DLL_XFORM_DQS1 */
677 0x00014000, /* EMC_DLL_XFORM_DQS2 */
678 0x00014000, /* EMC_DLL_XFORM_DQS3 */
679 0x00014000, /* EMC_DLL_XFORM_DQS4 */
680 0x00014000, /* EMC_DLL_XFORM_DQS5 */
681 0x00014000, /* EMC_DLL_XFORM_DQS6 */
682 0x00014000, /* EMC_DLL_XFORM_DQS7 */
683 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
684 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
685 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
686 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
687 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
688 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
689 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
690 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
691 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
692 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
693 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
694 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
695 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
696 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
697 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
698 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
699 0x00020000, /* EMC_DLL_XFORM_DQ0 */
700 0x00020000, /* EMC_DLL_XFORM_DQ1 */
701 0x00020000, /* EMC_DLL_XFORM_DQ2 */
702 0x00020000, /* EMC_DLL_XFORM_DQ3 */
703 0x000002a0, /* EMC_XM2CMDPADCTRL */
704 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
705 0x00000000, /* EMC_XM2DQPADCTRL2 */
706 0x77fff884, /* EMC_XM2CLKPADCTRL */
707 0x01f1f508, /* EMC_XM2COMPPADCTRL */
708 0x05057404, /* EMC_XM2VTTGENPADCTRL */
709 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
710 0x080001e8, /* EMC_XM2QUSEPADCTRL */
711 0x08000021, /* EMC_XM2DQSPADCTRL3 */
712 0x00000802, /* EMC_CTT_TERM_CTRL */
713 0x00020000, /* EMC_ZCAL_INTERVAL */
714 0x00000100, /* EMC_ZCAL_WAIT_CNT */
715 0x015c000c, /* EMC_MRS_WAIT_CNT */
716 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
717 0x00000000, /* EMC_CTT */
718 0x00000000, /* EMC_CTT_DURATION */
719 0x800014d4, /* EMC_DYN_SELF_REF_CONTROL */
720 0x00000005, /* MC_EMEM_ARB_CFG */
721 0x8000003d, /* MC_EMEM_ARB_OUTSTANDING_REQ */
722 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
723 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
724 0x00000008, /* MC_EMEM_ARB_TIMING_RC */
725 0x00000004, /* MC_EMEM_ARB_TIMING_RAS */
726 0x00000007, /* MC_EMEM_ARB_TIMING_FAW */
727 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
728 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
729 0x00000007, /* MC_EMEM_ARB_TIMING_WAP2PRE */
730 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
731 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
732 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
733 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
734 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
735 0x000b0608, /* MC_EMEM_ARB_DA_COVERS */
736 0x70850f09, /* MC_EMEM_ARB_MISC0 */
737 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
738 0xe8000000, /* EMC_FBIO_SPARE */
739 0xff00ff89, /* EMC_CFG_RSV */
740 },
741 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
742 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
743 0x00000000, /* EMC_CFG.PERIODIC_QRST */
744 0x80000321, /* Mode Register 0 */
745 0x80100002, /* Mode Register 1 */
746 0x80200000, /* Mode Register 2 */
747 0x00000000, /* EMC_CFG.DYN_SELF_REF */
748 },
749 {
750 0x32, /* Rev 3.2 */
751 667000, /* SDRAM frequency */
752 {
753 0x00000020, /* EMC_RC */
754 0x000000c7, /* EMC_RFC */
755 0x00000017, /* EMC_RAS */
756 0x00000007, /* EMC_RP */
757 0x00000005, /* EMC_R2W */
758 0x0000000c, /* EMC_W2R */
759 0x00000003, /* EMC_R2P */
760 0x00000011, /* EMC_W2P */
761 0x00000007, /* EMC_RD_RCD */
762 0x00000007, /* EMC_WR_RCD */
763 0x00000002, /* EMC_RRD */
764 0x00000001, /* EMC_REXT */
765 0x00000000, /* EMC_WEXT */
766 0x00000007, /* EMC_WDV */
767 0x0000000a, /* EMC_QUSE */
768 0x00000009, /* EMC_QRST */
769 0x0000000d, /* EMC_QSAFE */
770 0x00000012, /* EMC_RDV */
771 0x00001412, /* EMC_REFRESH */
772 0x00000000, /* EMC_BURST_REFRESH_NUM */
773 0x00000504, /* EMC_PRE_REFRESH_REQ_CNT */
774 0x00000002, /* EMC_PDEX2WR */
775 0x0000000e, /* EMC_PDEX2RD */
776 0x00000001, /* EMC_PCHG2PDEN */
777 0x00000000, /* EMC_ACT2PDEN */
778 0x0000000c, /* EMC_AR2PDEN */
779 0x00000016, /* EMC_RW2PDEN */
780 0x000000cf, /* EMC_TXSR */
781 0x00000200, /* EMC_TXSRDLL */
782 0x00000005, /* EMC_TCKE */
783 0x0000001f, /* EMC_TFAW */
784 0x00000000, /* EMC_TRPAB */
785 0x00000006, /* EMC_TCLKSTABLE */
786 0x00000007, /* EMC_TCLKSTOP */
787 0x00001453, /* EMC_TREFBW */
788 0x0000000b, /* EMC_QUSE_EXTRA */
789 0x00000006, /* EMC_FBIO_CFG6 */
790 0x00000000, /* EMC_ODT_WRITE */
791 0x00000000, /* EMC_ODT_READ */
792 0x00005088, /* EMC_FBIO_CFG5 */
793 0xf00b0191, /* EMC_CFG_DIG_DLL */
794 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
795 0x0000000a, /* EMC_DLL_XFORM_DQS0 */
796 0x0000000a, /* EMC_DLL_XFORM_DQS1 */
797 0x00000008, /* EMC_DLL_XFORM_DQS2 */
798 0x0000000a, /* EMC_DLL_XFORM_DQS3 */
799 0x0000000a, /* EMC_DLL_XFORM_DQS4 */
800 0x0000000a, /* EMC_DLL_XFORM_DQS5 */
801 0x00000008, /* EMC_DLL_XFORM_DQS6 */
802 0x0000000a, /* EMC_DLL_XFORM_DQS7 */
803 0x00018000, /* EMC_DLL_XFORM_QUSE0 */
804 0x00018000, /* EMC_DLL_XFORM_QUSE1 */
805 0x00018000, /* EMC_DLL_XFORM_QUSE2 */
806 0x00018000, /* EMC_DLL_XFORM_QUSE3 */
807 0x00018000, /* EMC_DLL_XFORM_QUSE4 */
808 0x00018000, /* EMC_DLL_XFORM_QUSE5 */
809 0x00018000, /* EMC_DLL_XFORM_QUSE6 */
810 0x00018000, /* EMC_DLL_XFORM_QUSE7 */
811 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
812 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
813 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
814 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
815 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
816 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
817 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
818 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
819 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
820 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
821 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
822 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
823 0x000002a0, /* EMC_XM2CMDPADCTRL */
824 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
825 0x22220000, /* EMC_XM2DQPADCTRL2 */
826 0x77fff884, /* EMC_XM2CLKPADCTRL */
827 0x01f1f501, /* EMC_XM2COMPPADCTRL */
828 0x07077404, /* EMC_XM2VTTGENPADCTRL */
829 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
830 0x080001e8, /* EMC_XM2QUSEPADCTRL */
831 0x06000021, /* EMC_XM2DQSPADCTRL3 */
832 0x00000802, /* EMC_CTT_TERM_CTRL */
833 0x00020000, /* EMC_ZCAL_INTERVAL */
834 0x00000100, /* EMC_ZCAL_WAIT_CNT */
835 0x00f8000c, /* EMC_MRS_WAIT_CNT */
836 0xa0f10202, /* EMC_AUTO_CAL_CONFIG */
837 0x00000000, /* EMC_CTT */
838 0x00000000, /* EMC_CTT_DURATION */
839 0x800028a5, /* EMC_DYN_SELF_REF_CONTROL */
840 0x0000000a, /* MC_EMEM_ARB_CFG */
841 0x80000079, /* MC_EMEM_ARB_OUTSTANDING_REQ */
842 0x00000003, /* MC_EMEM_ARB_TIMING_RCD */
843 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
844 0x00000010, /* MC_EMEM_ARB_TIMING_RC */
845 0x0000000b, /* MC_EMEM_ARB_TIMING_RAS */
846 0x0000000f, /* MC_EMEM_ARB_TIMING_FAW */
847 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
848 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
849 0x0000000b, /* MC_EMEM_ARB_TIMING_WAP2PRE */
850 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
851 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
852 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
853 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
854 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
855 0x00130b10, /* MC_EMEM_ARB_DA_COVERS */
856 0x70ea1f11, /* MC_EMEM_ARB_MISC0 */
857 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
858 0xe8000000, /* EMC_FBIO_SPARE */
859 0xff00ff49, /* EMC_CFG_RSV */
860 },
861 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
862 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
863 0x00000001, /* EMC_CFG.PERIODIC_QRST */
864 0x80000b71, /* Mode Register 0 */
865 0x80100002, /* Mode Register 1 */
866 0x80200018, /* Mode Register 2 */
867 0x00000000, /* EMC_CFG.DYN_SELF_REF */
868 },
869};
870
871int kai_emc_init(void)
872{
873 tegra_init_emc(kai_emc_tables_h5tc4g,
874 ARRAY_SIZE(kai_emc_tables_h5tc4g));
875
876 return 0;
877}
diff --git a/arch/arm/mach-tegra/board-kai-panel.c b/arch/arm/mach-tegra/board-kai-panel.c
new file mode 100644
index 00000000000..71e238fdcdc
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-panel.c
@@ -0,0 +1,740 @@
1/*
2 * arch/arm/mach-tegra/board-kai-panel.c
3 *
4 * Copyright (c) 2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/regulator/consumer.h>
23#include <linux/resource.h>
24#include <asm/mach-types.h>
25#include <linux/platform_device.h>
26#include <linux/earlysuspend.h>
27#include <linux/pwm_backlight.h>
28#include <asm/atomic.h>
29#include <linux/nvhost.h>
30#include <mach/nvmap.h>
31#include <mach/irqs.h>
32#include <mach/iomap.h>
33#include <mach/dc.h>
34#include <mach/fb.h>
35
36#include "board.h"
37#include "board-kai.h"
38#include "devices.h"
39#include "gpio-names.h"
40
41/* kai default display board pins */
42#define kai_lvds_avdd_en TEGRA_GPIO_PH6
43#define kai_lvds_stdby TEGRA_GPIO_PG5
44#define kai_lvds_rst TEGRA_GPIO_PG7
45#define kai_lvds_shutdown TEGRA_GPIO_PN6
46#define kai_lvds_rs TEGRA_GPIO_PV6
47#define kai_lvds_lr TEGRA_GPIO_PG1
48
49/* kai A00 display board pins */
50#define kai_lvds_rs_a00 TEGRA_GPIO_PH1
51
52/* common pins( backlight ) for all display boards */
53#define kai_bl_enb TEGRA_GPIO_PH3
54#define kai_bl_pwm TEGRA_GPIO_PH0
55#define kai_hdmi_hpd TEGRA_GPIO_PN7
56
57#ifdef CONFIG_TEGRA_DC
58static struct regulator *kai_hdmi_reg;
59static struct regulator *kai_hdmi_pll;
60static struct regulator *kai_hdmi_vddio;
61#endif
62
63static atomic_t sd_brightness = ATOMIC_INIT(255);
64
65static struct regulator *kai_lvds_reg;
66static struct regulator *kai_lvds_vdd_panel;
67
68static tegra_dc_bl_output kai_bl_output_measured = {
69 0, 1, 2, 3, 4, 5, 6, 7,
70 8, 9, 10, 11, 12, 13, 14, 15,
71 16, 17, 18, 19, 20, 21, 22, 23,
72 24, 25, 26, 27, 28, 29, 30, 31,
73 32, 33, 34, 35, 36, 37, 38, 39,
74 40, 41, 42, 43, 44, 45, 46, 47,
75 48, 49, 49, 50, 51, 52, 53, 54,
76 55, 56, 57, 58, 59, 60, 61, 62,
77 63, 64, 65, 66, 67, 68, 69, 70,
78 70, 72, 73, 74, 75, 76, 77, 78,
79 79, 80, 81, 82, 83, 84, 85, 86,
80 87, 88, 89, 90, 91, 92, 93, 94,
81 95, 96, 97, 98, 99, 100, 101, 102,
82 103, 104, 105, 106, 107, 108, 110, 111,
83 112, 113, 114, 115, 116, 117, 118, 119,
84 120, 121, 122, 123, 124, 124, 125, 126,
85 127, 128, 129, 130, 131, 132, 133, 133,
86 134, 135, 136, 137, 138, 139, 140, 141,
87 142, 143, 144, 145, 146, 147, 148, 148,
88 149, 150, 151, 152, 153, 154, 155, 156,
89 157, 158, 159, 160, 161, 162, 163, 164,
90 165, 166, 167, 168, 169, 170, 171, 172,
91 173, 174, 175, 176, 177, 179, 180, 181,
92 182, 184, 185, 186, 187, 188, 189, 190,
93 191, 192, 193, 194, 195, 196, 197, 198,
94 199, 200, 201, 202, 203, 204, 205, 206,
95 207, 208, 209, 211, 212, 213, 214, 215,
96 216, 217, 218, 219, 220, 221, 222, 223,
97 224, 225, 226, 227, 228, 229, 230, 231,
98 232, 233, 234, 235, 236, 237, 238, 239,
99 240, 241, 242, 243, 244, 245, 246, 247,
100 248, 249, 250, 251, 252, 253, 254, 255
101};
102
103static p_tegra_dc_bl_output bl_output;
104
105static int kai_backlight_init(struct device *dev)
106{
107 int ret;
108
109 bl_output = kai_bl_output_measured;
110
111 if (WARN_ON(ARRAY_SIZE(kai_bl_output_measured) != 256))
112 pr_err("bl_output array does not have 256 elements\n");
113
114 tegra_gpio_disable(kai_bl_pwm);
115
116 ret = gpio_request(kai_bl_enb, "backlight_enb");
117 if (ret < 0)
118 return ret;
119
120 ret = gpio_direction_output(kai_bl_enb, 1);
121 if (ret < 0)
122 gpio_free(kai_bl_enb);
123 else
124 tegra_gpio_enable(kai_bl_enb);
125
126 return ret;
127};
128
129static void kai_backlight_exit(struct device *dev)
130{
131 /* int ret; */
132 /*ret = gpio_request(kai_bl_enb, "backlight_enb");*/
133 gpio_set_value(kai_bl_enb, 0);
134 gpio_free(kai_bl_enb);
135 tegra_gpio_disable(kai_bl_enb);
136 return;
137}
138
139static int kai_backlight_notify(struct device *unused, int brightness)
140{
141 int cur_sd_brightness = atomic_read(&sd_brightness);
142
143 /* Set the backlight GPIO pin mode to 'backlight_enable' */
144 gpio_set_value(kai_bl_enb, !!brightness);
145
146 /* SD brightness is a percentage, 8-bit value. */
147 brightness = (brightness * cur_sd_brightness) / 255;
148
149 /* Apply any backlight response curve */
150 if (brightness > 255)
151 pr_info("Error: Brightness > 255!\n");
152 else
153 brightness = bl_output[brightness];
154
155 return brightness;
156}
157
158static int kai_disp1_check_fb(struct device *dev, struct fb_info *info);
159
160static struct platform_pwm_backlight_data kai_backlight_data = {
161 .pwm_id = 0,
162 .max_brightness = 255,
163 .dft_brightness = 224,
164 .pwm_period_ns = 100000,
165 .init = kai_backlight_init,
166 .exit = kai_backlight_exit,
167 .notify = kai_backlight_notify,
168 /* Only toggle backlight on fb blank notifications for disp1 */
169 .check_fb = kai_disp1_check_fb,
170};
171
172static struct platform_device kai_backlight_device = {
173 .name = "pwm-backlight",
174 .id = -1,
175 .dev = {
176 .platform_data = &kai_backlight_data,
177 },
178};
179
180static int kai_panel_enable(void)
181{
182 if (kai_lvds_reg == NULL) {
183 kai_lvds_reg = regulator_get(NULL, "vdd_lvds");
184 if (WARN_ON(IS_ERR(kai_lvds_reg)))
185 pr_err("%s: couldn't get regulator vdd_lvds: %ld\n",
186 __func__, PTR_ERR(kai_lvds_reg));
187 else
188 regulator_enable(kai_lvds_reg);
189 }
190
191 if (kai_lvds_vdd_panel == NULL) {
192 kai_lvds_vdd_panel = regulator_get(NULL, "vdd_lcd_panel");
193 if (WARN_ON(IS_ERR(kai_lvds_vdd_panel)))
194 pr_err("%s: couldn't get regulator vdd_lcd_panel: %ld\n",
195 __func__, PTR_ERR(kai_lvds_vdd_panel));
196 else
197 regulator_enable(kai_lvds_vdd_panel);
198 }
199
200 mdelay(5);
201
202 gpio_set_value(kai_lvds_avdd_en, 1);
203 mdelay(5);
204
205 gpio_set_value(kai_lvds_stdby, 1);
206 gpio_set_value(kai_lvds_rst, 1);
207 gpio_set_value(kai_lvds_shutdown, 1);
208 gpio_set_value(kai_lvds_lr, 1);
209
210 mdelay(10);
211
212 return 0;
213}
214
215static int kai_panel_disable(void)
216{
217 gpio_set_value(kai_lvds_lr, 0);
218 gpio_set_value(kai_lvds_shutdown, 0);
219 gpio_set_value(kai_lvds_rst, 0);
220 gpio_set_value(kai_lvds_stdby, 0);
221 mdelay(5);
222
223 gpio_set_value(kai_lvds_avdd_en, 0);
224 mdelay(5);
225
226 regulator_disable(kai_lvds_reg);
227 regulator_put(kai_lvds_reg);
228 kai_lvds_reg = NULL;
229
230 regulator_disable(kai_lvds_vdd_panel);
231 regulator_put(kai_lvds_vdd_panel);
232 kai_lvds_vdd_panel = NULL;
233
234 return 0;
235}
236
237#ifdef CONFIG_TEGRA_DC
238static int kai_hdmi_vddio_enable(void)
239{
240 int ret;
241 if (!kai_hdmi_vddio) {
242 kai_hdmi_vddio = regulator_get(NULL, "vdd_hdmi_con");
243 if (IS_ERR_OR_NULL(kai_hdmi_vddio)) {
244 ret = PTR_ERR(kai_hdmi_vddio);
245 pr_err("hdmi: couldn't get regulator vdd_hdmi_con\n");
246 kai_hdmi_vddio = NULL;
247 return ret;
248 }
249 }
250 ret = regulator_enable(kai_hdmi_vddio);
251 if (ret < 0) {
252 pr_err("hdmi: couldn't enable regulator vdd_hdmi_con\n");
253 regulator_put(kai_hdmi_vddio);
254 kai_hdmi_vddio = NULL;
255 return ret;
256 }
257 return ret;
258}
259
260static int kai_hdmi_vddio_disable(void)
261{
262 if (kai_hdmi_vddio) {
263 regulator_disable(kai_hdmi_vddio);
264 regulator_put(kai_hdmi_vddio);
265 kai_hdmi_vddio = NULL;
266 }
267 return 0;
268}
269
270static int kai_hdmi_enable(void)
271{
272 int ret;
273 if (!kai_hdmi_reg) {
274 kai_hdmi_reg = regulator_get(NULL, "avdd_hdmi");
275 if (IS_ERR_OR_NULL(kai_hdmi_reg)) {
276 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
277 kai_hdmi_reg = NULL;
278 return PTR_ERR(kai_hdmi_reg);
279 }
280 }
281 ret = regulator_enable(kai_hdmi_reg);
282 if (ret < 0) {
283 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
284 return ret;
285 }
286 if (!kai_hdmi_pll) {
287 kai_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll");
288 if (IS_ERR_OR_NULL(kai_hdmi_pll)) {
289 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
290 kai_hdmi_pll = NULL;
291 regulator_put(kai_hdmi_reg);
292 kai_hdmi_reg = NULL;
293 return PTR_ERR(kai_hdmi_pll);
294 }
295 }
296 ret = regulator_enable(kai_hdmi_pll);
297 if (ret < 0) {
298 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
299 return ret;
300 }
301 return 0;
302}
303
304static int kai_hdmi_disable(void)
305{
306 regulator_disable(kai_hdmi_reg);
307 regulator_put(kai_hdmi_reg);
308 kai_hdmi_reg = NULL;
309
310 regulator_disable(kai_hdmi_pll);
311 regulator_put(kai_hdmi_pll);
312 kai_hdmi_pll = NULL;
313 return 0;
314}
315
316static struct resource kai_disp1_resources[] = {
317 {
318 .name = "irq",
319 .start = INT_DISPLAY_GENERAL,
320 .end = INT_DISPLAY_GENERAL,
321 .flags = IORESOURCE_IRQ,
322 },
323 {
324 .name = "regs",
325 .start = TEGRA_DISPLAY_BASE,
326 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
327 .flags = IORESOURCE_MEM,
328 },
329 {
330 .name = "fbmem",
331 .start = 0, /* Filled in by kai_panel_init() */
332 .end = 0, /* Filled in by kai_panel_init() */
333 .flags = IORESOURCE_MEM,
334 },
335};
336
337static struct resource kai_disp2_resources[] = {
338 {
339 .name = "irq",
340 .start = INT_DISPLAY_B_GENERAL,
341 .end = INT_DISPLAY_B_GENERAL,
342 .flags = IORESOURCE_IRQ,
343 },
344 {
345 .name = "regs",
346 .start = TEGRA_DISPLAY2_BASE,
347 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
348 .flags = IORESOURCE_MEM,
349 },
350 {
351 .name = "fbmem",
352 .flags = IORESOURCE_MEM,
353 .start = 0,
354 .end = 0,
355 },
356 {
357 .name = "hdmi_regs",
358 .start = TEGRA_HDMI_BASE,
359 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
360 .flags = IORESOURCE_MEM,
361 },
362};
363#endif
364
365static struct tegra_dc_mode kai_panel_modes[] = {
366 {
367 /* 1024x600@60Hz */
368 .pclk = 51206000,
369 .h_ref_to_sync = 11,
370 .v_ref_to_sync = 1,
371 .h_sync_width = 10,
372 .v_sync_width = 5,
373 .h_back_porch = 10,
374 .v_back_porch = 15,
375 .h_active = 1024,
376 .v_active = 600,
377 .h_front_porch = 300,
378 .v_front_porch = 15,
379 },
380};
381
382static struct tegra_dc_sd_settings kai_sd_settings = {
383 .enable = 1, /* enabled by default. */
384 .use_auto_pwm = false,
385 .hw_update_delay = 0,
386 .bin_width = -1,
387 .aggressiveness = 1,
388 .phase_in_adjustments = true,
389 .use_vid_luma = false,
390 /* Default video coefficients */
391 .coeff = {5, 9, 2},
392 .fc = {0, 0},
393 /* Immediate backlight changes */
394 .blp = {1024, 255},
395 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
396 /* Default BL TF */
397 .bltf = {
398 {
399 {57, 65, 74, 83},
400 {93, 103, 114, 126},
401 {138, 151, 165, 179},
402 {194, 209, 225, 242},
403 },
404 {
405 {58, 66, 75, 84},
406 {94, 105, 116, 127},
407 {140, 153, 166, 181},
408 {196, 211, 227, 244},
409 },
410 {
411 {60, 68, 77, 87},
412 {97, 107, 119, 130},
413 {143, 156, 170, 184},
414 {199, 215, 231, 248},
415 },
416 {
417 {64, 73, 82, 91},
418 {102, 113, 124, 137},
419 {149, 163, 177, 192},
420 {207, 223, 240, 255},
421 },
422 },
423 /* Default LUT */
424 .lut = {
425 {
426 {250, 250, 250},
427 {194, 194, 194},
428 {149, 149, 149},
429 {113, 113, 113},
430 {82, 82, 82},
431 {56, 56, 56},
432 {34, 34, 34},
433 {15, 15, 15},
434 {0, 0, 0},
435 },
436 {
437 {246, 246, 246},
438 {191, 191, 191},
439 {147, 147, 147},
440 {111, 111, 111},
441 {80, 80, 80},
442 {55, 55, 55},
443 {33, 33, 33},
444 {14, 14, 14},
445 {0, 0, 0},
446 },
447 {
448 {239, 239, 239},
449 {185, 185, 185},
450 {142, 142, 142},
451 {107, 107, 107},
452 {77, 77, 77},
453 {52, 52, 52},
454 {30, 30, 30},
455 {12, 12, 12},
456 {0, 0, 0},
457 },
458 {
459 {224, 224, 224},
460 {173, 173, 173},
461 {133, 133, 133},
462 {99, 99, 99},
463 {70, 70, 70},
464 {46, 46, 46},
465 {25, 25, 25},
466 {7, 7, 7},
467 {0, 0, 0},
468 },
469 },
470 .sd_brightness = &sd_brightness,
471 .bl_device = &kai_backlight_device,
472};
473
474#ifdef CONFIG_TEGRA_DC
475static struct tegra_fb_data kai_fb_data = {
476 .win = 0,
477 .xres = 1024,
478 .yres = 600,
479 .bits_per_pixel = 32,
480 .flags = TEGRA_FB_FLIP_ON_PROBE,
481};
482
483static struct tegra_fb_data kai_hdmi_fb_data = {
484 .win = 0,
485 .xres = 1024,
486 .yres = 600,
487 .bits_per_pixel = 32,
488 .flags = TEGRA_FB_FLIP_ON_PROBE,
489};
490
491static struct tegra_dc_out kai_disp2_out = {
492 .type = TEGRA_DC_OUT_HDMI,
493 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
494
495 .dcc_bus = 3,
496 .hotplug_gpio = kai_hdmi_hpd,
497
498 .max_pixclock = KHZ2PICOS(148500),
499
500 .align = TEGRA_DC_ALIGN_MSB,
501 .order = TEGRA_DC_ORDER_RED_BLUE,
502
503 .enable = kai_hdmi_enable,
504 .disable = kai_hdmi_disable,
505
506 .postsuspend = kai_hdmi_vddio_disable,
507 .hotplug_init = kai_hdmi_vddio_enable,
508};
509
510static struct tegra_dc_platform_data kai_disp2_pdata = {
511 .flags = 0,
512 .default_out = &kai_disp2_out,
513 .fb = &kai_hdmi_fb_data,
514 .emc_clk_rate = 300000000,
515};
516#endif
517
518static struct tegra_dc_out kai_disp1_out = {
519 .align = TEGRA_DC_ALIGN_MSB,
520 .order = TEGRA_DC_ORDER_RED_BLUE,
521 .sd_settings = &kai_sd_settings,
522 .parent_clk = "pll_p",
523 .parent_clk_backup = "pll_d2_out0",
524
525 .type = TEGRA_DC_OUT_RGB,
526 .depth = 18,
527 .dither = TEGRA_DC_ORDERED_DITHER,
528
529 .modes = kai_panel_modes,
530 .n_modes = ARRAY_SIZE(kai_panel_modes),
531
532 .enable = kai_panel_enable,
533 .disable = kai_panel_disable,
534};
535
536#ifdef CONFIG_TEGRA_DC
537static struct tegra_dc_platform_data kai_disp1_pdata = {
538 .flags = TEGRA_DC_FLAG_ENABLED,
539 .default_out = &kai_disp1_out,
540 .emc_clk_rate = 300000000,
541 .fb = &kai_fb_data,
542};
543
544static struct nvhost_device kai_disp1_device = {
545 .name = "tegradc",
546 .id = 0,
547 .resource = kai_disp1_resources,
548 .num_resources = ARRAY_SIZE(kai_disp1_resources),
549 .dev = {
550 .platform_data = &kai_disp1_pdata,
551 },
552};
553
554static int kai_disp1_check_fb(struct device *dev, struct fb_info *info)
555{
556 return info->device == &kai_disp1_device.dev;
557}
558
559static struct nvhost_device kai_disp2_device = {
560 .name = "tegradc",
561 .id = 1,
562 .resource = kai_disp2_resources,
563 .num_resources = ARRAY_SIZE(kai_disp2_resources),
564 .dev = {
565 .platform_data = &kai_disp2_pdata,
566 },
567};
568#else
569static int kai_disp1_check_fb(struct device *dev, struct fb_info *info)
570{
571 return 0;
572}
573#endif
574
575#if defined(CONFIG_TEGRA_NVMAP)
576static struct nvmap_platform_carveout kai_carveouts[] = {
577 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
578 [1] = {
579 .name = "generic-0",
580 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
581 .base = 0, /* Filled in by kai_panel_init() */
582 .size = 0, /* Filled in by kai_panel_init() */
583 .buddy_size = SZ_32K,
584 },
585};
586
587static struct nvmap_platform_data kai_nvmap_data = {
588 .carveouts = kai_carveouts,
589 .nr_carveouts = ARRAY_SIZE(kai_carveouts),
590};
591
592static struct platform_device kai_nvmap_device = {
593 .name = "tegra-nvmap",
594 .id = -1,
595 .dev = {
596 .platform_data = &kai_nvmap_data,
597 },
598};
599#endif
600
601static struct platform_device *kai_gfx_devices[] __initdata = {
602#if defined(CONFIG_TEGRA_NVMAP)
603 &kai_nvmap_device,
604#endif
605 &tegra_pwfm0_device,
606 &kai_backlight_device,
607};
608
609
610#ifdef CONFIG_HAS_EARLYSUSPEND
611/* put early_suspend/late_resume handlers here for the display in order
612 * to keep the code out of the display driver, keeping it closer to upstream
613 */
614struct early_suspend kai_panel_early_suspender;
615
616static void kai_panel_early_suspend(struct early_suspend *h)
617{
618 /* power down LCD, add use a black screen for HDMI */
619 if (num_registered_fb > 0)
620 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
621 if (num_registered_fb > 1)
622 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
623
624#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
625 cpufreq_save_default_governor();
626 cpufreq_set_conservative_governor();
627 cpufreq_set_conservative_governor_param("up_threshold",
628 SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
629
630 cpufreq_set_conservative_governor_param("down_threshold",
631 SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
632
633 cpufreq_set_conservative_governor_param("freq_step",
634 SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
635#endif
636
637}
638
639static void kai_panel_late_resume(struct early_suspend *h)
640{
641 unsigned i;
642#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
643 cpufreq_restore_default_governor();
644#endif
645 for (i = 0; i < num_registered_fb; i++)
646 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
647}
648#endif
649
650int __init kai_panel_init(void)
651{
652 int err;
653 struct resource __maybe_unused *res;
654 struct board_info board_info;
655
656 tegra_get_board_info(&board_info);
657
658#if defined(CONFIG_TEGRA_NVMAP)
659 kai_carveouts[1].base = tegra_carveout_start;
660 kai_carveouts[1].size = tegra_carveout_size;
661#endif
662 gpio_request(kai_lvds_avdd_en, "lvds_avdd_en");
663 gpio_direction_output(kai_lvds_avdd_en, 1);
664 tegra_gpio_enable(kai_lvds_avdd_en);
665
666 gpio_request(kai_lvds_stdby, "lvds_stdby");
667 gpio_direction_output(kai_lvds_stdby, 1);
668 tegra_gpio_enable(kai_lvds_stdby);
669
670 gpio_request(kai_lvds_rst, "lvds_rst");
671 gpio_direction_output(kai_lvds_rst, 1);
672 tegra_gpio_enable(kai_lvds_rst);
673
674 if (board_info.fab == BOARD_FAB_A00) {
675 gpio_request(kai_lvds_rs_a00, "lvds_rs");
676 gpio_direction_output(kai_lvds_rs_a00, 0);
677 tegra_gpio_enable(kai_lvds_rs_a00);
678 } else {
679 gpio_request(kai_lvds_rs, "lvds_rs");
680 gpio_direction_output(kai_lvds_rs, 0);
681 tegra_gpio_enable(kai_lvds_rs);
682 }
683
684 gpio_request(kai_lvds_lr, "lvds_lr");
685 gpio_direction_output(kai_lvds_lr, 1);
686 tegra_gpio_enable(kai_lvds_lr);
687
688 gpio_request(kai_lvds_shutdown, "lvds_shutdown");
689 gpio_direction_output(kai_lvds_shutdown, 1);
690 tegra_gpio_enable(kai_lvds_shutdown);
691
692 tegra_gpio_enable(kai_hdmi_hpd);
693 gpio_request(kai_hdmi_hpd, "hdmi_hpd");
694 gpio_direction_input(kai_hdmi_hpd);
695
696#ifdef CONFIG_HAS_EARLYSUSPEND
697 kai_panel_early_suspender.suspend = kai_panel_early_suspend;
698 kai_panel_early_suspender.resume = kai_panel_late_resume;
699 kai_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
700 register_early_suspend(&kai_panel_early_suspender);
701#endif
702
703#ifdef CONFIG_TEGRA_GRHOST
704 err = nvhost_device_register(&tegra_grhost_device);
705 if (err)
706 return err;
707#endif
708
709 err = platform_add_devices(kai_gfx_devices,
710 ARRAY_SIZE(kai_gfx_devices));
711
712#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
713 res = nvhost_get_resource_byname(&kai_disp1_device,
714 IORESOURCE_MEM, "fbmem");
715 res->start = tegra_fb_start;
716 res->end = tegra_fb_start + tegra_fb_size - 1;
717#endif
718
719 /* Copy the bootloader fb to the fb. */
720 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
721 min(tegra_fb_size, tegra_bootloader_fb_size));
722
723#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
724 if (!err)
725 err = nvhost_device_register(&kai_disp1_device);
726
727 res = nvhost_get_resource_byname(&kai_disp2_device,
728 IORESOURCE_MEM, "fbmem");
729 res->start = tegra_fb2_start;
730 res->end = tegra_fb2_start + tegra_fb2_size - 1;
731 if (!err)
732 err = nvhost_device_register(&kai_disp2_device);
733#endif
734
735#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
736 if (!err)
737 err = nvhost_device_register(&nvavp_device);
738#endif
739 return err;
740}
diff --git a/arch/arm/mach-tegra/board-kai-pinmux.c b/arch/arm/mach-tegra/board-kai-pinmux.c
new file mode 100644
index 00000000000..1bc64bdb155
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-pinmux.c
@@ -0,0 +1,565 @@
1/*
2 * arch/arm/mach-tegra/board-kai-pinmux.c
3 *
4 * Copyright (C) 2012 NVIDIA Corporation
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 <mach/pinmux.h>
20#include "board.h"
21#include "board-kai.h"
22#include "gpio-names.h"
23
24#define DEFAULT_DRIVE(_name) \
25 { \
26 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
27 .hsm = TEGRA_HSM_DISABLE, \
28 .schmitt = TEGRA_SCHMITT_ENABLE, \
29 .drive = TEGRA_DRIVE_DIV_1, \
30 .pull_down = TEGRA_PULL_31, \
31 .pull_up = TEGRA_PULL_31, \
32 .slew_rising = TEGRA_SLEW_SLOWEST, \
33 .slew_falling = TEGRA_SLEW_SLOWEST, \
34 }
35/* Setting the drive strength of pins
36 * hsm: Enable High speed mode (ENABLE/DISABLE)
37 * Schimit: Enable/disable schimit (ENABLE/DISABLE)
38 * drive: low power mode (DIV_1, DIV_2, DIV_4, DIV_8)
39 * pulldn_drive - drive down (falling edge) - Driver Output Pull-Down drive
40 * strength code. Value from 0 to 31.
41 * pullup_drive - drive up (rising edge) - Driver Output Pull-Up drive
42 * strength code. Value from 0 to 31.
43 * pulldn_slew - Driver Output Pull-Up slew control code - 2bit code
44 * code 11 is least slewing of signal. code 00 is highest
45 * slewing of the signal.
46 * Value - FASTEST, FAST, SLOW, SLOWEST
47 * pullup_slew - Driver Output Pull-Down slew control code -
48 * code 11 is least slewing of signal. code 00 is highest
49 * slewing of the signal.
50 * Value - FASTEST, FAST, SLOW, SLOWEST
51 */
52#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
53 { \
54 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
55 .hsm = TEGRA_HSM_##_hsm, \
56 .schmitt = TEGRA_SCHMITT_##_schmitt, \
57 .drive = TEGRA_DRIVE_##_drive, \
58 .pull_down = TEGRA_PULL_##_pulldn_drive, \
59 .pull_up = TEGRA_PULL_##_pullup_drive, \
60 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
61 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
62 }
63
64/* !!!FIXME!!!! POPULATE THIS TABLE */
65static __initdata struct tegra_drive_pingroup_config kai_drive_pinmux[] = {
66 /* DEFAULT_DRIVE(<pin_group>), */
67 /* SET_DRIVE(ATA, DISABLE, DISABLE, DIV_1, 31, 31, FAST, FAST) */
68 SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
69
70 /* All I2C pins are driven to maximum drive strength */
71 /* GEN1 I2C */
72 SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
73
74 /* GEN2 I2C */
75 SET_DRIVE(AT5, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
76
77 /* CAM I2C */
78 SET_DRIVE(GME, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
79
80 /* DDC I2C */
81 SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
82
83 /* PWR_I2C */
84 SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
85
86 /* UART3 */
87 SET_DRIVE(UART3, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
88
89 /* SDMMC1 */
90 SET_DRIVE(SDIO1, DISABLE, DISABLE, DIV_1, 46, 42, FAST, FAST),
91
92 /* SDMMC3 */
93 SET_DRIVE(SDIO3, DISABLE, DISABLE, DIV_1, 46, 42, FAST, FAST),
94
95 /* SDMMC4 */
96 SET_DRIVE(GMA, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
97 SET_DRIVE(GMB, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
98 SET_DRIVE(GMC, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
99 SET_DRIVE(GMD, DISABLE, DISABLE, DIV_1, 9, 9, SLOWEST, SLOWEST),
100
101};
102
103#define DEFAULT_PINMUX(_pingroup, _mux, _pupd, _tri, _io) \
104 { \
105 .pingroup = TEGRA_PINGROUP_##_pingroup, \
106 .func = TEGRA_MUX_##_mux, \
107 .pupd = TEGRA_PUPD_##_pupd, \
108 .tristate = TEGRA_TRI_##_tri, \
109 .io = TEGRA_PIN_##_io, \
110 .lock = TEGRA_PIN_LOCK_DEFAULT, \
111 .od = TEGRA_PIN_OD_DEFAULT, \
112 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
113 }
114
115#define I2C_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _od) \
116 { \
117 .pingroup = TEGRA_PINGROUP_##_pingroup, \
118 .func = TEGRA_MUX_##_mux, \
119 .pupd = TEGRA_PUPD_##_pupd, \
120 .tristate = TEGRA_TRI_##_tri, \
121 .io = TEGRA_PIN_##_io, \
122 .lock = TEGRA_PIN_LOCK_##_lock, \
123 .od = TEGRA_PIN_OD_##_od, \
124 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
125 }
126
127#define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
128 { \
129 .pingroup = TEGRA_PINGROUP_##_pingroup, \
130 .func = TEGRA_MUX_##_mux, \
131 .pupd = TEGRA_PUPD_##_pupd, \
132 .tristate = TEGRA_TRI_##_tri, \
133 .io = TEGRA_PIN_##_io, \
134 .lock = TEGRA_PIN_LOCK_##_lock, \
135 .od = TEGRA_PIN_OD_DEFAULT, \
136 .ioreset = TEGRA_PIN_IO_RESET_##_ioreset \
137 }
138
139static __initdata struct tegra_pingroup_config kai_pinmux_common[] = {
140 /* SDMMC1 pinmux */
141 DEFAULT_PINMUX(SDMMC1_CLK, SDMMC1, NORMAL, NORMAL, INPUT),
142 DEFAULT_PINMUX(SDMMC1_CMD, SDMMC1, PULL_UP, NORMAL, INPUT),
143 DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, PULL_UP, NORMAL, INPUT),
144 DEFAULT_PINMUX(SDMMC1_DAT2, SDMMC1, PULL_UP, NORMAL, INPUT),
145 DEFAULT_PINMUX(SDMMC1_DAT1, SDMMC1, PULL_UP, NORMAL, INPUT),
146 DEFAULT_PINMUX(SDMMC1_DAT0, SDMMC1, PULL_UP, NORMAL, INPUT),
147
148 /* SDMMC3 pinmux */
149 DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT),
150 DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, PULL_UP, NORMAL, INPUT),
151 DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, PULL_UP, NORMAL, INPUT),
152 DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, PULL_UP, NORMAL, INPUT),
153 DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, PULL_UP, NORMAL, INPUT),
154 DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, PULL_UP, NORMAL, INPUT),
155 DEFAULT_PINMUX(SDMMC3_DAT6, SDMMC3, PULL_UP, NORMAL, INPUT),
156 DEFAULT_PINMUX(SDMMC3_DAT7, SDMMC3, PULL_UP, NORMAL, INPUT),
157
158 /* SDMMC4 pinmux */
159 DEFAULT_PINMUX(SDMMC4_CLK, SDMMC4, NORMAL, NORMAL, INPUT),
160 DEFAULT_PINMUX(SDMMC4_CMD, SDMMC4, PULL_UP, NORMAL, INPUT),
161 DEFAULT_PINMUX(SDMMC4_DAT0, SDMMC4, PULL_UP, NORMAL, INPUT),
162 DEFAULT_PINMUX(SDMMC4_DAT1, SDMMC4, PULL_UP, NORMAL, INPUT),
163 DEFAULT_PINMUX(SDMMC4_DAT2, SDMMC4, PULL_UP, NORMAL, INPUT),
164 DEFAULT_PINMUX(SDMMC4_DAT3, SDMMC4, PULL_UP, NORMAL, INPUT),
165 DEFAULT_PINMUX(SDMMC4_DAT4, SDMMC4, PULL_UP, NORMAL, INPUT),
166 DEFAULT_PINMUX(SDMMC4_DAT5, SDMMC4, PULL_UP, NORMAL, INPUT),
167 DEFAULT_PINMUX(SDMMC4_DAT6, SDMMC4, PULL_UP, NORMAL, INPUT),
168 DEFAULT_PINMUX(SDMMC4_DAT7, SDMMC4, PULL_UP, NORMAL, INPUT),
169 DEFAULT_PINMUX(SDMMC4_RST_N, RSVD1, PULL_DOWN, NORMAL, INPUT),
170
171 /* I2C1 pinmux */
172 I2C_PINMUX(GEN1_I2C_SCL, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
173 I2C_PINMUX(GEN1_I2C_SDA, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
174
175 /* I2C2 pinmux */
176 I2C_PINMUX(GEN2_I2C_SCL, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
177 I2C_PINMUX(GEN2_I2C_SDA, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
178
179 /* I2C3 pinmux */
180 I2C_PINMUX(CAM_I2C_SCL, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
181 I2C_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
182
183 /* I2C4 pinmux */
184 I2C_PINMUX(DDC_SCL, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
185 I2C_PINMUX(DDC_SDA, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
186
187 /* Power I2C pinmux */
188 I2C_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
189 I2C_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
190
191 /* LCD */
192 DEFAULT_PINMUX(LCD_PCLK, DISPLAYA, NORMAL, NORMAL, INPUT),
193 DEFAULT_PINMUX(LCD_DE, DISPLAYA, NORMAL, NORMAL, INPUT),
194 DEFAULT_PINMUX(LCD_HSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
195 DEFAULT_PINMUX(LCD_VSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
196 DEFAULT_PINMUX(LCD_D0, DISPLAYA, NORMAL, NORMAL, INPUT),
197 DEFAULT_PINMUX(LCD_D1, DISPLAYA, NORMAL, NORMAL, INPUT),
198 DEFAULT_PINMUX(LCD_D2, DISPLAYA, NORMAL, NORMAL, INPUT),
199 DEFAULT_PINMUX(LCD_D3, DISPLAYA, NORMAL, NORMAL, INPUT),
200 DEFAULT_PINMUX(LCD_D4, DISPLAYA, NORMAL, NORMAL, INPUT),
201 DEFAULT_PINMUX(LCD_D5, DISPLAYA, NORMAL, NORMAL, INPUT),
202 DEFAULT_PINMUX(LCD_D6, DISPLAYA, NORMAL, NORMAL, INPUT),
203 DEFAULT_PINMUX(LCD_D7, DISPLAYA, NORMAL, NORMAL, INPUT),
204 DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
205 DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
206 DEFAULT_PINMUX(LCD_D10, DISPLAYA, NORMAL, NORMAL, INPUT),
207 DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
208 DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
209 DEFAULT_PINMUX(LCD_D13, DISPLAYA, NORMAL, NORMAL, INPUT),
210 DEFAULT_PINMUX(LCD_D14, DISPLAYA, NORMAL, NORMAL, INPUT),
211 DEFAULT_PINMUX(LCD_D15, DISPLAYA, NORMAL, NORMAL, INPUT),
212 DEFAULT_PINMUX(LCD_D16, DISPLAYA, NORMAL, NORMAL, INPUT),
213 DEFAULT_PINMUX(LCD_D17, DISPLAYA, NORMAL, NORMAL, INPUT),
214 DEFAULT_PINMUX(LCD_D18, DISPLAYA, NORMAL, NORMAL, INPUT),
215 DEFAULT_PINMUX(LCD_D19, DISPLAYA, NORMAL, NORMAL, INPUT),
216 DEFAULT_PINMUX(LCD_D20, DISPLAYA, NORMAL, NORMAL, INPUT),
217 DEFAULT_PINMUX(LCD_D21, DISPLAYA, NORMAL, NORMAL, INPUT),
218 DEFAULT_PINMUX(LCD_D22, DISPLAYA, NORMAL, NORMAL, INPUT),
219 DEFAULT_PINMUX(LCD_D23, DISPLAYA, NORMAL, NORMAL, INPUT),
220
221 /* UART B : GPS */
222 DEFAULT_PINMUX(UART2_RXD, IRDA, NORMAL, NORMAL, INPUT),
223 DEFAULT_PINMUX(UART2_TXD, IRDA, NORMAL, NORMAL, OUTPUT),
224 DEFAULT_PINMUX(UART2_RTS_N, UARTB, NORMAL, NORMAL, OUTPUT),
225 DEFAULT_PINMUX(UART2_CTS_N, UARTB, NORMAL, NORMAL, INPUT),
226
227 /*UART C : BT */
228 DEFAULT_PINMUX(UART3_TXD, UARTC, NORMAL, NORMAL, OUTPUT),
229 DEFAULT_PINMUX(UART3_RXD, UARTC, NORMAL, NORMAL, INPUT),
230 DEFAULT_PINMUX(UART3_CTS_N, UARTC, NORMAL, NORMAL, INPUT),
231 DEFAULT_PINMUX(UART3_RTS_N, UARTC, NORMAL, NORMAL, OUTPUT),
232
233 /* UART D : DEBUG */
234 DEFAULT_PINMUX(GMI_A16, UARTD, NORMAL, NORMAL, OUTPUT),
235 DEFAULT_PINMUX(GMI_A17, UARTD, NORMAL, NORMAL, INPUT),
236 DEFAULT_PINMUX(GMI_A18, UARTD, NORMAL, NORMAL, INPUT),
237 DEFAULT_PINMUX(GMI_A19, UARTD, NORMAL, NORMAL, OUTPUT),
238
239 /* KBC keys */
240 DEFAULT_PINMUX(KB_COL0, KBC, PULL_UP, NORMAL, INPUT),
241 DEFAULT_PINMUX(KB_COL1, KBC, PULL_UP, NORMAL, INPUT),
242 DEFAULT_PINMUX(KB_COL2, KBC, PULL_UP, NORMAL, INPUT),
243 DEFAULT_PINMUX(KB_COL3, KBC, PULL_UP, NORMAL, INPUT),
244 DEFAULT_PINMUX(KB_ROW0, KBC, PULL_UP, NORMAL, INPUT),
245 DEFAULT_PINMUX(KB_ROW1, KBC, PULL_UP, NORMAL, INPUT),
246 DEFAULT_PINMUX(KB_ROW2, KBC, PULL_UP, NORMAL, INPUT),
247
248 /* I2S0 : for MODEM */
249 DEFAULT_PINMUX(DAP1_FS, I2S0, NORMAL, NORMAL, INPUT),
250 DEFAULT_PINMUX(DAP1_DIN, I2S0, NORMAL, NORMAL, INPUT),
251 DEFAULT_PINMUX(DAP1_DOUT, I2S0, NORMAL, NORMAL, INPUT),
252 DEFAULT_PINMUX(DAP1_SCLK, I2S0, NORMAL, NORMAL, INPUT),
253
254 /* I2S1 : for CODEC */
255 DEFAULT_PINMUX(DAP2_FS, I2S1, NORMAL, NORMAL, INPUT),
256 DEFAULT_PINMUX(DAP2_DIN, I2S1, NORMAL, NORMAL, INPUT),
257 DEFAULT_PINMUX(DAP2_DOUT, I2S1, NORMAL, NORMAL, INPUT),
258 DEFAULT_PINMUX(DAP2_SCLK, I2S1, NORMAL, NORMAL, INPUT),
259
260 /* I2S3 : for BT */
261 DEFAULT_PINMUX(DAP4_FS, I2S3, NORMAL, NORMAL, INPUT),
262 DEFAULT_PINMUX(DAP4_DIN, I2S3, NORMAL, NORMAL, INPUT),
263 DEFAULT_PINMUX(DAP4_DOUT, I2S3, NORMAL, NORMAL, INPUT),
264 DEFAULT_PINMUX(DAP4_SCLK, I2S3, NORMAL, NORMAL, INPUT),
265
266 /* SPI1 : touch */
267 DEFAULT_PINMUX(SPI1_MOSI, SPI1, NORMAL, NORMAL, INPUT),
268 DEFAULT_PINMUX(SPI1_SCK, SPI1, NORMAL, NORMAL, INPUT),
269 DEFAULT_PINMUX(SPI1_CS0_N, SPI1, NORMAL, NORMAL, INPUT),
270 DEFAULT_PINMUX(SPI1_MISO, SPI1, NORMAL, NORMAL, INPUT),
271
272 /* SPIDIF */
273 DEFAULT_PINMUX(SPDIF_IN, SPDIF, NORMAL, NORMAL, INPUT),
274 DEFAULT_PINMUX(SPDIF_OUT, SPDIF, NORMAL, NORMAL, OUTPUT),
275
276 /* FIXED FUNCTION AND CONFIGURATION */
277 DEFAULT_PINMUX(CLK_32K_OUT, BLINK, NORMAL, NORMAL, OUTPUT),
278 DEFAULT_PINMUX(SYS_CLK_REQ, SYSCLK, NORMAL, NORMAL, OUTPUT),
279 DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT),
280 DEFAULT_PINMUX(GMI_AD4, RSVD1, NORMAL, NORMAL, INPUT),
281 DEFAULT_PINMUX(CLK1_OUT, EXTPERIPH1, NORMAL, NORMAL, INPUT),
282 DEFAULT_PINMUX(CLK2_OUT, EXTPERIPH2, NORMAL, NORMAL, INPUT),
283 DEFAULT_PINMUX(CLK3_OUT, EXTPERIPH3, NORMAL, NORMAL, OUTPUT),
284 DEFAULT_PINMUX(CLK2_REQ, DAP, NORMAL, NORMAL, INPUT),
285 DEFAULT_PINMUX(HDMI_INT, RSVD0, NORMAL, TRISTATE, INPUT),
286
287 /* GPIO */
288 /* POWER RAIL GPIO */
289 DEFAULT_PINMUX(DAP3_FS, I2S2, NORMAL, NORMAL, OUTPUT),
290 DEFAULT_PINMUX(GMI_AD14, RSVD1, PULL_DOWN, NORMAL, OUTPUT),
291 DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, NORMAL, NORMAL, OUTPUT),
292 DEFAULT_PINMUX(KB_ROW6, KBC, NORMAL, NORMAL, OUTPUT),
293 DEFAULT_PINMUX(KB_ROW7, KBC, NORMAL, NORMAL, OUTPUT),
294 DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, OUTPUT),
295 DEFAULT_PINMUX(LCD_PWR0, DISPLAYA, NORMAL, NORMAL, OUTPUT),
296 DEFAULT_PINMUX(LCD_PWR1, DISPLAYA, NORMAL, NORMAL, OUTPUT),
297 DEFAULT_PINMUX(LCD_PWR2, DISPLAYA, NORMAL, NORMAL, OUTPUT),
298 DEFAULT_PINMUX(KB_ROW8, KBC, NORMAL, NORMAL, OUTPUT),
299
300 /* CAMERA */
301 DEFAULT_PINMUX(CAM_MCLK, VI_ALT2, PULL_UP, NORMAL, INPUT),
302 DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, NORMAL, INPUT),
303 DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, NORMAL, INPUT),
304 DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, NORMAL, INPUT),
305 DEFAULT_PINMUX(GPIO_PBB5, VGP5, NORMAL, NORMAL, INPUT),
306 DEFAULT_PINMUX(GPIO_PBB6, VGP6, NORMAL, NORMAL, INPUT),
307 DEFAULT_PINMUX(GPIO_PBB7, I2S4, NORMAL, NORMAL, INPUT),
308 DEFAULT_PINMUX(GPIO_PCC2, I2S4, NORMAL, NORMAL, INPUT),
309 DEFAULT_PINMUX(KB_ROW4, KBC, NORMAL, NORMAL, OUTPUT),
310 DEFAULT_PINMUX(KB_ROW5, KBC, NORMAL, NORMAL, OUTPUT),
311 DEFAULT_PINMUX(KB_ROW9, KBC, NORMAL, NORMAL, OUTPUT),
312 DEFAULT_PINMUX(KB_ROW10, KBC, NORMAL, NORMAL, OUTPUT),
313
314 /* MODEM */
315 DEFAULT_PINMUX(GPIO_PV0, RSVD, NORMAL, NORMAL, INPUT),
316 DEFAULT_PINMUX(GPIO_PV1, RSVD, NORMAL, NORMAL, INPUT),
317
318 /* GPS and BT */
319 DEFAULT_PINMUX(GPIO_PU0, RSVD1, NORMAL, NORMAL, INPUT),
320 DEFAULT_PINMUX(GPIO_PU1, RSVD1, NORMAL, NORMAL, OUTPUT),
321 DEFAULT_PINMUX(GPIO_PU2, RSVD1, NORMAL, NORMAL, INPUT),
322 DEFAULT_PINMUX(GPIO_PU3, RSVD1, NORMAL, NORMAL, INPUT),
323 DEFAULT_PINMUX(GPIO_PU4, PWM1, NORMAL, NORMAL, OUTPUT),
324 DEFAULT_PINMUX(GPIO_PU5, PWM2, NORMAL, NORMAL, INPUT),
325 DEFAULT_PINMUX(GPIO_PU6, RSVD1, NORMAL, NORMAL, INPUT),
326 DEFAULT_PINMUX(KB_ROW14, KBC, NORMAL, TRISTATE, OUTPUT),
327
328 /* LCD GPIO */
329 DEFAULT_PINMUX(GMI_AD0, RSVD1, NORMAL, NORMAL, OUTPUT),
330 DEFAULT_PINMUX(GMI_AD1, RSVD1, NORMAL, NORMAL, OUTPUT),
331 DEFAULT_PINMUX(GMI_AD2, RSVD1, PULL_DOWN, NORMAL, OUTPUT),
332 DEFAULT_PINMUX(GMI_AD3, RSVD1, PULL_DOWN, NORMAL, OUTPUT),
333 DEFAULT_PINMUX(GMI_AD5, RSVD1, PULL_DOWN, NORMAL, OUTPUT),
334 DEFAULT_PINMUX(GMI_AD6, RSVD1, PULL_DOWN, NORMAL, OUTPUT),
335 DEFAULT_PINMUX(GMI_AD7, RSVD1, PULL_DOWN, NORMAL, OUTPUT),
336 DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
337 DEFAULT_PINMUX(GMI_AD9, RSVD2, PULL_DOWN, NORMAL, OUTPUT),
338 DEFAULT_PINMUX(GMI_AD11, PWM3, NORMAL, NORMAL, OUTPUT),
339
340 /* TOUCH */
341 DEFAULT_PINMUX(GMI_WAIT, RSVD1, PULL_UP, NORMAL, INPUT),
342 DEFAULT_PINMUX(GMI_WP_N, RSVD1, PULL_UP, NORMAL, INPUT),
343 DEFAULT_PINMUX(LCD_SDOUT, DISPLAYA, NORMAL, NORMAL, INPUT),
344 DEFAULT_PINMUX(LCD_DC1, DISPLAYA, NORMAL, NORMAL, INPUT),
345 DEFAULT_PINMUX(LCD_WR_N, DISPLAYA, PULL_UP, NORMAL, INPUT),
346
347 /* SDMMC */
348 DEFAULT_PINMUX(GMI_IORDY, RSVD1, PULL_UP, NORMAL, INPUT),
349
350 /* CODEC */
351 DEFAULT_PINMUX(SPI2_SCK, SPI2, NORMAL, NORMAL, OUTPUT),
352 DEFAULT_PINMUX(SPI2_CS1_N, SPI2, NORMAL, NORMAL, INPUT),
353 DEFAULT_PINMUX(GMI_CS2_N, RSVD1, NORMAL, NORMAL, INPUT),
354 DEFAULT_PINMUX(GMI_CS3_N, RSVD1, NORMAL, NORMAL, INPUT),
355
356 /* OTHERS */
357 DEFAULT_PINMUX(KB_ROW3, KBC, NORMAL, NORMAL, OUTPUT),
358 DEFAULT_PINMUX(GMI_DQS, RSVD1, NORMAL, NORMAL, INPUT),
359
360 DEFAULT_PINMUX(GMI_AD15, RSVD1, PULL_UP, NORMAL, OUTPUT),
361 DEFAULT_PINMUX(GMI_CLK, RSVD1, PULL_UP, NORMAL, INPUT),
362
363 DEFAULT_PINMUX(GMI_RST_N, NAND, PULL_UP, NORMAL, OUTPUT),
364 DEFAULT_PINMUX(LCD_DC0, DISPLAYA, NORMAL, NORMAL, INPUT),
365 DEFAULT_PINMUX(LCD_CS0_N, DISPLAYA, NORMAL, NORMAL, INPUT),
366 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
367 DEFAULT_PINMUX(LCD_SCK, DISPLAYA, NORMAL, NORMAL, INPUT),
368 DEFAULT_PINMUX(LCD_SDIN, DISPLAYA, NORMAL, NORMAL, INPUT),
369 DEFAULT_PINMUX(CRT_HSYNC, CRT, NORMAL, NORMAL, OUTPUT),
370 DEFAULT_PINMUX(CRT_VSYNC, CRT, NORMAL, NORMAL, OUTPUT),
371 DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT),
372 DEFAULT_PINMUX(PEX_L2_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
373 DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
374 DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE, NORMAL, NORMAL, OUTPUT),
375 DEFAULT_PINMUX(HDMI_CEC, CEC, NORMAL, NORMAL, INPUT),
376
377 DEFAULT_PINMUX(KB_ROW15, KBC, NORMAL, NORMAL, OUTPUT),
378 DEFAULT_PINMUX(SPI2_CS2_N, SPI2, NORMAL, NORMAL, INPUT),
379 DEFAULT_PINMUX(SPI2_MISO, SPI2, NORMAL, NORMAL, INPUT),
380 DEFAULT_PINMUX(SPI2_MOSI, SPI2, NORMAL, NORMAL, INPUT),
381
382 DEFAULT_PINMUX(KB_ROW11, KBC, NORMAL, NORMAL, OUTPUT),
383 DEFAULT_PINMUX(KB_ROW12, KBC, NORMAL, TRISTATE, OUTPUT),
384 DEFAULT_PINMUX(KB_ROW13, KBC, NORMAL, TRISTATE, OUTPUT),
385};
386
387/*Do not use for now*/
388static __initdata struct tegra_pingroup_config unused_pins_lowpower[] = {
389 DEFAULT_PINMUX(ULPI_CLK, ULPI, NORMAL, TRISTATE, OUTPUT),
390 DEFAULT_PINMUX(ULPI_DATA0, ULPI, NORMAL, TRISTATE, OUTPUT),
391 DEFAULT_PINMUX(ULPI_DATA1, ULPI, NORMAL, TRISTATE, OUTPUT),
392 DEFAULT_PINMUX(ULPI_DATA2, ULPI, NORMAL, TRISTATE, OUTPUT),
393 DEFAULT_PINMUX(ULPI_DATA3, ULPI, NORMAL, TRISTATE, OUTPUT),
394 DEFAULT_PINMUX(ULPI_DATA4, ULPI, NORMAL, TRISTATE, OUTPUT),
395 DEFAULT_PINMUX(ULPI_DATA5, ULPI, NORMAL, TRISTATE, OUTPUT),
396 DEFAULT_PINMUX(ULPI_DATA6, ULPI, NORMAL, TRISTATE, OUTPUT),
397 DEFAULT_PINMUX(ULPI_DATA7, ULPI, NORMAL, TRISTATE, OUTPUT),
398 DEFAULT_PINMUX(ULPI_DIR, ULPI, NORMAL, TRISTATE, OUTPUT),
399 DEFAULT_PINMUX(ULPI_NXT, ULPI, NORMAL, TRISTATE, OUTPUT),
400 DEFAULT_PINMUX(ULPI_STP, ULPI, NORMAL, TRISTATE, OUTPUT),
401
402 DEFAULT_PINMUX(GMI_AD10, PWM2, NORMAL, TRISTATE, OUTPUT),
403 DEFAULT_PINMUX(GMI_AD12, RSVD1, NORMAL, TRISTATE, INPUT),
404 DEFAULT_PINMUX(GMI_AD13, RSVD1, NORMAL, TRISTATE, OUTPUT),
405 DEFAULT_PINMUX(CLK1_REQ, DAP, NORMAL, TRISTATE, OUTPUT),
406 DEFAULT_PINMUX(GMI_ADV_N, RSVD1, NORMAL, TRISTATE, OUTPUT),
407 DEFAULT_PINMUX(GMI_CS0_N, RSVD1, NORMAL, TRISTATE, OUTPUT),
408 DEFAULT_PINMUX(GMI_CS1_N, RSVD1, NORMAL, TRISTATE, OUTPUT),
409 DEFAULT_PINMUX(GMI_CS4_N, RSVD1, NORMAL, TRISTATE, OUTPUT),
410 DEFAULT_PINMUX(GMI_CS6_N, NAND, NORMAL, TRISTATE, OUTPUT),
411 DEFAULT_PINMUX(GMI_CS7_N, NAND, NORMAL, TRISTATE, OUTPUT),
412 DEFAULT_PINMUX(GMI_OE_N, RSVD1, NORMAL, TRISTATE, OUTPUT),
413 DEFAULT_PINMUX(GMI_WR_N, RSVD1, NORMAL, TRISTATE, OUTPUT),
414 DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, TRISTATE, OUTPUT),
415 DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, TRISTATE, OUTPUT),
416 DEFAULT_PINMUX(PEX_L0_RST_N, PCIE, NORMAL, TRISTATE, OUTPUT),
417 DEFAULT_PINMUX(PEX_L1_CLKREQ_N, PCIE, NORMAL, TRISTATE, OUTPUT),
418 DEFAULT_PINMUX(PEX_L1_PRSNT_N, PCIE, NORMAL, TRISTATE, OUTPUT),
419 DEFAULT_PINMUX(PEX_L1_RST_N, PCIE, NORMAL, TRISTATE, OUTPUT),
420 DEFAULT_PINMUX(GPIO_PV2, OWR, NORMAL, TRISTATE, OUTPUT),
421 DEFAULT_PINMUX(GPIO_PV3, RSVD1, NORMAL, TRISTATE, OUTPUT),
422 DEFAULT_PINMUX(HDMI_CEC, CEC, NORMAL, TRISTATE, OUTPUT),
423 DEFAULT_PINMUX(KB_COL4, KBC, NORMAL, TRISTATE, OUTPUT),
424 DEFAULT_PINMUX(KB_COL5, KBC, NORMAL, TRISTATE, OUTPUT),
425 DEFAULT_PINMUX(KB_COL6, KBC, NORMAL, TRISTATE, OUTPUT),
426 DEFAULT_PINMUX(KB_COL7, KBC, NORMAL, TRISTATE, OUTPUT),
427 DEFAULT_PINMUX(CLK3_REQ, DEV3, NORMAL, TRISTATE, OUTPUT),
428 DEFAULT_PINMUX(VI_D0, VI, NORMAL, TRISTATE, OUTPUT),
429 DEFAULT_PINMUX(VI_D1, VI, NORMAL, TRISTATE, OUTPUT),
430 DEFAULT_PINMUX(VI_D10, VI, NORMAL, TRISTATE, OUTPUT),
431 DEFAULT_PINMUX(VI_D11, VI, NORMAL, TRISTATE, OUTPUT),
432 DEFAULT_PINMUX(VI_D2, VI, NORMAL, TRISTATE, OUTPUT),
433 DEFAULT_PINMUX(VI_D3, VI, NORMAL, TRISTATE, OUTPUT),
434 DEFAULT_PINMUX(VI_D4, VI, NORMAL, TRISTATE, OUTPUT),
435 DEFAULT_PINMUX(VI_D5, VI, NORMAL, TRISTATE, OUTPUT),
436 DEFAULT_PINMUX(VI_D6, VI, NORMAL, TRISTATE, OUTPUT),
437 DEFAULT_PINMUX(VI_D7, VI, NORMAL, TRISTATE, OUTPUT),
438 DEFAULT_PINMUX(VI_D8, VI, NORMAL, TRISTATE, OUTPUT),
439 DEFAULT_PINMUX(VI_D9, VI, NORMAL, TRISTATE, OUTPUT),
440 DEFAULT_PINMUX(VI_HSYNC, VI, NORMAL, TRISTATE, OUTPUT),
441 DEFAULT_PINMUX(VI_MCLK, VI, NORMAL, TRISTATE, OUTPUT),
442 DEFAULT_PINMUX(VI_PCLK, VI, NORMAL, TRISTATE, OUTPUT),
443 DEFAULT_PINMUX(VI_VSYNC, VI, NORMAL, TRISTATE, OUTPUT),
444 DEFAULT_PINMUX(DAP3_DIN, I2S2, NORMAL, TRISTATE, OUTPUT),
445 DEFAULT_PINMUX(DAP3_DOUT, I2S2, NORMAL, TRISTATE, OUTPUT),
446 DEFAULT_PINMUX(DAP3_SCLK, I2S2, NORMAL, TRISTATE, OUTPUT),
447
448};
449
450static void __init kai_pinmux_audio_init(void)
451{
452 tegra_gpio_enable(TEGRA_GPIO_CDC_IRQ);
453 gpio_request(TEGRA_GPIO_CDC_IRQ, "rt5640");
454 gpio_direction_input(TEGRA_GPIO_CDC_IRQ);
455
456 tegra_gpio_enable(TEGRA_GPIO_HP_DET);
457 tegra_gpio_enable(TEGRA_GPIO_INT_MIC_EN);
458 tegra_gpio_enable(TEGRA_GPIO_EXT_MIC_EN);
459}
460
461/* We are disabling this code for now. */
462#define GPIO_INIT_PIN_MODE(_gpio, _is_input, _value) \
463 { \
464 .gpio_nr = _gpio, \
465 .is_input = _is_input, \
466 .value = _value, \
467 }
468
469static struct gpio_init_pin_info init_gpio_mode_kai_common[] = {
470 GPIO_INIT_PIN_MODE(TEGRA_GPIO_PDD7, false, 0),
471 GPIO_INIT_PIN_MODE(TEGRA_GPIO_PCC6, false, 0),
472};
473
474static void __init kai_gpio_init_configure(void)
475{
476 int len;
477 int i;
478 struct gpio_init_pin_info *pins_info;
479
480 len = ARRAY_SIZE(init_gpio_mode_kai_common);
481 pins_info = init_gpio_mode_kai_common;
482
483 for (i = 0; i < len; ++i) {
484 tegra_gpio_init_configure(pins_info->gpio_nr,
485 pins_info->is_input, pins_info->value);
486 pins_info++;
487 }
488}
489
490int __init kai_pinmux_init(void)
491{
492 struct board_info board_info;
493 tegra_get_board_info(&board_info);
494 BUG_ON(board_info.board_id != BOARD_E1565);
495 kai_gpio_init_configure();
496
497 tegra_pinmux_config_table(kai_pinmux_common, ARRAY_SIZE(kai_pinmux_common));
498 tegra_drive_pinmux_config_table(kai_drive_pinmux,
499 ARRAY_SIZE(kai_drive_pinmux));
500
501 tegra_pinmux_config_table(unused_pins_lowpower,
502 ARRAY_SIZE(unused_pins_lowpower));
503 kai_pinmux_audio_init();
504
505 return 0;
506}
507
508#define PIN_GPIO_LPM(_name, _gpio, _is_input, _value) \
509 { \
510 .name = _name, \
511 .gpio_nr = _gpio, \
512 .is_gpio = true, \
513 .is_input = _is_input, \
514 .value = _value, \
515 }
516
517struct gpio_init_pin_info pin_lpm_kai_common[] = {
518 PIN_GPIO_LPM("GMI_CS4_N", TEGRA_GPIO_PK2, 1, 0),
519 PIN_GPIO_LPM("GMI_CS7", TEGRA_GPIO_PI6, 1, 0),
520 PIN_GPIO_LPM("GMI_CS0", TEGRA_GPIO_PJ0, 1, 0),
521 PIN_GPIO_LPM("GMI_CS1", TEGRA_GPIO_PJ2, 1, 0),
522};
523
524static void set_unused_pin_gpio(struct gpio_init_pin_info *lpm_pin_info,
525 int list_count)
526{
527 int i;
528 struct gpio_init_pin_info *pin_info;
529 int ret;
530
531 for (i = 0; i < list_count; ++i) {
532 pin_info = (struct gpio_init_pin_info *)(lpm_pin_info + i);
533 if (!pin_info->is_gpio)
534 continue;
535
536 ret = gpio_request(pin_info->gpio_nr, pin_info->name);
537 if (ret < 0) {
538 pr_err("%s() Error in gpio_request() for gpio %d\n",
539 __func__, pin_info->gpio_nr);
540 continue;
541 }
542 if (pin_info->is_input)
543 ret = gpio_direction_input(pin_info->gpio_nr);
544 else
545 ret = gpio_direction_output(pin_info->gpio_nr,
546 pin_info->value);
547 if (ret < 0) {
548 pr_err("%s() Error in setting gpio %d to in/out\n",
549 __func__, pin_info->gpio_nr);
550 gpio_free(pin_info->gpio_nr);
551 continue;
552 }
553 tegra_gpio_enable(pin_info->gpio_nr);
554 }
555}
556
557/* Initialize the pins to desired state as per power/asic/system-eng
558 * recomendation */
559int __init kai_pins_state_init(void)
560{
561 set_unused_pin_gpio(&pin_lpm_kai_common[0],
562 ARRAY_SIZE(pin_lpm_kai_common));
563
564 return 0;
565}
diff --git a/arch/arm/mach-tegra/board-kai-power.c b/arch/arm/mach-tegra/board-kai-power.c
new file mode 100644
index 00000000000..edb0ee35abb
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-power.c
@@ -0,0 +1,658 @@
1/*
2 * arch/arm/mach-tegra/board-kai-power.c
3 *
4 * Copyright (C) 2012 NVIDIA, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20#include <linux/i2c.h>
21#include <linux/pda_power.h>
22#include <linux/platform_device.h>
23#include <linux/resource.h>
24#include <linux/regulator/machine.h>
25#include <linux/mfd/max77663-core.h>
26#include <linux/regulator/max77663-regulator.h>
27#include <linux/gpio.h>
28#include <linux/io.h>
29#include <linux/regulator/fixed.h>
30#include <linux/power/gpio-charger.h>
31
32#include <asm/mach-types.h>
33
34#include <mach/iomap.h>
35#include <mach/irqs.h>
36#include <mach/pinmux.h>
37#include <mach/edp.h>
38
39#include "gpio-names.h"
40#include "board.h"
41#include "board-kai.h"
42#include "pm.h"
43#include "wakeups-t3.h"
44#include "tegra3_tsensor.h"
45
46#define PMC_CTRL 0x0
47#define PMC_CTRL_INTR_LOW (1 << 17)
48
49static struct regulator_consumer_supply max77663_sd0_supply[] = {
50 REGULATOR_SUPPLY("vdd_cpu", NULL),
51};
52
53static struct regulator_consumer_supply max77663_sd1_supply[] = {
54 REGULATOR_SUPPLY("vdd_core", NULL),
55};
56
57static struct regulator_consumer_supply max77663_sd2_supply[] = {
58 REGULATOR_SUPPLY("vdd_gen1v8", NULL),
59 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
60 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
61 REGULATOR_SUPPLY("avdd_osc", NULL),
62 REGULATOR_SUPPLY("vddio_sys", NULL),
63 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.3"),
64 REGULATOR_SUPPLY("pwrdet_sdmmc4", NULL),
65 REGULATOR_SUPPLY("vddio_uart", NULL),
66 REGULATOR_SUPPLY("pwrdet_uart", NULL),
67 REGULATOR_SUPPLY("vddio_bb", NULL),
68 REGULATOR_SUPPLY("pwrdet_bb", NULL),
69 REGULATOR_SUPPLY("vddio_lcd_pmu", NULL),
70 REGULATOR_SUPPLY("pwrdet_lcd", NULL),
71 REGULATOR_SUPPLY("vddio_audio", NULL),
72 REGULATOR_SUPPLY("pwrdet_audio", NULL),
73 REGULATOR_SUPPLY("vddio_cam", NULL),
74 REGULATOR_SUPPLY("pwrdet_cam", NULL),
75 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.2"),
76 REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
77 REGULATOR_SUPPLY("vddio_vi", NULL),
78 REGULATOR_SUPPLY("pwrdet_vi", NULL),
79 REGULATOR_SUPPLY("vcore_nand", NULL),
80 REGULATOR_SUPPLY("pwrdet_nand", NULL),
81};
82
83static struct regulator_consumer_supply max77663_sd3_supply[] = {
84 REGULATOR_SUPPLY("vdd_ddr3l_1v35", NULL),
85};
86
87static struct regulator_consumer_supply max77663_ldo0_supply[] = {
88 REGULATOR_SUPPLY("vdd_ddr_hs", NULL),
89};
90
91static struct regulator_consumer_supply max77663_ldo1_supply[] = {
92};
93
94static struct regulator_consumer_supply max77663_ldo2_supply[] = {
95 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
96};
97
98static struct regulator_consumer_supply max77663_ldo3_supply[] = {
99 REGULATOR_SUPPLY("vmmc", NULL),
100};
101
102static struct regulator_consumer_supply max77663_ldo4_supply[] = {
103 REGULATOR_SUPPLY("vdd_rtc", NULL),
104};
105
106static struct regulator_consumer_supply max77663_ldo5_supply[] = {
107 REGULATOR_SUPPLY("vdd_sensor_2v8", NULL),
108};
109
110static struct regulator_consumer_supply max77663_ldo6_supply[] = {
111 REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.0"),
112 REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
113};
114
115static struct regulator_consumer_supply max77663_ldo7_supply[] = {
116 REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
117 REGULATOR_SUPPLY("pwrdet_mipi", NULL),
118};
119
120static struct regulator_consumer_supply max77663_ldo8_supply[] = {
121 REGULATOR_SUPPLY("avdd_plla_p_c_s", NULL),
122 REGULATOR_SUPPLY("avdd_pllm", NULL),
123 REGULATOR_SUPPLY("avdd_pllu_d", NULL),
124 REGULATOR_SUPPLY("avdd_pllu_d2", NULL),
125 REGULATOR_SUPPLY("avdd_pllx", NULL),
126};
127
128static struct max77663_regulator_fps_cfg max77663_fps_cfgs[] = {
129 {
130 .src = FPS_SRC_0,
131 .en_src = FPS_EN_SRC_EN0,
132 .time_period = FPS_TIME_PERIOD_DEF,
133 },
134 {
135 .src = FPS_SRC_1,
136 .en_src = FPS_EN_SRC_EN1,
137 .time_period = FPS_TIME_PERIOD_DEF,
138 },
139 {
140 .src = FPS_SRC_2,
141 .en_src = FPS_EN_SRC_EN0,
142 .time_period = FPS_TIME_PERIOD_DEF,
143 },
144};
145
146#define MAX77663_PDATA_INIT(_id, _min_uV, _max_uV, _supply_reg, \
147 _always_on, _boot_on, _apply_uV, \
148 _init_apply, _init_enable, _init_uV, \
149 _fps_src, _fps_pu_period, _fps_pd_period, _flags) \
150 static struct max77663_regulator_platform_data max77663_regulator_pdata_##_id = \
151 { \
152 .init_data = { \
153 .constraints = { \
154 .min_uV = _min_uV, \
155 .max_uV = _max_uV, \
156 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
157 REGULATOR_MODE_STANDBY), \
158 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
159 REGULATOR_CHANGE_STATUS | \
160 REGULATOR_CHANGE_VOLTAGE), \
161 .always_on = _always_on, \
162 .boot_on = _boot_on, \
163 .apply_uV = _apply_uV, \
164 }, \
165 .num_consumer_supplies = \
166 ARRAY_SIZE(max77663_##_id##_supply), \
167 .consumer_supplies = max77663_##_id##_supply, \
168 .supply_regulator = _supply_reg, \
169 }, \
170 .init_apply = _init_apply, \
171 .init_enable = _init_enable, \
172 .init_uV = _init_uV, \
173 .fps_src = _fps_src, \
174 .fps_pu_period = _fps_pu_period, \
175 .fps_pd_period = _fps_pd_period, \
176 .fps_cfgs = max77663_fps_cfgs, \
177 .flags = _flags, \
178 }
179
180MAX77663_PDATA_INIT(sd0, 600000, 3387500, NULL, 1, 0, 0,
181 0, 0, -1, FPS_SRC_NONE, -1, -1, EN2_CTRL_SD0 | SD_FSRADE_DISABLE);
182
183MAX77663_PDATA_INIT(sd1, 800000, 1587500, NULL, 1, 0, 0,
184 1, 1, -1, FPS_SRC_1, -1, -1, SD_FSRADE_DISABLE);
185
186MAX77663_PDATA_INIT(sd2, 1800000, 1800000, NULL, 1, 0, 0,
187 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
188
189MAX77663_PDATA_INIT(sd3, 600000, 3387500, NULL, 1, 0, 0,
190 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
191
192MAX77663_PDATA_INIT(ldo0, 800000, 2350000, max77663_rails(sd3), 1, 0, 0,
193 1, 1, -1, FPS_SRC_1, -1, -1, 0);
194
195MAX77663_PDATA_INIT(ldo1, 800000, 2350000, max77663_rails(sd3), 0, 0, 0,
196 0, 0, -1, FPS_SRC_NONE, -1, -1, 0);
197
198MAX77663_PDATA_INIT(ldo2, 800000, 3950000, NULL, 1, 0, 0,
199 1, 1, -1, FPS_SRC_1, -1, -1, 0);
200
201MAX77663_PDATA_INIT(ldo3, 800000, 3950000, NULL, 1, 0, 0,
202 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
203
204MAX77663_PDATA_INIT(ldo4, 800000, 1587500, NULL, 0, 0, 0,
205 1, 1, 1000000, FPS_SRC_NONE, -1, -1, LDO4_EN_TRACKING);
206
207MAX77663_PDATA_INIT(ldo5, 800000, 2800000, NULL, 0, 0, 0,
208 1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
209
210MAX77663_PDATA_INIT(ldo6, 800000, 3950000, NULL, 0, 0, 0,
211 0, 0, -1, FPS_SRC_NONE, -1, -1, 0);
212
213MAX77663_PDATA_INIT(ldo7, 800000, 3950000, max77663_rails(sd3), 0, 0, 0,
214 0, 0, -1, FPS_SRC_NONE, -1, -1, 0);
215
216MAX77663_PDATA_INIT(ldo8, 800000, 3950000, max77663_rails(sd3), 0, 0, 0,
217 1, 1, -1, FPS_SRC_1, -1, -1, 0);
218
219#define MAX77663_REG(_id, _data) \
220 { \
221 .name = "max77663-regulator", \
222 .id = MAX77663_REGULATOR_ID_##_id, \
223 .platform_data = &max77663_regulator_pdata_##_data, \
224 .pdata_size = sizeof(max77663_regulator_pdata_##_data), \
225 }
226
227#define MAX77663_RTC() \
228 { \
229 .name = "max77663-rtc", \
230 .id = 0, \
231 }
232
233static struct mfd_cell max77663_subdevs[] = {
234 MAX77663_REG(SD0, sd0),
235 MAX77663_REG(SD1, sd1),
236 MAX77663_REG(SD2, sd2),
237 MAX77663_REG(SD3, sd3),
238 MAX77663_REG(LDO0, ldo0),
239 MAX77663_REG(LDO1, ldo1),
240 MAX77663_REG(LDO2, ldo2),
241 MAX77663_REG(LDO3, ldo3),
242 MAX77663_REG(LDO4, ldo4),
243 MAX77663_REG(LDO5, ldo5),
244 MAX77663_REG(LDO6, ldo6),
245 MAX77663_REG(LDO7, ldo7),
246 MAX77663_REG(LDO8, ldo8),
247 MAX77663_RTC(),
248};
249
250static struct max77663_gpio_config max77663_gpio_cfgs[] = {
251 {
252 .gpio = MAX77663_GPIO0,
253 .dir = GPIO_DIR_OUT,
254 .dout = GPIO_DOUT_LOW,
255 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
256 .alternate = GPIO_ALT_DISABLE,
257 },
258 {
259 .gpio = MAX77663_GPIO1,
260 .dir = GPIO_DIR_IN,
261 .dout = GPIO_DOUT_LOW,
262 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
263 .alternate = GPIO_ALT_DISABLE,
264 },
265 {
266 .gpio = MAX77663_GPIO2,
267 .dir = GPIO_DIR_OUT,
268 .dout = GPIO_DOUT_HIGH,
269 .out_drv = GPIO_OUT_DRV_OPEN_DRAIN,
270 .alternate = GPIO_ALT_DISABLE,
271 },
272 {
273 .gpio = MAX77663_GPIO3,
274 .dir = GPIO_DIR_OUT,
275 .dout = GPIO_DOUT_HIGH,
276 .out_drv = GPIO_OUT_DRV_OPEN_DRAIN,
277 .alternate = GPIO_ALT_DISABLE,
278 },
279 {
280 .gpio = MAX77663_GPIO4,
281 .dir = GPIO_DIR_OUT,
282 .dout = GPIO_DOUT_HIGH,
283 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
284 .alternate = GPIO_ALT_ENABLE,
285 },
286 {
287 .gpio = MAX77663_GPIO5,
288 .dir = GPIO_DIR_OUT,
289 .dout = GPIO_DOUT_LOW,
290 .out_drv = GPIO_OUT_DRV_PUSH_PULL,
291 .alternate = GPIO_ALT_DISABLE,
292 },
293 {
294 .gpio = MAX77663_GPIO6,
295 .dir = GPIO_DIR_IN,
296 .alternate = GPIO_ALT_DISABLE,
297 },
298 {
299 .gpio = MAX77663_GPIO7,
300 .dir = GPIO_DIR_OUT,
301 .dout = GPIO_DOUT_LOW,
302 .out_drv = GPIO_OUT_DRV_OPEN_DRAIN,
303 .alternate = GPIO_ALT_DISABLE,
304 },
305};
306
307static struct max77663_platform_data max7763_pdata = {
308 .irq_base = MAX77663_IRQ_BASE,
309 .gpio_base = MAX77663_GPIO_BASE,
310
311 .num_gpio_cfgs = ARRAY_SIZE(max77663_gpio_cfgs),
312 .gpio_cfgs = max77663_gpio_cfgs,
313
314 .num_subdevs = ARRAY_SIZE(max77663_subdevs),
315 .sub_devices = max77663_subdevs,
316
317 .rtc_i2c_addr = 0x68,
318
319 .use_power_off = true,
320};
321
322static struct i2c_board_info __initdata max77663_regulators[] = {
323 {
324 /* The I2C address was determined by OTP factory setting */
325 I2C_BOARD_INFO("max77663", 0x3c),
326 .irq = INT_EXTERNAL_PMU,
327 .platform_data = &max7763_pdata,
328 },
329};
330
331static int __init kai_max77663_regulator_init(void)
332{
333 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
334 u32 pmc_ctrl;
335
336 /* configure the power management controller to trigger PMU
337 * interrupts when low */
338 pmc_ctrl = readl(pmc + PMC_CTRL);
339 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
340
341 i2c_register_board_info(4, max77663_regulators,
342 ARRAY_SIZE(max77663_regulators));
343
344 return 0;
345}
346
347static struct regulator_consumer_supply fixed_reg_en_3v3_sys_a00_supply[] = {
348 REGULATOR_SUPPLY("vdd_3v3", NULL),
349 REGULATOR_SUPPLY("vdd_3v3_devices", NULL),
350 REGULATOR_SUPPLY("debug_cons", NULL),
351 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
352};
353
354static struct regulator_consumer_supply fixed_reg_en_3v3_sys_a01_supply[] = {
355 REGULATOR_SUPPLY("vdd_3v3", NULL),
356 REGULATOR_SUPPLY("vdd_3v3_devices", NULL),
357 REGULATOR_SUPPLY("debug_cons", NULL),
358 REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
359 REGULATOR_SUPPLY("vddio_gmi", NULL),
360};
361
362static struct regulator_consumer_supply fixed_reg_en_avdd_hdmi_usb_a00_supply[] = {
363 REGULATOR_SUPPLY("avdd_hdmi", NULL),
364 REGULATOR_SUPPLY("avdd_usb", NULL),
365 REGULATOR_SUPPLY("vddio_gmi", NULL),
366};
367
368static struct regulator_consumer_supply fixed_reg_en_avdd_hdmi_usb_a01_supply[] = {
369 REGULATOR_SUPPLY("avdd_hdmi", NULL),
370 REGULATOR_SUPPLY("avdd_usb", NULL),
371};
372
373static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
374 REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
375 REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
376 REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
377};
378
379static struct regulator_consumer_supply fixed_reg_en_vddio_vid_supply[] = {
380 REGULATOR_SUPPLY("vdd_hdmi_con", NULL),
381};
382
383static struct regulator_consumer_supply fixed_reg_en_3v3_modem_supply[] = {
384 REGULATOR_SUPPLY("vdd_mini_card", NULL),
385};
386
387static struct regulator_consumer_supply fixed_reg_en_vdd_pnl_supply[] = {
388 REGULATOR_SUPPLY("vdd_lvds", NULL),
389 REGULATOR_SUPPLY("vdd_lcd_panel", NULL),
390 REGULATOR_SUPPLY("vdd_touch", NULL),
391 REGULATOR_SUPPLY("vddio_ts", NULL),
392};
393
394static struct regulator_consumer_supply fixed_reg_en_cam3_ldo_supply[] = {
395 REGULATOR_SUPPLY("vdd_cam3", NULL),
396};
397
398static struct regulator_consumer_supply fixed_reg_en_vdd_com_supply[] = {
399 REGULATOR_SUPPLY("vdd_com_bd", NULL),
400};
401
402static struct regulator_consumer_supply fixed_reg_en_vdd_sdmmc1_supply[] = {
403 REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.0"),
404};
405
406static struct regulator_consumer_supply fixed_reg_en_3v3_fuse_supply[] = {
407 REGULATOR_SUPPLY("vdd_fuse", NULL),
408};
409
410static struct regulator_consumer_supply fixed_reg_cdc_en_supply[] = {
411 REGULATOR_SUPPLY("cdc_en", NULL),
412};
413
414/* Macro for defining fixed regulator sub device data */
415#define FIXED_SUPPLY(_name) "fixed_reg_"#_name
416#define FIXED_REG(_id, _var, _name, _in_supply, _always_on, _boot_on, \
417 _gpio_nr, _active_high, _boot_state, _millivolts) \
418 static struct regulator_init_data ri_data_##_var = \
419 { \
420 .supply_regulator = _in_supply, \
421 .num_consumer_supplies = \
422 ARRAY_SIZE(fixed_reg_##_name##_supply), \
423 .consumer_supplies = fixed_reg_##_name##_supply, \
424 .constraints = { \
425 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
426 REGULATOR_MODE_STANDBY), \
427 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
428 REGULATOR_CHANGE_STATUS | \
429 REGULATOR_CHANGE_VOLTAGE), \
430 .always_on = _always_on, \
431 .boot_on = _boot_on, \
432 }, \
433 }; \
434 static struct fixed_voltage_config fixed_reg_##_var##_pdata = \
435 { \
436 .supply_name = FIXED_SUPPLY(_name), \
437 .microvolts = _millivolts * 1000, \
438 .gpio = _gpio_nr, \
439 .enable_high = _active_high, \
440 .enabled_at_boot = _boot_state, \
441 .init_data = &ri_data_##_var, \
442 }; \
443 static struct platform_device fixed_reg_##_var##_dev = { \
444 .name = "reg-fixed-voltage", \
445 .id = _id, \
446 .dev = { \
447 .platform_data = &fixed_reg_##_var##_pdata, \
448 }, \
449 }
450
451
452/* A00 specific */
453FIXED_REG(1, en_3v3_sys_a00, en_3v3_sys_a00, NULL,
454 1, 0, MAX77663_GPIO_BASE + MAX77663_GPIO3, true, 1, 3300);
455FIXED_REG(2, en_avdd_hdmi_usb_a00, en_avdd_hdmi_usb_a00, FIXED_SUPPLY(en_3v3_sys_a00),
456 1, 0, MAX77663_GPIO_BASE + MAX77663_GPIO2, true, 1, 3300);
457FIXED_REG(3, en_1v8_cam_a00, en_1v8_cam, max77663_rails(sd2),
458 0, 0, TEGRA_GPIO_PS0, true, 0, 1800);
459FIXED_REG(4, en_vddio_vid_a00, en_vddio_vid, NULL,
460 0, 0, TEGRA_GPIO_PB2, true, 0, 5000);
461FIXED_REG(5, en_3v3_modem_a00, en_3v3_modem, NULL,
462 1, 1, TEGRA_GPIO_PP0, true, 0, 3300);
463FIXED_REG(6, en_vdd_pnl_a00, en_vdd_pnl, FIXED_SUPPLY(en_3v3_sys_a00),
464 0, 0, TEGRA_GPIO_PW1, true, 0, 3300);
465FIXED_REG(7, en_cam3_ldo_a00, en_cam3_ldo, FIXED_SUPPLY(en_3v3_sys_a00),
466 0, 0, TEGRA_GPIO_PR7, true, 0, 3300);
467FIXED_REG(8, en_vdd_com_a00, en_vdd_com, FIXED_SUPPLY(en_3v3_sys_a00),
468 1, 0, TEGRA_GPIO_PD0, true, 0, 3300);
469FIXED_REG(9, en_vdd_sdmmc1_a00, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys_a00),
470 0, 0, TEGRA_GPIO_PC6, true, 0, 3300);
471FIXED_REG(10, en_3v3_fuse_a00, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys_a00),
472 0, 0, TEGRA_GPIO_PC1, true, 0, 3300);
473FIXED_REG(11, cdc_en_a00, cdc_en, max77663_rails(sd2),
474 0, 1, TEGRA_GPIO_PX2, true, 0, 1200);
475
476/* A01 specific */
477FIXED_REG(1, en_3v3_sys_a01, en_3v3_sys_a01, NULL,
478 1, 0, MAX77663_GPIO_BASE + MAX77663_GPIO3, true, 1, 3300);
479FIXED_REG(2, en_avdd_hdmi_usb_a01, en_avdd_hdmi_usb_a01, FIXED_SUPPLY(en_3v3_sys_a01),
480 0, 0, MAX77663_GPIO_BASE + MAX77663_GPIO2, true, 0, 3300);
481FIXED_REG(3, en_1v8_cam_a01, en_1v8_cam, max77663_rails(sd2),
482 0, 0, TEGRA_GPIO_PS0, true, 0, 1800);
483FIXED_REG(4, en_vddio_vid_a01, en_vddio_vid, NULL,
484 0, 0, TEGRA_GPIO_PB2, true, 0, 5000);
485FIXED_REG(5, en_3v3_modem_a01, en_3v3_modem, NULL,
486 1, 1, TEGRA_GPIO_PP0, true, 0, 3300);
487FIXED_REG(6, en_vdd_pnl_a01, en_vdd_pnl, FIXED_SUPPLY(en_3v3_sys_a01),
488 0, 0, TEGRA_GPIO_PW1, true, 0, 3300);
489FIXED_REG(7, en_cam3_ldo_a01, en_cam3_ldo, FIXED_SUPPLY(en_3v3_sys_a01),
490 0, 0, TEGRA_GPIO_PR7, true, 0, 3300);
491FIXED_REG(8, en_vdd_com_a01, en_vdd_com, FIXED_SUPPLY(en_3v3_sys_a01),
492 1, 0, TEGRA_GPIO_PD0, true, 0, 3300);
493FIXED_REG(9, en_vdd_sdmmc1_a01, en_vdd_sdmmc1, FIXED_SUPPLY(en_3v3_sys_a01),
494 0, 0, TEGRA_GPIO_PC6, true, 0, 3300);
495FIXED_REG(10, en_3v3_fuse_a01, en_3v3_fuse, FIXED_SUPPLY(en_3v3_sys_a01),
496 0, 0, TEGRA_GPIO_PC1, true, 0, 3300);
497FIXED_REG(11, cdc_en_a01, cdc_en, max77663_rails(sd2),
498 0, 1, TEGRA_GPIO_PX2, true, 0, 1200);
499
500/*
501 * Creating the fixed regulator device tables
502 */
503
504#define ADD_FIXED_REG(_name) (&fixed_reg_##_name##_dev)
505
506/* A00 specific */
507#define E1565_A00_FIXED_REG \
508 ADD_FIXED_REG(en_3v3_sys_a00), \
509 ADD_FIXED_REG(en_avdd_hdmi_usb_a00), \
510 ADD_FIXED_REG(en_1v8_cam_a00), \
511 ADD_FIXED_REG(en_vddio_vid_a00), \
512 ADD_FIXED_REG(en_3v3_modem_a00), \
513 ADD_FIXED_REG(en_vdd_pnl_a00), \
514 ADD_FIXED_REG(en_cam3_ldo_a00), \
515 ADD_FIXED_REG(en_vdd_com_a00), \
516 ADD_FIXED_REG(en_vdd_sdmmc1_a00), \
517 ADD_FIXED_REG(en_3v3_fuse_a00), \
518 ADD_FIXED_REG(cdc_en_a00), \
519
520/* A01 specific */
521#define E1565_A01_FIXED_REG \
522 ADD_FIXED_REG(en_3v3_sys_a01), \
523 ADD_FIXED_REG(en_avdd_hdmi_usb_a01), \
524 ADD_FIXED_REG(en_1v8_cam_a01), \
525 ADD_FIXED_REG(en_vddio_vid_a01), \
526 ADD_FIXED_REG(en_3v3_modem_a01), \
527 ADD_FIXED_REG(en_vdd_pnl_a01), \
528 ADD_FIXED_REG(en_cam3_ldo_a01), \
529 ADD_FIXED_REG(en_vdd_com_a01), \
530 ADD_FIXED_REG(en_vdd_sdmmc1_a01), \
531 ADD_FIXED_REG(en_3v3_fuse_a01), \
532 ADD_FIXED_REG(cdc_en_a01), \
533
534/* Gpio switch regulator platform data for Kai A00 */
535static struct platform_device *fixed_reg_devs_a00[] = {
536 E1565_A00_FIXED_REG
537};
538
539/* Gpio switch regulator platform data for Kai A01 */
540static struct platform_device *fixed_reg_devs_a01[] = {
541 E1565_A01_FIXED_REG
542};
543
544static int __init kai_fixed_regulator_init(void)
545{
546 int i;
547 struct board_info board_info;
548 struct platform_device **fixed_reg_devs;
549 int nfixreg_devs;
550
551 tegra_get_board_info(&board_info);
552
553 if (board_info.fab == BOARD_FAB_A00) {
554 fixed_reg_devs = fixed_reg_devs_a00;
555 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_a00);
556 } else {
557 fixed_reg_devs = fixed_reg_devs_a01;
558 nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_a01);
559 }
560
561 if (!machine_is_kai())
562 return 0;
563
564 for (i = 0; i < nfixreg_devs; ++i) {
565 int gpio_nr;
566 struct fixed_voltage_config *fixed_reg_pdata =
567 fixed_reg_devs[i]->dev.platform_data;
568 gpio_nr = fixed_reg_pdata->gpio;
569
570 if (gpio_nr < TEGRA_NR_GPIOS)
571 tegra_gpio_enable(gpio_nr);
572 }
573
574 return platform_add_devices(fixed_reg_devs, nfixreg_devs);
575}
576subsys_initcall_sync(kai_fixed_regulator_init);
577
578int __init kai_regulator_init(void)
579{
580 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
581 u32 pmc_ctrl;
582 int ret;
583
584 /* configure the power management controller to trigger PMU
585 * interrupts when low */
586
587 pmc_ctrl = readl(pmc + PMC_CTRL);
588 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
589
590 ret = kai_max77663_regulator_init();
591 if (ret < 0)
592 return ret;
593
594 return 0;
595}
596
597static void kai_board_suspend(int lp_state, enum suspend_stage stg)
598{
599 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
600 tegra_console_uart_suspend();
601}
602
603static void kai_board_resume(int lp_state, enum resume_stage stg)
604{
605 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
606 tegra_console_uart_resume();
607}
608
609static struct tegra_suspend_platform_data kai_suspend_data = {
610 .cpu_timer = 2000,
611 .cpu_off_timer = 200,
612 .suspend_mode = TEGRA_SUSPEND_LP0,
613 .core_timer = 0x7e7e,
614 .core_off_timer = 0,
615 .corereq_high = true,
616 .sysclkreq_high = true,
617 .cpu_lp2_min_residency = 2000,
618 .board_suspend = kai_board_suspend,
619 .board_resume = kai_board_resume,
620};
621
622int __init kai_suspend_init(void)
623{
624 tegra_init_suspend(&kai_suspend_data);
625 return 0;
626}
627
628static struct tegra_tsensor_pmu_data tpdata = {
629 .poweroff_reg_addr = 0x3F,
630 .poweroff_reg_data = 0x80,
631 .reset_tegra = 1,
632 .controller_type = 0,
633 .i2c_controller_id = 4,
634 .pinmux = 0,
635 .pmu_16bit_ops = 0,
636 .pmu_i2c_addr = 0x2D,
637};
638
639void __init kai_tsensor_init(void)
640{
641 tegra3_tsensor_init(&tpdata);
642}
643
644#ifdef CONFIG_TEGRA_EDP_LIMITS
645
646int __init kai_edp_init(void)
647{
648 unsigned int regulator_mA;
649
650 regulator_mA = get_maximum_cpu_current_supported();
651 if (!regulator_mA)
652 regulator_mA = 6000; /* regular T30/s */
653 pr_info("%s: CPU regulator %d mA\n", __func__, regulator_mA);
654
655 tegra_init_cpu_edp_limits(regulator_mA);
656 return 0;
657}
658#endif
diff --git a/arch/arm/mach-tegra/board-kai-sdhci.c b/arch/arm/mach-tegra/board-kai-sdhci.c
new file mode 100644
index 00000000000..3e489927108
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-sdhci.c
@@ -0,0 +1,267 @@
1/*
2 * arch/arm/mach-tegra/board-kai-sdhci.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2012 NVIDIA Corporation.
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/resource.h>
19#include <linux/platform_device.h>
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/mmc/host.h>
25#include <linux/wl12xx.h>
26
27#include <asm/mach-types.h>
28#include <mach/irqs.h>
29#include <mach/iomap.h>
30#include <mach/sdhci.h>
31
32#include "gpio-names.h"
33#include "board.h"
34#include "board-kai.h"
35
36#define KAI_SD_CD TEGRA_GPIO_PI5
37#define KAI_WLAN_EN TEGRA_GPIO_PD3
38#define KAI_WLAN_IRQ TEGRA_GPIO_PV1
39
40static void (*wifi_status_cb)(int card_present, void *dev_id);
41static void *wifi_status_cb_devid;
42static int kai_wifi_power(int power_on);
43static int kai_wifi_set_carddetect(int val);
44
45static int kai_wifi_status_register(
46 void (*callback)(int card_present, void *dev_id),
47 void *dev_id)
48{
49 if (wifi_status_cb)
50 return -EAGAIN;
51 wifi_status_cb = callback;
52 wifi_status_cb_devid = dev_id;
53 return 0;
54}
55
56
57static struct wl12xx_platform_data kai_wlan_data __initdata = {
58 .irq = TEGRA_GPIO_TO_IRQ(KAI_WLAN_IRQ),
59 .board_ref_clock = WL12XX_REFCLOCK_26,
60 .board_tcxo_clock = 1,
61 .set_power = kai_wifi_power,
62 .set_carddetect = kai_wifi_set_carddetect,
63};
64
65static struct resource sdhci_resource0[] = {
66 [0] = {
67 .start = INT_SDMMC1,
68 .end = INT_SDMMC1,
69 .flags = IORESOURCE_IRQ,
70 },
71 [1] = {
72 .start = TEGRA_SDMMC1_BASE,
73 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
74 .flags = IORESOURCE_MEM,
75 },
76};
77
78static struct resource sdhci_resource2[] = {
79 [0] = {
80 .start = INT_SDMMC3,
81 .end = INT_SDMMC3,
82 .flags = IORESOURCE_IRQ,
83 },
84 [1] = {
85 .start = TEGRA_SDMMC3_BASE,
86 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
87 .flags = IORESOURCE_MEM,
88 },
89};
90
91static struct resource sdhci_resource3[] = {
92 [0] = {
93 .start = INT_SDMMC4,
94 .end = INT_SDMMC4,
95 .flags = IORESOURCE_IRQ,
96 },
97 [1] = {
98 .start = TEGRA_SDMMC4_BASE,
99 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
100 .flags = IORESOURCE_MEM,
101 },
102};
103
104static struct embedded_sdio_data embedded_sdio_data2 = {
105 .cccr = {
106 .sdio_vsn = 2,
107 .multi_block = 1,
108 .low_speed = 0,
109 .wide_bus = 0,
110 .high_power = 1,
111 .high_speed = 1,
112 },
113 .cis = {
114 .vendor = 0x0097,
115 .device = 0x4076,
116 },
117};
118
119static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
120 .mmc_data = {
121 .register_status_notify = kai_wifi_status_register,
122 /* .embedded_sdio = &embedded_sdio_data2, */
123 .built_in = 1,
124 },
125 .cd_gpio = -1,
126 .wp_gpio = -1,
127 .power_gpio = -1,
128/* .tap_delay = 6,
129 .is_voltage_switch_supported = false,
130 .vdd_rail_name = NULL,
131 .slot_rail_name = NULL,
132 .vdd_max_uv = -1,
133 .vdd_min_uv = -1,
134 .max_clk = 0,
135 .is_8bit_supported = false, */
136 /* .max_clk = 25000000, */
137};
138
139static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
140 .cd_gpio = KAI_SD_CD,
141 .wp_gpio = -1,
142 .power_gpio = -1,
143/* .tap_delay = 6,
144 .is_voltage_switch_supported = true,
145 .vdd_rail_name = "vddio_sdmmc1",
146 .slot_rail_name = "vddio_sd_slot",
147 .vdd_max_uv = 3320000,
148 .vdd_min_uv = 3280000,
149 .max_clk = 208000000,
150 .is_8bit_supported = false, */
151};
152
153static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
154 .cd_gpio = -1,
155 .wp_gpio = -1,
156 .power_gpio = -1,
157 .is_8bit = 1,
158 .tap_delay = 0x0F,
159 .mmc_data = {
160 .built_in = 1,
161 }
162/* .tap_delay = 6,
163 .is_voltage_switch_supported = false,
164 .vdd_rail_name = NULL,
165 .slot_rail_name = NULL,
166 .vdd_max_uv = -1,
167 .vdd_min_uv = -1,
168 .max_clk = 48000000,
169 .is_8bit_supported = true, */
170};
171
172static struct platform_device tegra_sdhci_device0 = {
173 .name = "sdhci-tegra",
174 .id = 0,
175 .resource = sdhci_resource0,
176 .num_resources = ARRAY_SIZE(sdhci_resource0),
177 .dev = {
178 .platform_data = &tegra_sdhci_platform_data0,
179 },
180};
181
182static struct platform_device tegra_sdhci_device2 = {
183 .name = "sdhci-tegra",
184 .id = 2,
185 .resource = sdhci_resource2,
186 .num_resources = ARRAY_SIZE(sdhci_resource2),
187 .dev = {
188 .platform_data = &tegra_sdhci_platform_data2,
189 },
190};
191
192static struct platform_device tegra_sdhci_device3 = {
193 .name = "sdhci-tegra",
194 .id = 3,
195 .resource = sdhci_resource3,
196 .num_resources = ARRAY_SIZE(sdhci_resource3),
197 .dev = {
198 .platform_data = &tegra_sdhci_platform_data3,
199 },
200};
201
202static int kai_wifi_set_carddetect(int val)
203{
204 pr_debug("%s: %d\n", __func__, val);
205 if (wifi_status_cb)
206 wifi_status_cb(val, wifi_status_cb_devid);
207 else
208 pr_warning("%s: Nobody to notify\n", __func__);
209 return 0;
210}
211
212static int kai_wifi_power(int power_on)
213{
214 pr_err("Powering %s wifi\n", (power_on ? "on" : "off"));
215
216 if (power_on) {
217 gpio_set_value(KAI_WLAN_EN, 1);
218 mdelay(15);
219 gpio_set_value(KAI_WLAN_EN, 0);
220 mdelay(1);
221 gpio_set_value(KAI_WLAN_EN, 1);
222 mdelay(70);
223 } else {
224 gpio_set_value(KAI_WLAN_EN, 0);
225 }
226
227 return 0;
228}
229
230static int __init kai_wifi_init(void)
231{
232 int rc;
233
234 rc = gpio_request(KAI_WLAN_EN, "wl12xx");
235 if (rc)
236 pr_err("WLAN_EN gpio request failed:%d\n", rc);
237
238 rc = gpio_request(KAI_WLAN_IRQ, "wl12xx");
239 if (rc)
240 pr_err("WLAN_IRQ gpio request failed:%d\n", rc);
241
242 tegra_gpio_enable(KAI_WLAN_EN);
243 tegra_gpio_enable(KAI_WLAN_IRQ);
244
245 rc = gpio_direction_output(KAI_WLAN_EN, 0);
246 if (rc)
247 pr_err("WLAN_EN gpio direction configuration failed:%d\n", rc);
248
249 rc = gpio_direction_input(KAI_WLAN_IRQ);
250 if (rc)
251 pr_err("WLAN_IRQ gpio direction configuration failed:%d\n", rc);
252
253 if (wl12xx_set_platform_data(&kai_wlan_data))
254 pr_err("Error setting wl12xx data\n");
255
256 return 0;
257}
258
259int __init kai_sdhci_init(void)
260{
261 platform_device_register(&tegra_sdhci_device3);
262 platform_device_register(&tegra_sdhci_device2);
263 platform_device_register(&tegra_sdhci_device0);
264
265 kai_wifi_init();
266 return 0;
267}
diff --git a/arch/arm/mach-tegra/board-kai-sensors.c b/arch/arm/mach-tegra/board-kai-sensors.c
new file mode 100644
index 00000000000..82784ebd973
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-sensors.c
@@ -0,0 +1,259 @@
1
2/*
3 * arch/arm/mach-tegra/board-kai-sensors.c
4 *
5 * Copyright (c) 2012, NVIDIA Corporation.
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, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/err.h>
23#include <linux/i2c.h>
24#include <linux/cm3217.h>
25#include <linux/mpu.h>
26#include <linux/regulator/consumer.h>
27#include <asm/mach-types.h>
28#include <mach/gpio.h>
29#include <media/ov2710.h>
30#include "board.h"
31#include "board-kai.h"
32#include "cpu-tegra.h"
33
34static struct regulator *kai_1v8_cam3;
35static struct regulator *kai_vdd_cam3;
36
37static struct cm3217_platform_data kai_cm3217_pdata = {
38 .levels = {10, 160, 225, 320, 640, 1280, 2600, 5800, 8000, 10240},
39 .golden_adc = 0,
40 .power = 0,
41};
42
43static struct i2c_board_info kai_i2c0_cm3217_board_info[] = {
44 {
45 I2C_BOARD_INFO("cm3217", 0x10),
46 .platform_data = &kai_cm3217_pdata,
47 },
48};
49
50static int kai_camera_init(void)
51{
52 int ret;
53
54 tegra_gpio_enable(CAM2_POWER_DWN_GPIO);
55 ret = gpio_request(CAM2_POWER_DWN_GPIO, "cam2_power_en");
56 if (ret < 0) {
57 pr_err("%s: gpio_request failed for gpio %s\n",
58 __func__, "CAM2_POWER_DWN_GPIO");
59 }
60
61 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
62 mdelay(10);
63
64 tegra_gpio_enable(CAM2_RST_GPIO);
65 ret = gpio_request(CAM2_RST_GPIO, "cam2_reset");
66 if (ret < 0) {
67 pr_err("%s: gpio_request failed for gpio %s\n",
68 __func__, "CAM2_RST_GPIO");
69 }
70
71 gpio_direction_output(CAM2_RST_GPIO, 0);
72 mdelay(5);
73
74 return 0;
75}
76
77static int kai_ov2710_power_on(void)
78{
79 gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
80 mdelay(10);
81
82 if (kai_vdd_cam3 == NULL) {
83 kai_vdd_cam3 = regulator_get(NULL, "vdd_cam3");
84 if (WARN_ON(IS_ERR(kai_vdd_cam3))) {
85 pr_err("%s: couldn't get regulator vdd_cam3: %d\n",
86 __func__, PTR_ERR(kai_vdd_cam3));
87 goto reg_get_vdd_cam3_fail;
88 }
89 }
90 regulator_enable(kai_vdd_cam3);
91
92 if (kai_1v8_cam3 == NULL) {
93 kai_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3");
94 if (WARN_ON(IS_ERR(kai_1v8_cam3))) {
95 pr_err("%s: couldn't get regulator vdd_1v8_cam3: %d\n",
96 __func__, PTR_ERR(kai_1v8_cam3));
97 goto reg_get_vdd_1v8_cam3_fail;
98 }
99 }
100 regulator_enable(kai_1v8_cam3);
101 mdelay(5);
102
103 gpio_direction_output(CAM2_RST_GPIO, 1);
104 mdelay(10);
105
106 return 0;
107
108reg_get_vdd_1v8_cam3_fail:
109 kai_1v8_cam3 = NULL;
110 regulator_put(kai_vdd_cam3);
111
112reg_get_vdd_cam3_fail:
113 kai_vdd_cam3 = NULL;
114
115 return -ENODEV;
116}
117
118static int kai_ov2710_power_off(void)
119{
120 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
121
122 gpio_direction_output(CAM2_RST_GPIO, 0);
123
124 if (kai_1v8_cam3)
125 regulator_disable(kai_1v8_cam3);
126 if (kai_vdd_cam3)
127 regulator_disable(kai_vdd_cam3);
128
129 return 0;
130}
131
132struct ov2710_platform_data kai_ov2710_data = {
133 .power_on = kai_ov2710_power_on,
134 .power_off = kai_ov2710_power_off,
135};
136
137static struct i2c_board_info kai_i2c2_board_info[] = {
138 {
139 I2C_BOARD_INFO("ov2710", 0x36),
140 .platform_data = &kai_ov2710_data,
141 },
142};
143
144/* MPU board file definition */
145
146#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
147#define MPU_GYRO_NAME "mpu3050"
148#endif
149#if (MPU_GYRO_TYPE == MPU_TYPE_MPU6050)
150#define MPU_GYRO_NAME "mpu6050"
151#endif
152
153static struct mpu_platform_data mpu_gyro_data = {
154 .int_config = 0x10,
155 .level_shifter = 0,
156 .orientation = MPU_GYRO_ORIENTATION,
157};
158
159#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
160static struct ext_slave_platform_data mpu_accel_data = {
161 .address = MPU_ACCEL_ADDR,
162 .irq = 0,
163 .adapt_num = MPU_ACCEL_BUS_NUM,
164 .bus = EXT_SLAVE_BUS_SECONDARY,
165 .orientation = MPU_ACCEL_ORIENTATION,
166};
167#endif
168
169static struct ext_slave_platform_data mpu_compass_data = {
170 .address = MPU_COMPASS_ADDR,
171 .irq = 0,
172 .adapt_num = MPU_COMPASS_BUS_NUM,
173 .bus = EXT_SLAVE_BUS_PRIMARY,
174 .orientation = MPU_COMPASS_ORIENTATION,
175};
176
177static struct i2c_board_info __initdata inv_mpu_i2c0_board_info[] = {
178 {
179 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
180 .irq = TEGRA_GPIO_TO_IRQ(MPU_GYRO_IRQ_GPIO),
181 .platform_data = &mpu_gyro_data,
182 },
183#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
184 {
185 I2C_BOARD_INFO(MPU_ACCEL_NAME, MPU_ACCEL_ADDR),
186#if MPU_ACCEL_IRQ_GPIO
187 .irq = TEGRA_GPIO_TO_IRQ(MPU_ACCEL_IRQ_GPIO),
188#endif
189 .platform_data = &mpu_accel_data,
190 },
191#endif
192 {
193 I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
194#if MPU_COMPASS_IRQ_GPIO
195 .irq = TEGRA_GPIO_TO_IRQ(MPU_COMPASS_IRQ_GPIO),
196#endif
197 .platform_data = &mpu_compass_data,
198 },
199};
200
201static void mpuirq_init(void)
202{
203 int ret = 0;
204
205 pr_info("*** MPU START *** mpuirq_init...\n");
206
207#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
208#if MPU_ACCEL_IRQ_GPIO
209 /* ACCEL-IRQ assignment */
210 tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
211 ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
212 if (ret < 0) {
213 pr_err("%s: gpio_request failed %d\n", __func__, ret);
214 return;
215 }
216
217 ret = gpio_direction_input(MPU_ACCEL_IRQ_GPIO);
218 if (ret < 0) {
219 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
220 gpio_free(MPU_ACCEL_IRQ_GPIO);
221 return;
222 }
223#endif
224#endif
225
226 /* MPU-IRQ assignment */
227 tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
228 ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
229 if (ret < 0) {
230 pr_err("%s: gpio_request failed %d\n", __func__, ret);
231 return;
232 }
233
234 ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO);
235 if (ret < 0) {
236 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
237 gpio_free(MPU_GYRO_IRQ_GPIO);
238 return;
239 }
240 pr_info("*** MPU END *** mpuirq_init...\n");
241
242 i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c0_board_info,
243 ARRAY_SIZE(inv_mpu_i2c0_board_info));
244}
245
246int __init kai_sensors_init(void)
247{
248 kai_camera_init();
249
250 i2c_register_board_info(2, kai_i2c2_board_info,
251 ARRAY_SIZE(kai_i2c2_board_info));
252
253 i2c_register_board_info(0, kai_i2c0_cm3217_board_info,
254 ARRAY_SIZE(kai_i2c0_cm3217_board_info));
255
256 mpuirq_init();
257
258 return 0;
259}
diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c
new file mode 100644
index 00000000000..487f26ad7a2
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai.c
@@ -0,0 +1,854 @@
1/*
2 * arch/arm/mach-tegra/board-kai.c
3 *
4 * Copyright (c) 2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/ctype.h>
24#include <linux/platform_device.h>
25#include <linux/clk.h>
26#include <linux/serial_8250.h>
27#include <linux/i2c.h>
28#include <linux/dma-mapping.h>
29#include <linux/delay.h>
30#include <linux/i2c-tegra.h>
31#include <linux/gpio.h>
32#include <linux/input.h>
33#include <linux/platform_data/tegra_usb.h>
34#include <linux/spi/spi.h>
35#include <linux/tegra_uart.h>
36#include <linux/memblock.h>
37#include <linux/spi-tegra.h>
38#include <linux/nfc/pn544.h>
39#include <linux/skbuff.h>
40#include <linux/ti_wilink_st.h>
41#include <linux/regulator/consumer.h>
42#include <linux/smb349-charger.h>
43#include <linux/max17048_battery.h>
44#include <linux/leds.h>
45#include <linux/i2c/at24.h>
46
47#include <mach/clk.h>
48#include <mach/iomap.h>
49#include <mach/irqs.h>
50#include <mach/pinmux.h>
51#include <mach/iomap.h>
52#include <mach/io.h>
53#include <mach/i2s.h>
54#include <mach/tegra_rt5640_pdata.h>
55#include <asm/mach-types.h>
56#include <asm/mach/arch.h>
57#include <mach/usb_phy.h>
58#include <mach/thermal.h>
59
60#include "board.h"
61#include "clock.h"
62#include "board-kai.h"
63#include "devices.h"
64#include "gpio-names.h"
65#include "fuse.h"
66#include "pm.h"
67#include "wdt-recovery.h"
68
69/* All units are in millicelsius */
70static struct tegra_thermal_data thermal_data = {
71 .temp_throttle = 85000,
72 .temp_shutdown = 90000,
73 .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */
74#ifdef CONFIG_TEGRA_EDP_LIMITS
75 .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */
76 .hysteresis_edp = 3000,
77#endif
78#ifdef CONFIG_TEGRA_THERMAL_SYSFS
79 .tc1 = 0,
80 .tc2 = 1,
81 .passive_delay = 2000,
82#else
83 .hysteresis_throttle = 1000,
84#endif
85};
86
87/* !!!TODO: Change for kai (Taken from Ventana) */
88static struct tegra_utmip_config utmi_phy_config[] = {
89 [0] = {
90 .hssync_start_delay = 0,
91 .idle_wait_delay = 17,
92 .elastic_limit = 16,
93 .term_range_adj = 6,
94 .xcvr_setup = 15,
95 .xcvr_setup_offset = 0,
96 .xcvr_use_fuses = 1,
97 .xcvr_lsfslew = 2,
98 .xcvr_lsrslew = 2,
99 },
100 [1] = {
101 .hssync_start_delay = 0,
102 .idle_wait_delay = 17,
103 .elastic_limit = 16,
104 .term_range_adj = 6,
105 .xcvr_setup = 15,
106 .xcvr_setup_offset = 0,
107 .xcvr_use_fuses = 1,
108 .xcvr_lsfslew = 2,
109 .xcvr_lsrslew = 2,
110 },
111 [2] = {
112 .hssync_start_delay = 0,
113 .idle_wait_delay = 17,
114 .elastic_limit = 16,
115 .term_range_adj = 6,
116 .xcvr_setup = 8,
117 .xcvr_setup_offset = 0,
118 .xcvr_use_fuses = 1,
119 .xcvr_lsfslew = 2,
120 .xcvr_lsrslew = 2,
121 },
122};
123
124/* wl128x BT, FM, GPS connectivity chip */
125struct ti_st_plat_data kai_wilink_pdata = {
126 .nshutdown_gpio = TEGRA_GPIO_PU0,
127 .dev_name = BLUETOOTH_UART_DEV_NAME,
128 .flow_cntrl = 1,
129 .baud_rate = 3000000,
130};
131
132static struct platform_device wl128x_device = {
133 .name = "kim",
134 .id = -1,
135 .dev.platform_data = &kai_wilink_pdata,
136};
137
138static struct platform_device btwilink_device = {
139 .name = "btwilink",
140 .id = -1,
141};
142
143static noinline void __init kai_bt_st(void)
144{
145 pr_info("kai_bt_st");
146
147 platform_device_register(&wl128x_device);
148 platform_device_register(&btwilink_device);
149 tegra_gpio_enable(TEGRA_GPIO_PU0);
150}
151
152static struct resource kai_bluesleep_resources[] = {
153 [0] = {
154 .name = "host_wake",
155 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
156 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
157 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
158 },
159};
160
161static struct platform_device kai_bluesleep_device = {
162 .name = "tibluesleep",
163 .id = 0,
164 .num_resources = ARRAY_SIZE(kai_bluesleep_resources),
165 .resource = kai_bluesleep_resources,
166};
167
168static noinline void __init kai_tegra_setup_tibluesleep(void)
169{
170 platform_device_register(&kai_bluesleep_device);
171 tegra_gpio_enable(TEGRA_GPIO_PU6);
172}
173
174static __initdata struct tegra_clk_init_table kai_clk_init_table[] = {
175 /* name parent rate enabled */
176 { "pll_m", NULL, 0, false},
177 { "hda", "pll_p", 108000000, false},
178 { "hda2codec_2x", "pll_p", 48000000, false},
179 { "pwm", "pll_p", 3187500, false},
180 { "blink", "clk_32k", 32768, true},
181 { "i2s1", "pll_a_out0", 0, false},
182 { "i2s3", "pll_a_out0", 0, false},
183 { "i2s4", "pll_a_out0", 0, false},
184 { "spdif_out", "pll_a_out0", 0, false},
185 { "d_audio", "clk_m", 12000000, false},
186 { "dam0", "clk_m", 12000000, false},
187 { "dam1", "clk_m", 12000000, false},
188 { "dam2", "clk_m", 12000000, false},
189 { "audio1", "i2s1_sync", 0, false},
190 { "audio3", "i2s3_sync", 0, false},
191 { "vi_sensor", "pll_p", 150000000, false},
192 { "i2c1", "pll_p", 3200000, false},
193 { "i2c2", "pll_p", 3200000, false},
194 { "i2c3", "pll_p", 3200000, false},
195 { "i2c4", "pll_p", 3200000, false},
196 { "i2c5", "pll_p", 3200000, false},
197 { NULL, NULL, 0, 0},
198};
199
200static struct pn544_i2c_platform_data nfc_pdata = {
201 .irq_gpio = TEGRA_GPIO_PX0,
202 .ven_gpio = TEGRA_GPIO_PS7,
203 .firm_gpio = TEGRA_GPIO_PR3,
204};
205
206static struct i2c_board_info __initdata kai_nfc_board_info[] = {
207 {
208 I2C_BOARD_INFO("pn544", 0x28),
209 .platform_data = &nfc_pdata,
210 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PX0),
211 },
212};
213
214static struct tegra_i2c_platform_data kai_i2c1_platform_data = {
215 .adapter_nr = 0,
216 .bus_count = 1,
217 .bus_clk_rate = { 100000, 0 },
218 .scl_gpio = {TEGRA_GPIO_PC4, 0},
219 .sda_gpio = {TEGRA_GPIO_PC5, 0},
220 .arb_recovery = arb_lost_recovery,
221};
222
223static struct tegra_i2c_platform_data kai_i2c2_platform_data = {
224 .adapter_nr = 1,
225 .bus_count = 1,
226 .bus_clk_rate = { 100000, 0 },
227 .is_clkon_always = true,
228 .scl_gpio = {TEGRA_GPIO_PT5, 0},
229 .sda_gpio = {TEGRA_GPIO_PT6, 0},
230 .arb_recovery = arb_lost_recovery,
231};
232
233static struct tegra_i2c_platform_data kai_i2c3_platform_data = {
234 .adapter_nr = 2,
235 .bus_count = 1,
236 .bus_clk_rate = { 100000, 0 },
237 .scl_gpio = {TEGRA_GPIO_PBB1, 0},
238 .sda_gpio = {TEGRA_GPIO_PBB2, 0},
239 .arb_recovery = arb_lost_recovery,
240};
241
242static struct tegra_i2c_platform_data kai_i2c4_platform_data = {
243 .adapter_nr = 3,
244 .bus_count = 1,
245 .bus_clk_rate = { 100000, 0 },
246 .scl_gpio = {TEGRA_GPIO_PV4, 0},
247 .sda_gpio = {TEGRA_GPIO_PV5, 0},
248 .arb_recovery = arb_lost_recovery,
249};
250
251static struct tegra_i2c_platform_data kai_i2c5_platform_data = {
252 .adapter_nr = 4,
253 .bus_count = 1,
254 .bus_clk_rate = { 400000, 0 },
255 .scl_gpio = {TEGRA_GPIO_PZ6, 0},
256 .sda_gpio = {TEGRA_GPIO_PZ7, 0},
257 .arb_recovery = arb_lost_recovery,
258};
259
260struct max17048_battery_model max17048_mdata = {
261 .rcomp = 170,
262 .soccheck_A = 252,
263 .soccheck_B = 254,
264 .bits = 19,
265 .alert_threshold = 0x00,
266 .one_percent_alerts = 0x40,
267 .alert_on_reset = 0x40,
268 .rcomp_seg = 0x0800,
269 .hibernate = 0x3080,
270 .vreset = 0x9696,
271 .valert = 0xD4AA,
272 .ocvtest = 55600,
273};
274
275
276static struct at24_platform_data eeprom_info = {
277 .byte_len = (256*1024)/8,
278 .page_size = 64,
279 .flags = AT24_FLAG_ADDR16,
280 .setup = get_mac_addr,
281};
282
283static struct i2c_board_info kai_i2c4_max17048_board_info[] = {
284 {
285 I2C_BOARD_INFO("max17048", 0x36),
286 .platform_data = &max17048_mdata,
287 },
288};
289
290static struct i2c_board_info kai_eeprom_mac_add = {
291 I2C_BOARD_INFO("at24", 0x56),
292 .platform_data = &eeprom_info,
293};
294
295static struct i2c_board_info kai_i2c4_smb349_board_info[] = {
296 {
297 I2C_BOARD_INFO("smb349", 0x1B),
298 .irq = MAX77663_GPIO_BASE + MAX77663_GPIO1,
299 },
300};
301
302static struct i2c_board_info __initdata rt5640_board_info = {
303 I2C_BOARD_INFO("rt5640", 0x1c),
304 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
305};
306
307static struct i2c_board_info __initdata rt5639_board_info = {
308 I2C_BOARD_INFO("rt5639", 0x1c),
309 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
310};
311
312static void kai_i2c_init(void)
313{
314 struct board_info board_info;
315
316 tegra_get_board_info(&board_info);
317
318 tegra_i2c_device1.dev.platform_data = &kai_i2c1_platform_data;
319 tegra_i2c_device2.dev.platform_data = &kai_i2c2_platform_data;
320 tegra_i2c_device3.dev.platform_data = &kai_i2c3_platform_data;
321 tegra_i2c_device4.dev.platform_data = &kai_i2c4_platform_data;
322 tegra_i2c_device5.dev.platform_data = &kai_i2c5_platform_data;
323
324 platform_device_register(&tegra_i2c_device5);
325 platform_device_register(&tegra_i2c_device4);
326 platform_device_register(&tegra_i2c_device3);
327 platform_device_register(&tegra_i2c_device2);
328 platform_device_register(&tegra_i2c_device1);
329
330 i2c_register_board_info(4, kai_i2c4_smb349_board_info,
331 ARRAY_SIZE(kai_i2c4_smb349_board_info));
332
333 if (board_info.fab == BOARD_FAB_A00)
334 i2c_register_board_info(4, &rt5640_board_info, 1);
335 else
336 i2c_register_board_info(4, &rt5639_board_info, 1);
337
338 i2c_register_board_info(4, &kai_eeprom_mac_add, 1);
339
340 i2c_register_board_info(4, kai_i2c4_max17048_board_info,
341 ARRAY_SIZE(kai_i2c4_max17048_board_info));
342
343 i2c_register_board_info(0, kai_nfc_board_info, 1);
344}
345
346static struct platform_device *kai_uart_devices[] __initdata = {
347 &tegra_uarta_device,
348 &tegra_uartb_device,
349 &tegra_uartc_device,
350 &tegra_uartd_device,
351 &tegra_uarte_device,
352};
353static struct uart_clk_parent uart_parent_clk[] = {
354 [0] = {.name = "clk_m"},
355 [1] = {.name = "pll_p"},
356#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
357 [2] = {.name = "pll_m"},
358#endif
359};
360
361static struct tegra_uart_platform_data kai_uart_pdata;
362static struct tegra_uart_platform_data kai_loopback_uart_pdata;
363
364static void __init uart_debug_init(void)
365{
366 int debug_port_id;
367
368 debug_port_id = get_tegra_uart_debug_port_id();
369 if (debug_port_id < 0)
370 debug_port_id = 3;
371
372 switch (debug_port_id) {
373 case 0:
374 /* UARTA is the debug port. */
375 pr_info("Selecting UARTA as the debug console\n");
376 kai_uart_devices[0] = &debug_uarta_device;
377 debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
378 debug_uart_port_base = ((struct plat_serial8250_port *)(
379 debug_uarta_device.dev.platform_data))->mapbase;
380 break;
381
382 case 1:
383 /* UARTB is the debug port. */
384 pr_info("Selecting UARTB as the debug console\n");
385 kai_uart_devices[1] = &debug_uartb_device;
386 debug_uart_clk = clk_get_sys("serial8250.0", "uartb");
387 debug_uart_port_base = ((struct plat_serial8250_port *)(
388 debug_uartb_device.dev.platform_data))->mapbase;
389 break;
390
391 case 2:
392 /* UARTC is the debug port. */
393 pr_info("Selecting UARTC as the debug console\n");
394 kai_uart_devices[2] = &debug_uartc_device;
395 debug_uart_clk = clk_get_sys("serial8250.0", "uartc");
396 debug_uart_port_base = ((struct plat_serial8250_port *)(
397 debug_uartc_device.dev.platform_data))->mapbase;
398 break;
399
400 case 3:
401 /* UARTD is the debug port. */
402 pr_info("Selecting UARTD as the debug console\n");
403 kai_uart_devices[3] = &debug_uartd_device;
404 debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
405 debug_uart_port_base = ((struct plat_serial8250_port *)(
406 debug_uartd_device.dev.platform_data))->mapbase;
407 break;
408
409 case 4:
410 /* UARTE is the debug port. */
411 pr_info("Selecting UARTE as the debug console\n");
412 kai_uart_devices[4] = &debug_uarte_device;
413 debug_uart_clk = clk_get_sys("serial8250.0", "uarte");
414 debug_uart_port_base = ((struct plat_serial8250_port *)(
415 debug_uarte_device.dev.platform_data))->mapbase;
416 break;
417
418 default:
419 pr_info("The debug console id %d is invalid, Assuming UARTA",
420 debug_port_id);
421 kai_uart_devices[0] = &debug_uarta_device;
422 debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
423 debug_uart_port_base = ((struct plat_serial8250_port *)(
424 debug_uarta_device.dev.platform_data))->mapbase;
425 break;
426 }
427}
428
429static void __init kai_uart_init(void)
430{
431 struct clk *c;
432 int i;
433
434 for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
435 c = tegra_get_clock_by_name(uart_parent_clk[i].name);
436 if (IS_ERR_OR_NULL(c)) {
437 pr_err("Not able to get the clock for %s\n",
438 uart_parent_clk[i].name);
439 continue;
440 }
441 uart_parent_clk[i].parent_clk = c;
442 uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
443 }
444 kai_uart_pdata.parent_clk_list = uart_parent_clk;
445 kai_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
446 kai_loopback_uart_pdata.parent_clk_list = uart_parent_clk;
447 kai_loopback_uart_pdata.parent_clk_count =
448 ARRAY_SIZE(uart_parent_clk);
449 kai_loopback_uart_pdata.is_loopback = true;
450 tegra_uarta_device.dev.platform_data = &kai_uart_pdata;
451 tegra_uartb_device.dev.platform_data = &kai_uart_pdata;
452 tegra_uartc_device.dev.platform_data = &kai_uart_pdata;
453 tegra_uartd_device.dev.platform_data = &kai_uart_pdata;
454 /* UARTE is used for loopback test purpose */
455 tegra_uarte_device.dev.platform_data = &kai_loopback_uart_pdata;
456
457 /* Register low speed only if it is selected */
458 if (!is_tegra_debug_uartport_hs()) {
459 uart_debug_init();
460 /* Clock enable for the debug channel */
461 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
462 pr_info("The debug console clock name is %s\n",
463 debug_uart_clk->name);
464 c = tegra_get_clock_by_name("pll_p");
465 if (IS_ERR_OR_NULL(c))
466 pr_err("Not getting the parent clock pll_p\n");
467 else
468 clk_set_parent(debug_uart_clk, c);
469
470 clk_enable(debug_uart_clk);
471 clk_set_rate(debug_uart_clk, clk_get_rate(c));
472 } else {
473 pr_err("Not getting the clock %s for debug console\n",
474 debug_uart_clk->name);
475 }
476 }
477
478 platform_add_devices(kai_uart_devices,
479 ARRAY_SIZE(kai_uart_devices));
480}
481
482static struct platform_device tegra_camera = {
483 .name = "tegra_camera",
484 .id = -1,
485};
486
487static struct platform_device *kai_spi_devices[] __initdata = {
488 &tegra_spi_device4,
489 &tegra_spi_device1,
490};
491
492static struct spi_clk_parent spi_parent_clk[] = {
493 [0] = {.name = "pll_p"},
494#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
495 [1] = {.name = "pll_m"},
496 [2] = {.name = "clk_m"},
497#else
498 [1] = {.name = "clk_m"},
499#endif
500};
501
502static struct tegra_spi_platform_data kai_spi_pdata = {
503 .is_dma_based = true,
504 .max_dma_buffer = (16 * 1024),
505 .is_clkon_always = false,
506 .max_rate = 100000000,
507};
508
509static void __init kai_spi_init(void)
510{
511 int i;
512 struct clk *c;
513
514 for (i = 0; i < ARRAY_SIZE(spi_parent_clk); ++i) {
515 c = tegra_get_clock_by_name(spi_parent_clk[i].name);
516 if (IS_ERR_OR_NULL(c)) {
517 pr_err("Not able to get the clock for %s\n",
518 spi_parent_clk[i].name);
519 continue;
520 }
521 spi_parent_clk[i].parent_clk = c;
522 spi_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
523 }
524 kai_spi_pdata.parent_clk_list = spi_parent_clk;
525 kai_spi_pdata.parent_clk_count = ARRAY_SIZE(spi_parent_clk);
526 tegra_spi_device4.dev.platform_data = &kai_spi_pdata;
527 platform_add_devices(kai_spi_devices,
528 ARRAY_SIZE(kai_spi_devices));
529
530}
531
532static struct resource tegra_rtc_resources[] = {
533 [0] = {
534 .start = TEGRA_RTC_BASE,
535 .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1,
536 .flags = IORESOURCE_MEM,
537 },
538 [1] = {
539 .start = INT_RTC,
540 .end = INT_RTC,
541 .flags = IORESOURCE_IRQ,
542 },
543};
544
545static struct platform_device tegra_rtc_device = {
546 .name = "tegra_rtc",
547 .id = -1,
548 .resource = tegra_rtc_resources,
549 .num_resources = ARRAY_SIZE(tegra_rtc_resources),
550};
551
552static struct tegra_rt5640_platform_data kai_audio_pdata = {
553 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
554 .gpio_hp_det = TEGRA_GPIO_HP_DET,
555 .gpio_hp_mute = -1,
556 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
557 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
558};
559
560static struct platform_device kai_audio_device = {
561 .name = "tegra-snd-rt5640",
562 .id = 0,
563 .dev = {
564 .platform_data = &kai_audio_pdata,
565 },
566};
567
568static struct gpio_led kai_led_info[] = {
569 {
570 .name = "statled",
571 .default_trigger = "default-on",
572 .gpio = TEGRA_GPIO_STAT_LED,
573 .active_low = 1,
574 .retain_state_suspended = 0,
575 .default_state = LEDS_GPIO_DEFSTATE_OFF,
576 },
577};
578
579static struct gpio_led_platform_data kai_leds_pdata = {
580 .leds = kai_led_info,
581 .num_leds = ARRAY_SIZE(kai_led_info),
582};
583
584static struct platform_device kai_leds_gpio_device = {
585 .name = "leds-gpio",
586 .id = -1,
587 .dev = {
588 .platform_data = &kai_leds_pdata,
589 },
590};
591
592static struct platform_device *kai_devices[] __initdata = {
593 &tegra_pmu_device,
594 &tegra_rtc_device,
595 &tegra_udc_device,
596#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
597 &tegra_smmu_device,
598#endif
599 &tegra_wdt_device,
600#if defined(CONFIG_TEGRA_AVP)
601 &tegra_avp_device,
602#endif
603 &tegra_camera,
604#if defined(CONFIG_CRYPTO_DEV_TEGRA_SE)
605 &tegra_se_device,
606#endif
607 &tegra_ahub_device,
608 &tegra_dam_device0,
609 &tegra_dam_device1,
610 &tegra_dam_device2,
611 &tegra_i2s_device1,
612 &tegra_i2s_device3,
613 &tegra_i2s_device4,
614 &tegra_spdif_device,
615 &spdif_dit_device,
616 &bluetooth_dit_device,
617 &tegra_pcm_device,
618 &kai_audio_device,
619 &kai_leds_gpio_device,
620 &tegra_hda_device,
621#if defined(CONFIG_CRYPTO_DEV_TEGRA_AES)
622 &tegra_aes_device,
623#endif
624};
625
626static __initdata struct tegra_clk_init_table spi_clk_init_table[] = {
627 /* name parent rate enabled */
628 { "sbc1", "pll_p", 52000000, true},
629 { NULL, NULL, 0, 0},
630};
631
632static __initdata struct tegra_clk_init_table touch_clk_init_table[] = {
633 /* name parent rate enabled */
634 { "extern3", "pll_p", 41000000, true},
635 { "clk_out_3", "extern3", 40800000, true},
636 { NULL, NULL, 0, 0},
637};
638
639static int __init kai_touch_init(void)
640{
641 int touch_id;
642
643 tegra_gpio_enable(KAI_TS_ID1);
644 tegra_gpio_enable(KAI_TS_ID2);
645
646 gpio_request(KAI_TS_ID1, "touch-id1");
647 gpio_direction_input(KAI_TS_ID1);
648
649 gpio_request(KAI_TS_ID2, "touch-id2");
650 gpio_direction_input(KAI_TS_ID2);
651
652 touch_id = gpio_get_value(KAI_TS_ID1) << 1;
653 touch_id |= gpio_get_value(KAI_TS_ID2);
654
655 pr_info("touch-id %d\n", touch_id);
656
657 /* Disable TS_ID GPIO to save power */
658 gpio_direction_output(KAI_TS_ID1, 0);
659 tegra_pinmux_set_pullupdown(KAI_TS_ID1_PG, TEGRA_PUPD_NORMAL);
660 tegra_pinmux_set_tristate(KAI_TS_ID1_PG, TEGRA_TRI_TRISTATE);
661 gpio_direction_output(KAI_TS_ID2, 0);
662 tegra_pinmux_set_pullupdown(KAI_TS_ID2_PG, TEGRA_PUPD_NORMAL);
663 tegra_pinmux_set_tristate(KAI_TS_ID2_PG, TEGRA_TRI_TRISTATE);
664
665 switch (touch_id) {
666 case 0:
667 pr_info("Raydium PCB based touch init\n");
668 tegra_clk_init_from_table(spi_clk_init_table);
669 touch_init_raydium(TEGRA_GPIO_PZ3, TEGRA_GPIO_PN5, 0);
670 break;
671 case 1:
672 pr_info("Raydium On-Board touch init\n");
673 tegra_clk_init_from_table(spi_clk_init_table);
674 tegra_clk_init_from_table(touch_clk_init_table);
675 clk_enable(tegra_get_clock_by_name("clk_out_3"));
676
677 touch_init_raydium(TEGRA_GPIO_PZ3, TEGRA_GPIO_PN5, 1);
678 break;
679 case 3:
680 pr_info("Synaptics PCB based touch init\n");
681 touch_init_synaptics_kai();
682 break;
683 default:
684 pr_err("touch_id error, no touch %d\n", touch_id);
685 }
686 return 0;
687}
688
689static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
690 [0] = {
691 .phy_config = &utmi_phy_config[0],
692 .operating_mode = TEGRA_USB_HOST,
693 .power_down_on_bus_suspend = 1,
694 .default_enable = true,
695 },
696 [1] = {
697 .phy_config = &utmi_phy_config[1],
698 .operating_mode = TEGRA_USB_HOST,
699 .power_down_on_bus_suspend = 1,
700 .default_enable = false,
701 },
702};
703
704static struct tegra_otg_platform_data tegra_otg_pdata = {
705 .ehci_device = &tegra_ehci1_device,
706 .ehci_pdata = &tegra_ehci_pdata[0],
707};
708
709#ifdef CONFIG_USB_SUPPORT
710static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
711 [0] = {
712 .instance = 0,
713 .vbus_gpio = -1,
714 .vbus_irq = MAX77663_IRQ_BASE +
715 MAX77663_IRQ_ACOK_RISING,
716 },
717 [1] = {
718 .instance = 1,
719 .vbus_gpio = -1,
720 },
721};
722
723static void kai_usb_init(void)
724{
725 tegra_usb_phy_init(tegra_usb_phy_pdata,
726 ARRAY_SIZE(tegra_usb_phy_pdata));
727
728 tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
729 platform_device_register(&tegra_otg_device);
730
731 tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1];
732 platform_device_register(&tegra_ehci2_device);
733}
734
735static void kai_modem_init(void)
736{
737 int ret;
738
739 tegra_gpio_enable(TEGRA_GPIO_W_DISABLE);
740 tegra_gpio_enable(TEGRA_GPIO_MODEM_RSVD1);
741 tegra_gpio_enable(TEGRA_GPIO_MODEM_RSVD2);
742
743 ret = gpio_request(TEGRA_GPIO_W_DISABLE, "w_disable_gpio");
744 if (ret < 0)
745 pr_err("%s: gpio_request failed for gpio %d\n",
746 __func__, TEGRA_GPIO_W_DISABLE);
747 else
748 gpio_direction_output(TEGRA_GPIO_W_DISABLE, 1);
749
750
751 ret = gpio_request(TEGRA_GPIO_MODEM_RSVD1, "Port_V_PIN_0");
752 if (ret < 0)
753 pr_err("%s: gpio_request failed for gpio %d\n",
754 __func__, TEGRA_GPIO_MODEM_RSVD1);
755 else
756 gpio_direction_input(TEGRA_GPIO_MODEM_RSVD1);
757
758
759 ret = gpio_request(TEGRA_GPIO_MODEM_RSVD2, "Port_H_PIN_7");
760 if (ret < 0)
761 pr_err("%s: gpio_request failed for gpio %d\n",
762 __func__, TEGRA_GPIO_MODEM_RSVD2);
763 else
764 gpio_direction_output(TEGRA_GPIO_MODEM_RSVD2, 1);
765
766}
767
768#else
769static void kai_usb_init(void) { }
770static void kai_modem_init(void) { }
771#endif
772
773static void kai_audio_init(void)
774{
775 struct board_info board_info;
776
777 tegra_get_board_info(&board_info);
778
779 if (board_info.fab == BOARD_FAB_A01) {
780 kai_audio_pdata.codec_name = "rt5639.4-001c";
781 kai_audio_pdata.codec_dai_name = "rt5639-aif1";
782 } else if (board_info.fab == BOARD_FAB_A00) {
783 kai_audio_pdata.codec_name = "rt5640.4-001c";
784 kai_audio_pdata.codec_dai_name = "rt5640-aif1";
785 }
786}
787
788static void kai_nfc_init(void)
789{
790 tegra_gpio_enable(TEGRA_GPIO_PX0);
791 tegra_gpio_enable(TEGRA_GPIO_PP3);
792 tegra_gpio_enable(TEGRA_GPIO_PO7);
793}
794
795static void __init tegra_kai_init(void)
796{
797 tegra_thermal_init(&thermal_data);
798 tegra_clk_init_from_table(kai_clk_init_table);
799 kai_pinmux_init();
800 kai_i2c_init();
801 kai_spi_init();
802 kai_usb_init();
803#ifdef CONFIG_TEGRA_EDP_LIMITS
804 kai_edp_init();
805#endif
806 kai_uart_init();
807 kai_tsensor_init();
808 kai_audio_init();
809 platform_add_devices(kai_devices, ARRAY_SIZE(kai_devices));
810 tegra_ram_console_debug_init();
811 kai_sdhci_init();
812 kai_regulator_init();
813 kai_suspend_init();
814 kai_touch_init();
815 kai_keys_init();
816 kai_panel_init();
817 kai_bt_st();
818 kai_tegra_setup_tibluesleep();
819 kai_nfc_init();
820 kai_sensors_init();
821 kai_pins_state_init();
822 kai_emc_init();
823 tegra_release_bootloader_fb();
824 kai_modem_init();
825#ifdef CONFIG_TEGRA_WDT_RECOVERY
826 tegra_wdt_recovery_init();
827#endif
828}
829
830static void __init kai_ramconsole_reserve(unsigned long size)
831{
832 tegra_ram_console_debug_reserve(SZ_1M);
833}
834
835static void __init tegra_kai_reserve(void)
836{
837#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM)
838 /* support 1920X1200 with 24bpp */
839 tegra_reserve(0, SZ_8M + SZ_1M, SZ_8M + SZ_1M);
840#else
841 tegra_reserve(SZ_128M, SZ_8M, SZ_8M);
842#endif
843 kai_ramconsole_reserve(SZ_1M);
844}
845
846MACHINE_START(KAI, "kai")
847 .boot_params = 0x80000100,
848 .map_io = tegra_map_common_io,
849 .reserve = tegra_kai_reserve,
850 .init_early = tegra_init_early,
851 .init_irq = tegra_init_irq,
852 .timer = &tegra_timer,
853 .init_machine = tegra_kai_init,
854MACHINE_END
diff --git a/arch/arm/mach-tegra/board-kai.h b/arch/arm/mach-tegra/board-kai.h
new file mode 100644
index 00000000000..1f7c16ebf59
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai.h
@@ -0,0 +1,120 @@
1/*
2 * arch/arm/mach-tegra/board-kai.h
3 *
4 * Copyright (c) 2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#ifndef _MACH_TEGRA_BOARD_KAI_H
21#define _MACH_TEGRA_BOARD_KAI_H
22
23#include <mach/gpio.h>
24#include <mach/irqs.h>
25#include <linux/mfd/max77663-core.h>
26#include "gpio-names.h"
27
28/* Processor Board ID */
29#define BOARD_E1565 0xF41
30
31/* Board Fab version */
32#define BOARD_FAB_A00 0x0
33#define BOARD_FAB_A01 0x1
34#define BOARD_FAB_A02 0x2
35#define BOARD_FAB_A03 0x3
36#define BOARD_FAB_A04 0x4
37#define BOARD_FAB_A05 0x5
38
39/* External peripheral act as gpio */
40/* MAX77663 GPIO */
41#define MAX77663_GPIO_BASE TEGRA_NR_GPIOS
42#define MAX77663_GPIO_END (MAX77663_GPIO_BASE + MAX77663_GPIO_NR)
43
44/* CAMERA RELATED GPIOs on KAI */
45#define CAM2_RST_GPIO TEGRA_GPIO_PBB4
46#define CAM2_POWER_DWN_GPIO TEGRA_GPIO_PBB6
47/* Audio-related GPIOs */
48#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PW3
49#define TEGRA_GPIO_SPKR_EN -1
50#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
51#define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PK3
52#define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PK4
53/* Tegra Modem related GPIOs */
54#define TEGRA_GPIO_W_DISABLE TEGRA_GPIO_PDD7
55#define TEGRA_GPIO_MODEM_RSVD1 TEGRA_GPIO_PV0
56#define TEGRA_GPIO_MODEM_RSVD2 TEGRA_GPIO_PH7
57
58/* Stat LED GPIO */
59#define TEGRA_GPIO_STAT_LED (MAX77663_GPIO_BASE + MAX77663_GPIO7)
60
61
62/*****************Interrupt tables ******************/
63/* External peripheral act as interrupt controller */
64/* MAX77663 IRQs */
65#define MAX77663_IRQ_BASE TEGRA_NR_IRQS
66#define MAX77663_IRQ_END (MAX77663_IRQ_BASE + MAX77663_IRQ_NR)
67#define MAX77663_IRQ_ACOK_RISING MAX77663_IRQ_ONOFF_ACOK_RISING
68
69/* UART port which is used by bluetooth*/
70#define BLUETOOTH_UART_DEV_NAME "/dev/ttyHS2"
71
72int kai_charge_init(void);
73int kai_regulator_init(void);
74int kai_suspend_init(void);
75int kai_sdhci_init(void);
76int kai_pinmux_init(void);
77int kai_panel_init(void);
78int kai_sensors_init(void);
79int kai_keys_init(void);
80int kai_pins_state_init(void);
81int kai_emc_init(void);
82int kai_edp_init(void);
83void __init kai_tsensor_init(void);
84int __init touch_init_raydium(int irq_gpio, int reset_gpio, int platform);
85int __init touch_init_synaptics_kai(void);
86
87#define TOUCH_GPIO_IRQ_RAYDIUM_SPI TEGRA_GPIO_PZ3
88#define TOUCH_GPIO_RST_RAYDIUM_SPI TEGRA_GPIO_PN5
89
90#define SYNAPTICS_ATTN_GPIO TEGRA_GPIO_PZ3
91#define SYNAPTICS_RESET_GPIO TEGRA_GPIO_PN5
92
93#define KAI_TS_ID1 TEGRA_GPIO_PI7
94#define KAI_TS_ID2 TEGRA_GPIO_PC7
95#define KAI_TS_ID1_PG TEGRA_PINGROUP_GMI_WAIT
96#define KAI_TS_ID2_PG TEGRA_PINGROUP_GMI_WP_N
97
98#define MPU_TYPE_MPU3050 1
99#define MPU_TYPE_MPU6050 2
100#define MPU_GYRO_TYPE MPU_TYPE_MPU6050
101#define MPU_GYRO_IRQ_GPIO TEGRA_GPIO_PX1
102#define MPU_GYRO_ADDR 0x68
103#define MPU_GYRO_BUS_NUM 0
104#define MPU_GYRO_ORIENTATION { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
105#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
106#define MPU_ACCEL_NAME "kxtf9"
107#define MPU_ACCEL_IRQ_GPIO TEGRA_GPIO_PL1
108#define MPU_ACCEL_ADDR 0x0F
109#define MPU_ACCEL_BUS_NUM 0
110#define MPU_ACCEL_ORIENTATION { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
111#endif
112#define MPU_COMPASS_NAME "ak8975"
113#define MPU_COMPASS_IRQ_GPIO 0
114#define MPU_COMPASS_ADDR 0x0C
115#define MPU_COMPASS_BUS_NUM 2
116#define MPU_COMPASS_ORIENTATION { 1, 0, 0, 0, 1, 0, 0, 0, 1 }
117
118#define TDIODE_OFFSET (10000) /* in millicelsius */
119
120#endif
diff --git a/arch/arm/mach-tegra/board-p1852-panel.c b/arch/arm/mach-tegra/board-p1852-panel.c
new file mode 100644
index 00000000000..8940af0c0b6
--- /dev/null
+++ b/arch/arm/mach-tegra/board-p1852-panel.c
@@ -0,0 +1,144 @@
1/*
2 * arch/arm/mach-tegra/board-p1852-panel.c
3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/resource.h>
20#include <asm/mach-types.h>
21#include <linux/platform_device.h>
22#include <linux/nvhost.h>
23#include <mach/nvmap.h>
24#include <mach/irqs.h>
25#include <mach/iomap.h>
26#include <mach/dc.h>
27#include <mach/fb.h>
28
29#include "board.h"
30#include "devices.h"
31
32static int p1852_panel_enable(void)
33{
34 return 0;
35}
36
37static int p1852_panel_disable(void)
38{
39 return 0;
40}
41
42static struct tegra_dc_mode p1852_panel_modes[] = {
43 {
44 /* 800x480@60 */
45 .pclk = 32460000,
46 .h_ref_to_sync = 1,
47 .v_ref_to_sync = 1,
48 .h_sync_width = 64,
49 .v_sync_width = 3,
50 .h_back_porch = 128,
51 .v_back_porch = 22,
52 .h_front_porch = 64,
53 .v_front_porch = 20,
54 .h_active = 800,
55 .v_active = 480,
56 },
57};
58
59static struct tegra_fb_data p1852_fb_data = {
60 .win = 0,
61 .xres = 800,
62 .yres = 480,
63 .bits_per_pixel = 32,
64};
65
66static struct tegra_dc_out p1852_disp1_out = {
67 .align = TEGRA_DC_ALIGN_MSB,
68 .order = TEGRA_DC_ORDER_RED_BLUE,
69 .type = TEGRA_DC_OUT_RGB,
70 .modes = p1852_panel_modes,
71 .n_modes = ARRAY_SIZE(p1852_panel_modes),
72 .enable = p1852_panel_enable,
73 .disable = p1852_panel_disable,
74};
75
76static struct tegra_dc_platform_data p1852_disp1_pdata = {
77 .flags = TEGRA_DC_FLAG_ENABLED,
78 .default_out = &p1852_disp1_out,
79 .emc_clk_rate = 300000000,
80 .fb = &p1852_fb_data,
81};
82
83static struct nvmap_platform_carveout p1852_carveouts[] = {
84 [0] = {
85 .name = "iram",
86 .usage_mask = NVMAP_HEAP_CARVEOUT_IRAM,
87 .base = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
88 .size = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
89 .buddy_size = 0, /* no buddy allocation for IRAM */
90 },
91 [1] = {
92 .name = "generic-0",
93 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
94 .base = 0, /* Filled in by p1852_panel_init() */
95 .size = 0, /* Filled in by p1852_panel_init() */
96 .buddy_size = SZ_32K,
97 },
98};
99
100static struct nvmap_platform_data p1852_nvmap_data = {
101 .carveouts = p1852_carveouts,
102 .nr_carveouts = ARRAY_SIZE(p1852_carveouts),
103};
104
105static struct platform_device *p1852_gfx_devices[] __initdata = {
106 &tegra_nvmap_device,
107};
108
109int __init p1852_panel_init(void)
110{
111 int err;
112 struct resource *res;
113
114 p1852_carveouts[1].base = tegra_carveout_start;
115 p1852_carveouts[1].size = tegra_carveout_size;
116 tegra_nvmap_device.dev.platform_data = &p1852_nvmap_data;
117 tegra_disp1_device.dev.platform_data = &p1852_disp1_pdata;
118
119 res = nvhost_get_resource_byname(&tegra_disp1_device,
120 IORESOURCE_MEM, "fbmem");
121 if (!res) {
122 pr_err("No memory resources\n");
123 return -ENODEV;
124 }
125 res->start = tegra_fb_start;
126 res->end = tegra_fb_start + tegra_fb_size - 1;
127
128#ifdef CONFIG_TEGRA_GRHOST
129 err = nvhost_device_register(&tegra_grhost_device);
130 if (err)
131 return err;
132#endif
133
134 err = platform_add_devices(p1852_gfx_devices,
135 ARRAY_SIZE(p1852_gfx_devices));
136 if (!err)
137 err = nvhost_device_register(&tegra_disp1_device);
138
139#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
140 if (!err)
141 err = nvhost_device_register(&nvavp_device);
142#endif
143 return err;
144}
diff --git a/arch/arm/mach-tegra/board-p1852-pinmux.c b/arch/arm/mach-tegra/board-p1852-pinmux.c
new file mode 100644
index 00000000000..611d3ebfa8b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-p1852-pinmux.c
@@ -0,0 +1,391 @@
1/*
2 * arch/arm/mach-tegra/board-p1852-pinmux.c
3 *
4 * Copyright (C) 2010-2012 NVIDIA Corporation
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 <mach/pinmux.h>
20#include "board.h"
21#include "board-p1852.h"
22#include "gpio-names.h"
23
24#define DEFAULT_DRIVE(_name) \
25 { \
26 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
27 .hsm = TEGRA_HSM_DISABLE, \
28 .schmitt = TEGRA_SCHMITT_ENABLE, \
29 .drive = TEGRA_DRIVE_DIV_1, \
30 .pull_down = TEGRA_PULL_31, \
31 .pull_up = TEGRA_PULL_31, \
32 .slew_rising = TEGRA_SLEW_SLOWEST, \
33 .slew_falling = TEGRA_SLEW_SLOWEST, \
34 }
35/* Setting the drive strength of pins
36 * hsm: Enable High speed mode (ENABLE/DISABLE)
37 * Schimit: Enable/disable schimit (ENABLE/DISABLE)
38 * drive: low power mode (DIV_1, DIV_2, DIV_4, DIV_8)
39 * pulldn_drive - drive down (falling edge) - Driver Output Pull-Down drive
40 * strength code. Value from 0 to 31.
41 * pullup_drive - drive up (rising edge) - Driver Output Pull-Up drive
42 * strength code. Value from 0 to 31.
43 * pulldn_slew - Driver Output Pull-Up slew control code - 2bit code
44 * code 11 is least slewing of signal. code 00 is highest
45 * slewing of the signal.
46 * Value - FASTEST, FAST, SLOW, SLOWEST
47 * pullup_slew - Driver Output Pull-Down slew control code -
48 * code 11 is least slewing of signal. code 00 is highest
49 * slewing of the signal.
50 * Value - FASTEST, FAST, SLOW, SLOWEST
51 */
52#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
53 { \
54 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
55 .hsm = TEGRA_HSM_##_hsm, \
56 .schmitt = TEGRA_SCHMITT_##_schmitt, \
57 .drive = TEGRA_DRIVE_##_drive, \
58 .pull_down = TEGRA_PULL_##_pulldn_drive, \
59 .pull_up = TEGRA_PULL_##_pullup_drive, \
60 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
61 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
62 }
63
64/* !!!FIXME!!!! Update drive strength with characterized value */
65static __initdata struct tegra_drive_pingroup_config p1852_drive_pinmux[] = {
66 SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
67
68 /* All I2C pins are driven to maximum drive strength */
69 /* GEN1 I2C */
70 SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
71
72 /* GEN2 I2C */
73 SET_DRIVE(AT5, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
74
75 /* DDC I2C */
76 SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
77
78 /* PWR_I2C */
79 SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
80
81 /* SDMMC4 */
82 SET_DRIVE(GME, DISABLE, ENABLE, DIV_1, 22, 18, SLOWEST, SLOWEST),
83 SET_DRIVE(GMF, DISABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
84 SET_DRIVE(GMG, DISABLE, ENABLE, DIV_1, 15, 6, SLOWEST, SLOWEST),
85 SET_DRIVE(GMH, DISABLE, ENABLE, DIV_1, 12, 6, SLOWEST, SLOWEST),
86};
87
88#define DEFAULT_PINMUX(_pingroup, _mux, _pupd, _tri, _io) \
89 { \
90 .pingroup = TEGRA_PINGROUP_##_pingroup, \
91 .func = TEGRA_MUX_##_mux, \
92 .pupd = TEGRA_PUPD_##_pupd, \
93 .tristate = TEGRA_TRI_##_tri, \
94 .io = TEGRA_PIN_##_io, \
95 .lock = TEGRA_PIN_LOCK_DEFAULT, \
96 .od = TEGRA_PIN_OD_DEFAULT, \
97 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
98 }
99
100#define I2C_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _od) \
101 { \
102 .pingroup = TEGRA_PINGROUP_##_pingroup, \
103 .func = TEGRA_MUX_##_mux, \
104 .pupd = TEGRA_PUPD_##_pupd, \
105 .tristate = TEGRA_TRI_##_tri, \
106 .io = TEGRA_PIN_##_io, \
107 .lock = TEGRA_PIN_LOCK_##_lock, \
108 .od = TEGRA_PIN_OD_##_od, \
109 .ioreset = TEGRA_PIN_IO_RESET_DEFAULT, \
110 }
111
112#define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
113 { \
114 .pingroup = TEGRA_PINGROUP_##_pingroup, \
115 .func = TEGRA_MUX_##_mux, \
116 .pupd = TEGRA_PUPD_##_pupd, \
117 .tristate = TEGRA_TRI_##_tri, \
118 .io = TEGRA_PIN_##_io, \
119 .lock = TEGRA_PIN_LOCK_##_lock, \
120 .od = TEGRA_PIN_OD_DEFAULT, \
121 .ioreset = TEGRA_PIN_IO_RESET_##_ioreset \
122 }
123
124static __initdata struct tegra_pingroup_config p1852_pinmux_common[] = {
125 /* SDMMC1 pinmux */
126 DEFAULT_PINMUX(SDMMC1_CLK, SDMMC1, NORMAL, NORMAL, INPUT),
127 DEFAULT_PINMUX(SDMMC1_CMD, SDMMC1, PULL_UP, NORMAL, INPUT),
128 DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, PULL_UP, NORMAL, INPUT),
129 DEFAULT_PINMUX(SDMMC1_DAT2, SDMMC1, PULL_UP, NORMAL, INPUT),
130 DEFAULT_PINMUX(SDMMC1_DAT1, SDMMC1, PULL_UP, NORMAL, INPUT),
131 DEFAULT_PINMUX(SDMMC1_DAT0, SDMMC1, PULL_UP, NORMAL, INPUT),
132
133 /* SDMMC2 pinmux */
134 DEFAULT_PINMUX(KB_ROW10, SDMMC2, NORMAL, NORMAL, INPUT),
135 DEFAULT_PINMUX(KB_ROW11, SDMMC2, PULL_UP, NORMAL, INPUT),
136 DEFAULT_PINMUX(KB_ROW12, SDMMC2, PULL_UP, NORMAL, INPUT),
137 DEFAULT_PINMUX(KB_ROW13, SDMMC2, PULL_UP, NORMAL, INPUT),
138 DEFAULT_PINMUX(KB_ROW14, SDMMC2, PULL_UP, NORMAL, INPUT),
139 DEFAULT_PINMUX(KB_ROW15, SDMMC2, PULL_UP, NORMAL, INPUT),
140 DEFAULT_PINMUX(KB_ROW6, SDMMC2, PULL_UP, NORMAL, INPUT),
141 DEFAULT_PINMUX(KB_ROW7, SDMMC2, PULL_UP, NORMAL, INPUT),
142 DEFAULT_PINMUX(KB_ROW8, SDMMC2, PULL_UP, NORMAL, INPUT),
143 DEFAULT_PINMUX(KB_ROW9, SDMMC2, PULL_UP, NORMAL, INPUT),
144
145 /* SDMMC3 pinmux */
146 DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT),
147 DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, PULL_UP, NORMAL, INPUT),
148 DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, PULL_UP, NORMAL, INPUT),
149 DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, PULL_UP, NORMAL, INPUT),
150 DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, PULL_UP, NORMAL, INPUT),
151 DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, PULL_UP, NORMAL, INPUT),
152
153 /* SDMMC4 pinmux */
154 DEFAULT_PINMUX(CAM_MCLK, POPSDMMC4, NORMAL, NORMAL, INPUT),
155 DEFAULT_PINMUX(GPIO_PCC1, POPSDMMC4, NORMAL, NORMAL, INPUT),
156 DEFAULT_PINMUX(GPIO_PBB0, POPSDMMC4, PULL_UP, NORMAL, INPUT),
157 I2C_PINMUX(CAM_I2C_SCL, POPSDMMC4, PULL_UP, NORMAL, INPUT, DISABLE, DISABLE),
158 I2C_PINMUX(CAM_I2C_SDA, POPSDMMC4, PULL_UP, NORMAL, INPUT, DISABLE, DISABLE),
159 DEFAULT_PINMUX(GPIO_PBB3, POPSDMMC4, PULL_UP, NORMAL, INPUT),
160 DEFAULT_PINMUX(GPIO_PBB4, POPSDMMC4, PULL_UP, NORMAL, INPUT),
161 DEFAULT_PINMUX(GPIO_PBB5, POPSDMMC4, PULL_UP, NORMAL, INPUT),
162 DEFAULT_PINMUX(GPIO_PBB6, POPSDMMC4, PULL_UP, NORMAL, INPUT),
163 DEFAULT_PINMUX(GPIO_PBB7, POPSDMMC4, PULL_UP, NORMAL, INPUT),
164
165 /* UART1 pinmux */
166 DEFAULT_PINMUX(ULPI_DATA0, UARTA, NORMAL, NORMAL, OUTPUT),
167 DEFAULT_PINMUX(ULPI_DATA1, UARTA, NORMAL, NORMAL, INPUT),
168 DEFAULT_PINMUX(ULPI_DATA2, UARTA, NORMAL, NORMAL, INPUT),
169 DEFAULT_PINMUX(ULPI_DATA3, UARTA, NORMAL, NORMAL, OUTPUT),
170
171 /* UART2 pinmux */
172 DEFAULT_PINMUX(UART2_RXD, IRDA, NORMAL, NORMAL, INPUT),
173 DEFAULT_PINMUX(UART2_TXD, IRDA, NORMAL, NORMAL, OUTPUT),
174
175 /* UART4 pinmux */
176 DEFAULT_PINMUX(GMI_A16, UARTD, NORMAL, NORMAL, OUTPUT),
177 DEFAULT_PINMUX(GMI_A17, UARTD, NORMAL, NORMAL, INPUT),
178 DEFAULT_PINMUX(GMI_A18, UARTD, NORMAL, NORMAL, INPUT),
179 DEFAULT_PINMUX(GMI_A19, UARTD, NORMAL, NORMAL, OUTPUT),
180
181 /* UART5 pinmux */
182 DEFAULT_PINMUX(SDMMC4_DAT0, UARTE, NORMAL, NORMAL, INPUT),
183 DEFAULT_PINMUX(SDMMC4_DAT1, UARTE, NORMAL, NORMAL, OUTPUT),
184 DEFAULT_PINMUX(SDMMC4_DAT2, UARTE, NORMAL, NORMAL, INPUT),
185 DEFAULT_PINMUX(SDMMC4_DAT3, UARTE, NORMAL, NORMAL, OUTPUT),
186
187 /* I2C1 pinmux */
188 I2C_PINMUX(GEN1_I2C_SCL, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
189 I2C_PINMUX(GEN1_I2C_SDA, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
190
191 /* I2C2 pinmux */
192 I2C_PINMUX(GEN2_I2C_SCL, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
193 I2C_PINMUX(GEN2_I2C_SDA, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
194
195 /* I2C4 pinmux */
196 I2C_PINMUX(DDC_SCL, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
197 I2C_PINMUX(DDC_SDA, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
198
199 /* PowerI2C pinmux */
200 I2C_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
201 I2C_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
202
203 /* SPI1 pinmux */
204 DEFAULT_PINMUX(ULPI_CLK, SPI1, NORMAL, NORMAL, INPUT),
205 DEFAULT_PINMUX(ULPI_DIR, SPI1, NORMAL, NORMAL, INPUT),
206 DEFAULT_PINMUX(ULPI_NXT, SPI1, NORMAL, NORMAL, INPUT),
207 DEFAULT_PINMUX(ULPI_STP, SPI1, NORMAL, NORMAL, INPUT),
208
209 /* SPI2 pinmux */
210 DEFAULT_PINMUX(ULPI_DATA4, SPI2, NORMAL, NORMAL, INPUT),
211 DEFAULT_PINMUX(ULPI_DATA5, SPI2, NORMAL, NORMAL, INPUT),
212 DEFAULT_PINMUX(ULPI_DATA6, SPI2, NORMAL, NORMAL, INPUT),
213 DEFAULT_PINMUX(ULPI_DATA7, SPI2, NORMAL, NORMAL, INPUT),
214
215 /* SPDIF pinmux */
216 DEFAULT_PINMUX(SPDIF_IN, SPDIF, NORMAL, NORMAL, INPUT),
217
218 /* DAP1 */
219 DEFAULT_PINMUX(DAP1_FS, I2S0, NORMAL, NORMAL, INPUT),
220 DEFAULT_PINMUX(DAP1_DIN, I2S0, NORMAL, NORMAL, INPUT),
221 DEFAULT_PINMUX(DAP1_DOUT, I2S0, NORMAL, NORMAL, INPUT),
222 DEFAULT_PINMUX(DAP1_SCLK, I2S0, NORMAL, NORMAL, INPUT),
223
224 /* DAP2 */
225 DEFAULT_PINMUX(DAP3_FS, I2S2, NORMAL, NORMAL, INPUT),
226 DEFAULT_PINMUX(DAP3_DIN, I2S2, NORMAL, NORMAL, INPUT),
227 DEFAULT_PINMUX(DAP3_DOUT, I2S2, NORMAL, NORMAL, INPUT),
228 DEFAULT_PINMUX(DAP3_SCLK, I2S2, NORMAL, NORMAL, INPUT),
229
230 /* DAP3 */
231 DEFAULT_PINMUX(SDMMC4_DAT4, I2S4, NORMAL, NORMAL, INPUT),
232 DEFAULT_PINMUX(SDMMC4_DAT5, I2S4, NORMAL, NORMAL, INPUT),
233 DEFAULT_PINMUX(SDMMC4_DAT6, I2S4, NORMAL, NORMAL, INPUT),
234 DEFAULT_PINMUX(SDMMC4_DAT7, I2S4, NORMAL, NORMAL, INPUT),
235
236 /* NOR pinmux */
237 DEFAULT_PINMUX(GMI_AD0, GMI, NORMAL, NORMAL, INPUT),
238 DEFAULT_PINMUX(GMI_AD1, GMI, NORMAL, NORMAL, INPUT),
239 DEFAULT_PINMUX(GMI_AD2, GMI, NORMAL, NORMAL, INPUT),
240 DEFAULT_PINMUX(GMI_AD3, GMI, NORMAL, NORMAL, INPUT),
241 DEFAULT_PINMUX(GMI_AD4, GMI, NORMAL, NORMAL, INPUT),
242 DEFAULT_PINMUX(GMI_AD5, GMI, NORMAL, NORMAL, INPUT),
243 DEFAULT_PINMUX(GMI_AD6, GMI, NORMAL, NORMAL, INPUT),
244 DEFAULT_PINMUX(GMI_AD7, GMI, NORMAL, NORMAL, INPUT),
245 DEFAULT_PINMUX(GMI_AD8, GMI, NORMAL, NORMAL, INPUT),
246 DEFAULT_PINMUX(GMI_AD9, GMI, NORMAL, NORMAL, INPUT),
247 DEFAULT_PINMUX(GMI_AD10, GMI, NORMAL, NORMAL, INPUT),
248 DEFAULT_PINMUX(GMI_AD11, GMI, NORMAL, NORMAL, INPUT),
249 DEFAULT_PINMUX(GMI_AD12, GMI, NORMAL, NORMAL, INPUT),
250 DEFAULT_PINMUX(GMI_AD13, GMI, NORMAL, NORMAL, INPUT),
251 DEFAULT_PINMUX(GMI_AD14, GMI, NORMAL, NORMAL, INPUT),
252 DEFAULT_PINMUX(GMI_AD15, GMI, NORMAL, NORMAL, INPUT),
253 DEFAULT_PINMUX(GMI_ADV_N, GMI, NORMAL, NORMAL, OUTPUT),
254 DEFAULT_PINMUX(GMI_CLK, GMI, NORMAL, NORMAL, OUTPUT),
255 DEFAULT_PINMUX(GMI_CS0_N, GMI, NORMAL, NORMAL, OUTPUT),
256 DEFAULT_PINMUX(GMI_OE_N, GMI, NORMAL, NORMAL, OUTPUT),
257 DEFAULT_PINMUX(GMI_RST_N, GMI, NORMAL, NORMAL, OUTPUT),
258 DEFAULT_PINMUX(GMI_WAIT, GMI, NORMAL, NORMAL, INPUT),
259 DEFAULT_PINMUX(GMI_WP_N, GMI, NORMAL, NORMAL, OUTPUT),
260 DEFAULT_PINMUX(GMI_WR_N, GMI, NORMAL, NORMAL, OUTPUT),
261 DEFAULT_PINMUX(DAP2_FS, GMI, NORMAL, NORMAL, OUTPUT),
262 DEFAULT_PINMUX(DAP2_DIN, GMI, NORMAL, NORMAL, OUTPUT),
263 DEFAULT_PINMUX(DAP2_DOUT, GMI, NORMAL, NORMAL, OUTPUT),
264 DEFAULT_PINMUX(DAP2_SCLK, GMI, NORMAL, NORMAL, OUTPUT),
265 DEFAULT_PINMUX(SPI1_MOSI, GMI, NORMAL, NORMAL, OUTPUT),
266 DEFAULT_PINMUX(SPI2_CS0_N, GMI, NORMAL, NORMAL, OUTPUT),
267 DEFAULT_PINMUX(SPI2_SCK, GMI, NORMAL, NORMAL, OUTPUT),
268 DEFAULT_PINMUX(SPI2_MOSI, GMI, NORMAL, NORMAL, OUTPUT),
269 DEFAULT_PINMUX(SPI2_MISO, GMI, NORMAL, NORMAL, OUTPUT),
270 DEFAULT_PINMUX(DAP4_FS, GMI, NORMAL, NORMAL, OUTPUT),
271 DEFAULT_PINMUX(DAP4_DIN, GMI, NORMAL, NORMAL, OUTPUT),
272 DEFAULT_PINMUX(DAP4_DOUT, GMI, NORMAL, NORMAL, OUTPUT),
273 DEFAULT_PINMUX(DAP4_SCLK, GMI, NORMAL, NORMAL, OUTPUT),
274 DEFAULT_PINMUX(GPIO_PU0, GMI, NORMAL, NORMAL, OUTPUT),
275 DEFAULT_PINMUX(GPIO_PU1, GMI, NORMAL, NORMAL, OUTPUT),
276 DEFAULT_PINMUX(GPIO_PU2, GMI, NORMAL, NORMAL, OUTPUT),
277 DEFAULT_PINMUX(GPIO_PU3, GMI, NORMAL, NORMAL, OUTPUT),
278 DEFAULT_PINMUX(GPIO_PU4, GMI, NORMAL, NORMAL, OUTPUT),
279 DEFAULT_PINMUX(GPIO_PU5, GMI, NORMAL, NORMAL, OUTPUT),
280 DEFAULT_PINMUX(GPIO_PU6, GMI, NORMAL, NORMAL, OUTPUT),
281 DEFAULT_PINMUX(UART2_RTS_N, GMI, NORMAL, NORMAL, OUTPUT),
282 DEFAULT_PINMUX(UART2_CTS_N, GMI, NORMAL, NORMAL, OUTPUT),
283 DEFAULT_PINMUX(UART3_TXD, GMI, NORMAL, NORMAL, OUTPUT),
284 DEFAULT_PINMUX(UART3_RXD, GMI, NORMAL, NORMAL, OUTPUT),
285 DEFAULT_PINMUX(UART3_CTS_N, GMI, NORMAL, NORMAL, OUTPUT),
286 DEFAULT_PINMUX(UART3_RTS_N, GMI, NORMAL, NORMAL, OUTPUT),
287
288
289 /* DISPLAY pinmux */
290 DEFAULT_PINMUX(LCD_CS1_N, DISPLAYA, NORMAL, NORMAL, INPUT),
291 DEFAULT_PINMUX(LCD_D0, DISPLAYA, NORMAL, NORMAL, INPUT),
292 DEFAULT_PINMUX(LCD_D1, DISPLAYA, NORMAL, NORMAL, INPUT),
293 DEFAULT_PINMUX(LCD_D2, DISPLAYA, NORMAL, NORMAL, INPUT),
294 DEFAULT_PINMUX(LCD_D3, DISPLAYA, NORMAL, NORMAL, INPUT),
295 DEFAULT_PINMUX(LCD_D4, DISPLAYA, NORMAL, NORMAL, INPUT),
296 DEFAULT_PINMUX(LCD_D5, DISPLAYA, NORMAL, NORMAL, INPUT),
297 DEFAULT_PINMUX(LCD_D6, DISPLAYA, NORMAL, NORMAL, INPUT),
298 DEFAULT_PINMUX(LCD_D7, DISPLAYA, NORMAL, NORMAL, INPUT),
299 DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
300 DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
301 DEFAULT_PINMUX(LCD_D10, DISPLAYA, NORMAL, NORMAL, INPUT),
302 DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
303 DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
304 DEFAULT_PINMUX(LCD_D13, DISPLAYA, NORMAL, NORMAL, INPUT),
305 DEFAULT_PINMUX(LCD_D14, DISPLAYA, NORMAL, NORMAL, INPUT),
306 DEFAULT_PINMUX(LCD_D15, DISPLAYA, NORMAL, NORMAL, INPUT),
307 DEFAULT_PINMUX(LCD_D16, DISPLAYA, NORMAL, NORMAL, INPUT),
308 DEFAULT_PINMUX(LCD_D17, DISPLAYA, NORMAL, NORMAL, INPUT),
309 DEFAULT_PINMUX(LCD_D18, DISPLAYA, NORMAL, NORMAL, INPUT),
310 DEFAULT_PINMUX(LCD_D19, DISPLAYA, NORMAL, NORMAL, INPUT),
311 DEFAULT_PINMUX(LCD_D20, DISPLAYA, NORMAL, NORMAL, INPUT),
312 DEFAULT_PINMUX(LCD_D21, DISPLAYA, NORMAL, NORMAL, INPUT),
313 DEFAULT_PINMUX(LCD_D22, DISPLAYA, NORMAL, NORMAL, INPUT),
314 DEFAULT_PINMUX(LCD_D23, DISPLAYA, NORMAL, NORMAL, INPUT),
315 DEFAULT_PINMUX(LCD_DC0, DISPLAYA, NORMAL, NORMAL, INPUT),
316 DEFAULT_PINMUX(LCD_DE, DISPLAYA, NORMAL, NORMAL, INPUT),
317 DEFAULT_PINMUX(LCD_HSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
318 DEFAULT_PINMUX(LCD_PCLK, DISPLAYA, NORMAL, NORMAL, INPUT),
319 DEFAULT_PINMUX(LCD_VSYNC, DISPLAYA, NORMAL, NORMAL, INPUT),
320 DEFAULT_PINMUX(LCD_WR_N, DISPLAYA, NORMAL, NORMAL, INPUT),
321
322 DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT),
323 DEFAULT_PINMUX(PEX_L1_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
324 DEFAULT_PINMUX(PEX_L1_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
325 DEFAULT_PINMUX(PEX_L1_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
326 DEFAULT_PINMUX(PEX_L2_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
327 DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
328 DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
329
330 VI_PINMUX(VI_D2, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
331 VI_PINMUX(VI_D3, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
332 VI_PINMUX(VI_D4, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
333 VI_PINMUX(VI_D5, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
334 VI_PINMUX(VI_D6, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
335 VI_PINMUX(VI_D7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
336 VI_PINMUX(VI_D8, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
337 VI_PINMUX(VI_D9, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
338 VI_PINMUX(VI_PCLK, VI, PULL_UP, TRISTATE, INPUT, DISABLE, DISABLE),
339
340 /* pin config for gpios */
341 DEFAULT_PINMUX(VI_D0, SAFE, NORMAL, NORMAL, INPUT),
342 DEFAULT_PINMUX(CLK1_OUT, RSVD1, NORMAL, NORMAL, INPUT),
343 DEFAULT_PINMUX(CLK1_REQ, RSVD2, NORMAL, NORMAL, INPUT),
344 DEFAULT_PINMUX(LCD_SCK, SPI5, NORMAL, NORMAL, INPUT),
345 DEFAULT_PINMUX(LCD_DC1, RSVD1, NORMAL, NORMAL, INPUT),
346 DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, NORMAL, NORMAL, INPUT),
347 DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, NORMAL, NORMAL, INPUT),
348 DEFAULT_PINMUX(SPI2_CS1_N, SPI2, NORMAL, NORMAL, INPUT),
349 DEFAULT_PINMUX(SPDIF_OUT, SAFE, NORMAL, NORMAL, INPUT),
350 DEFAULT_PINMUX(SPI1_SCK, SPI2, NORMAL, NORMAL, INPUT),
351 DEFAULT_PINMUX(SPI1_CS0_N, SPI2, NORMAL, NORMAL, INPUT),
352 DEFAULT_PINMUX(SPI1_MISO, SAFE, NORMAL, NORMAL, INPUT),
353};
354
355int __init p1852_pinmux_init(void)
356{
357 tegra_pinmux_config_table(p1852_pinmux_common,
358 ARRAY_SIZE(p1852_pinmux_common));
359 tegra_drive_pinmux_config_table(p1852_drive_pinmux,
360 ARRAY_SIZE(p1852_drive_pinmux));
361 return 0;
362}
363
364static struct gpio p1852_sku8_gpios[] = {
365 {TEGRA_GPIO_PW4, GPIOF_OUT_INIT_HIGH, "w4"},
366 {TEGRA_GPIO_PEE2, GPIOF_OUT_INIT_HIGH, "ee2"},
367 {TEGRA_GPIO_PZ4, GPIOF_OUT_INIT_HIGH, "z4"},
368 {TEGRA_GPIO_PD2, GPIOF_OUT_INIT_HIGH, "d2"},
369 {TEGRA_GPIO_PD1, GPIOF_OUT_INIT_HIGH, "d1"},
370 {TEGRA_GPIO_PD0, GPIOF_OUT_INIT_HIGH, "d0"},
371 {TEGRA_GPIO_PW2, GPIOF_IN, "therm_alert"},
372 {TEGRA_GPIO_PK5, GPIOF_OUT_INIT_HIGH, "user1"},
373 {TEGRA_GPIO_PX5, GPIOF_OUT_INIT_HIGH, "user2"},
374 {TEGRA_GPIO_PX6, GPIOF_OUT_INIT_HIGH, "user3"},
375 {TEGRA_GPIO_PX7, GPIOF_OUT_INIT_HIGH, "user4"},
376};
377
378int __init p1852_gpio_init(void)
379{
380 int i, pin_count = 0;
381 struct gpio *gpios_info = NULL;
382 gpios_info = p1852_sku8_gpios;
383 pin_count = ARRAY_SIZE(p1852_sku8_gpios);
384
385 gpio_request_array(gpios_info, pin_count);
386 for (i = 0; i < pin_count; i++) {
387 tegra_gpio_enable(gpios_info[i].gpio);
388 gpio_export(gpios_info[i].gpio, true);
389 }
390 return 0;
391}
diff --git a/arch/arm/mach-tegra/board-p1852-sdhci.c b/arch/arm/mach-tegra/board-p1852-sdhci.c
new file mode 100644
index 00000000000..c1aa066ae1b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-p1852-sdhci.c
@@ -0,0 +1,79 @@
1/*
2 * arch/arm/mach-tegra/board-p1852-sdhci.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Copyright (C) 2012 NVIDIA Corporation
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/resource.h>
20#include <linux/platform_device.h>
21#include <linux/wlan_plat.h>
22#include <linux/delay.h>
23#include <linux/gpio.h>
24#include <linux/clk.h>
25#include <linux/err.h>
26#include <linux/mmc/host.h>
27
28#include <asm/mach-types.h>
29#include <mach/irqs.h>
30#include <mach/iomap.h>
31#include <mach/sdhci.h>
32
33#include "gpio-names.h"
34#include "board.h"
35#include "board-p1852.h"
36#include "devices.h"
37
38static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = {
39 .cd_gpio = TEGRA_GPIO_PV2,
40 .wp_gpio = TEGRA_GPIO_PD3,
41 .power_gpio = -1,
42 .is_8bit = false,
43};
44
45static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
46 .cd_gpio = -1,
47 .wp_gpio = -1,
48 .power_gpio = -1,
49 .is_8bit = true,
50};
51
52static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
53 .cd_gpio = TEGRA_GPIO_PV3,
54 .wp_gpio = TEGRA_GPIO_PD4,
55 .power_gpio = -1,
56 .is_8bit = false,
57};
58
59static struct tegra_sdhci_platform_data tegra_sdhci_platform_data4 = {
60 .cd_gpio = -1,
61 .wp_gpio = -1,
62 .power_gpio = -1,
63 .is_8bit = true,
64};
65
66int __init p1852_sdhci_init(void)
67{
68 tegra_sdhci_device1.dev.platform_data = &tegra_sdhci_platform_data1;
69 tegra_sdhci_device2.dev.platform_data = &tegra_sdhci_platform_data2;
70 tegra_sdhci_device3.dev.platform_data = &tegra_sdhci_platform_data3;
71 tegra_sdhci_device4.dev.platform_data = &tegra_sdhci_platform_data4;
72
73 platform_device_register(&tegra_sdhci_device1);
74 platform_device_register(&tegra_sdhci_device2);
75 platform_device_register(&tegra_sdhci_device3);
76 platform_device_register(&tegra_sdhci_device4);
77
78 return 0;
79}
diff --git a/arch/arm/mach-tegra/board-p1852.c b/arch/arm/mach-tegra/board-p1852.c
new file mode 100644
index 00000000000..ef53d405093
--- /dev/null
+++ b/arch/arm/mach-tegra/board-p1852.c
@@ -0,0 +1,456 @@
1/*
2 * arch/arm/mach-tegra/board-p1852.c
3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/ctype.h>
24#include <linux/platform_device.h>
25#include <linux/clk.h>
26#include <linux/serial_8250.h>
27#include <linux/i2c.h>
28#include <linux/i2c/panjit_ts.h>
29#include <linux/dma-mapping.h>
30#include <linux/delay.h>
31#include <linux/i2c-tegra.h>
32#include <linux/gpio.h>
33#include <linux/input.h>
34#include <linux/platform_data/tegra_usb.h>
35#include <linux/platform_data/tegra_nor.h>
36#include <linux/spi/spi.h>
37#include <linux/mtd/partitions.h>
38#include <mach/clk.h>
39#include <mach/iomap.h>
40#include <mach/irqs.h>
41#include <mach/pinmux.h>
42#include <mach/iomap.h>
43#include <mach/io.h>
44#include <mach/pci.h>
45#include <mach/audio.h>
46#include <mach/tegra_p1852_pdata.h>
47#include <asm/mach/flash.h>
48#include <asm/mach-types.h>
49#include <asm/mach/arch.h>
50#include <mach/usb_phy.h>
51#include <sound/wm8903.h>
52#include <mach/tsensor.h>
53#include "board.h"
54#include "clock.h"
55#include "board-p1852.h"
56#include "devices.h"
57#include "gpio-names.h"
58#include "fuse.h"
59
60static struct tegra_utmip_config utmi_phy_config[] = {
61 [0] = {
62 .hssync_start_delay = 0,
63 .idle_wait_delay = 17,
64 .elastic_limit = 16,
65 .term_range_adj = 6,
66 .xcvr_setup = 15,
67 .xcvr_setup_offset = 0,
68 .xcvr_use_fuses = 1,
69 .xcvr_lsfslew = 2,
70 .xcvr_lsrslew = 2,
71 },
72 [1] = {
73 .hssync_start_delay = 0,
74 .idle_wait_delay = 17,
75 .elastic_limit = 16,
76 .term_range_adj = 6,
77 .xcvr_setup = 15,
78 .xcvr_setup_offset = 0,
79 .xcvr_use_fuses = 1,
80 .xcvr_lsfslew = 2,
81 .xcvr_lsrslew = 2,
82 },
83 [2] = {
84 .hssync_start_delay = 0,
85 .idle_wait_delay = 17,
86 .elastic_limit = 16,
87 .term_range_adj = 6,
88 .xcvr_setup = 8,
89 .xcvr_setup_offset = 0,
90 .xcvr_use_fuses = 1,
91 .xcvr_lsfslew = 2,
92 .xcvr_lsrslew = 2,
93 },
94};
95
96static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = {
97 /* name parent rate enabled */
98 { "pll_m", NULL, 0, true},
99 { "hda", "pll_p", 108000000, false},
100 { "hda2codec_2x", "pll_p", 48000000, false},
101 { "pwm", "clk_32k", 32768, false},
102 { "blink", "clk_32k", 32768, true},
103 { "pll_a", NULL, 552960000, false},
104 { "pll_a_out0", NULL, 12288000, false},
105 { "d_audio", "pll_a_out0", 12288000, false},
106 { "nor", "pll_p", 86500000, true},
107 { "uarta", "pll_p", 480000000, true},
108 { "uartd", "pll_p", 480000000, true},
109 { "uarte", "pll_p", 480000000, true},
110 { "sdmmc2", "pll_p", 52000000, true},
111 { "sbc1", "pll_m", 100000000, true},
112 { "sbc2", "pll_m", 100000000, true},
113 { "sbc3", "pll_m", 100000000, true},
114 { "sbc4", "pll_m", 100000000, true},
115 { "sbc5", "pll_m", 100000000, true},
116 { "sbc6", "pll_m", 100000000, true},
117 { "cpu_g", "cclk_g", 900000000, true},
118 { "i2s0", "pll_a_out0", 12288000, false},
119 { "i2s1", "pll_a_out0", 12288000, false},
120 { "i2s2", "pll_a_out0", 12288000, false},
121 { "i2s3", "pll_a_out0", 12288000, false},
122 { "i2s4", "pll_a_out0", 12288000, false},
123 { "audio0", "i2s0_sync", 12288000, false},
124 { "audio1", "i2s1_sync", 12288000, false},
125 { "audio2", "i2s2_sync", 12288000, false},
126 { "audio3", "i2s3_sync", 12288000, false},
127 { "audio4", "i2s4_sync", 12288000, false},
128 { "apbif", "clk_m", 12000000, false},
129 { "dam0", "clk_m", 12000000, true},
130 { "dam1", "clk_m", 12000000, true},
131 { "dam2", "clk_m", 12000000, true},
132 { "vi", "pll_p", 470000000, false},
133 { "vi_sensor", "pll_p", 150000000, false},
134 { "vde", "pll_c", 484000000, true},
135 { "host1x", "pll_c", 242000000, true},
136 { "mpe", "pll_c", 484000000, true},
137 { "se", "pll_m", 625000000, true},
138 { "i2c1", "pll_p", 3200000, true},
139 { "i2c2", "pll_p", 3200000, true},
140 { "i2c3", "pll_p", 3200000, true},
141 { "i2c4", "pll_p", 3200000, true},
142 { "i2c5", "pll_p", 3200000, true},
143 { "sdmmc2", "pll_p", 104000000, false},
144 { NULL, NULL, 0, 0},
145};
146
147static struct tegra_i2c_platform_data p1852_i2c1_platform_data = {
148 .adapter_nr = 0,
149 .bus_count = 1,
150 .bus_clk_rate = { 100000, 0 },
151};
152
153static struct tegra_i2c_platform_data p1852_i2c2_platform_data = {
154 .adapter_nr = 1,
155 .bus_count = 1,
156 .bus_clk_rate = { 100000, 0 },
157 .is_clkon_always = true,
158};
159
160static struct tegra_i2c_platform_data p1852_i2c4_platform_data = {
161 .adapter_nr = 3,
162 .bus_count = 1,
163 .bus_clk_rate = { 100000, 0 },
164};
165
166static struct tegra_i2c_platform_data p1852_i2c5_platform_data = {
167 .adapter_nr = 4,
168 .bus_count = 1,
169 .bus_clk_rate = { 100000, 0 },
170};
171
172static struct tegra_pci_platform_data p1852_pci_platform_data = {
173 .port_status[0] = 0,
174 .port_status[1] = 1,
175 .port_status[2] = 1,
176 .use_dock_detect = 0,
177 .gpio = 0,
178};
179
180static void p1852_pcie_init(void)
181{
182 tegra_pci_device.dev.platform_data = &p1852_pci_platform_data;
183 platform_device_register(&tegra_pci_device);
184}
185
186static void p1852_i2c_init(void)
187{
188 tegra_i2c_device1.dev.platform_data = &p1852_i2c1_platform_data;
189 tegra_i2c_device2.dev.platform_data = &p1852_i2c2_platform_data;
190 tegra_i2c_device4.dev.platform_data = &p1852_i2c4_platform_data;
191 tegra_i2c_device5.dev.platform_data = &p1852_i2c5_platform_data;
192
193 platform_device_register(&tegra_i2c_device5);
194 platform_device_register(&tegra_i2c_device4);
195 platform_device_register(&tegra_i2c_device2);
196 platform_device_register(&tegra_i2c_device1);
197}
198
199static struct platform_device *p1852_uart_devices[] __initdata = {
200 &tegra_uarta_device,
201 &tegra_uartb_device,
202 &tegra_uartd_device,
203 &tegra_uarte_device,
204};
205static struct clk *debug_uart_clk;
206
207static void __init uart_debug_init(void)
208{
209 /* Use skuinfo to decide debug uart */
210 /* UARTB is the debug port. */
211 pr_info("Selecting UARTB as the debug console\n");
212 p1852_uart_devices[1] = &debug_uartb_device;
213 debug_uart_clk = clk_get_sys("serial8250.0", "uartb");
214}
215
216static void __init p1852_uart_init(void)
217{
218 /* Register low speed only if it is selected */
219 if (!is_tegra_debug_uartport_hs()) {
220 uart_debug_init();
221 /* Clock enable for the debug channel */
222 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
223 pr_info("The debug console clock name is %s\n",
224 debug_uart_clk->name);
225 clk_enable(debug_uart_clk);
226 clk_set_rate(debug_uart_clk, 408000000);
227 } else {
228 pr_err("Not getting the clock %s for debug console\n",
229 debug_uart_clk->name);
230 }
231 }
232
233 platform_add_devices(p1852_uart_devices,
234 ARRAY_SIZE(p1852_uart_devices));
235}
236
237static struct tegra_p1852_platform_data p1852_audio_pdata = {
238 .codec_info[0] = {
239 .codec_dai_name = "dit-hifi",
240 .cpu_dai_name = "tegra30-i2s.0",
241 .codec_name = "spdif-dit.0",
242 .name = "tegra-i2s-1",
243 .i2s_format = format_i2s,
244 .master = 1,
245 },
246 .codec_info[1] = {
247 .codec_dai_name = "dit-hifi",
248 .cpu_dai_name = "tegra30-i2s.1",
249 .codec_name = "spdif-dit.1",
250 .name = "tegra-i2s-2",
251 .i2s_format = format_i2s,
252 .master = 0,
253 },
254
255};
256
257static struct platform_device generic_codec_1 = {
258 .name = "spdif-dit",
259 .id = 0,
260};
261static struct platform_device generic_codec_2 = {
262 .name = "spdif-dit",
263 .id = 1,
264};
265
266static struct platform_device tegra_snd_p1852 = {
267 .name = "tegra-snd-p1852",
268 .id = 0,
269 .dev = {
270 .platform_data = &p1852_audio_pdata,
271 },
272};
273
274static void p1852_i2s_audio_init(void)
275{
276 platform_device_register(&tegra_pcm_device);
277 platform_device_register(&generic_codec_1);
278 platform_device_register(&generic_codec_2);
279 platform_device_register(&tegra_i2s_device0);
280 platform_device_register(&tegra_i2s_device1);
281 platform_device_register(&tegra_ahub_device);
282 platform_device_register(&tegra_snd_p1852);
283}
284
285
286#if defined(CONFIG_SPI_TEGRA) && defined(CONFIG_SPI_SPIDEV)
287static struct spi_board_info tegra_spi_devices[] __initdata = {
288 {
289 .modalias = "spidev",
290 .bus_num = 0,
291 .chip_select = 0,
292 .mode = SPI_MODE_0,
293 .max_speed_hz = 18000000,
294 .platform_data = NULL,
295 .irq = 0,
296 },
297 {
298 .modalias = "spidev",
299 .bus_num = 1,
300 .chip_select = 1,
301 .mode = SPI_MODE_0,
302 .max_speed_hz = 18000000,
303 .platform_data = NULL,
304 .irq = 0,
305 },
306 {
307 .modalias = "spidev",
308 .bus_num = 3,
309 .chip_select = 1,
310 .mode = SPI_MODE_0,
311 .max_speed_hz = 18000000,
312 .platform_data = NULL,
313 .irq = 0,
314 },
315};
316
317static void __init p852_register_spidev(void)
318{
319 spi_register_board_info(tegra_spi_devices,
320 ARRAY_SIZE(tegra_spi_devices));
321}
322#else
323#define p852_register_spidev() do {} while (0)
324#endif
325
326
327static void p1852_spi_init(void)
328{
329 tegra_spi_device2.name = "spi_slave_tegra";
330 platform_device_register(&tegra_spi_device1);
331 platform_device_register(&tegra_spi_device2);
332 p852_register_spidev();
333}
334
335static struct platform_device *p1852_devices[] __initdata = {
336#if defined(CONFIG_TEGRA_IOVMM_SMMU)
337 &tegra_smmu_device,
338#endif
339#if defined(CONFIG_TEGRA_AVP)
340 &tegra_avp_device,
341#endif
342};
343
344static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
345 [0] = {
346 .instance = 0,
347 .vbus_gpio = -1,
348 .vbus_reg_supply = NULL,
349 },
350 [1] = {
351 .instance = 1,
352 .vbus_gpio = -1,
353 },
354 [2] = {
355 .instance = 2,
356 .vbus_gpio = -1,
357 .vbus_reg_supply = NULL,
358 },
359};
360
361static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
362 [0] = {
363 .phy_config = &utmi_phy_config[0],
364 .operating_mode = TEGRA_USB_HOST,
365 .power_down_on_bus_suspend = 1,
366 },
367 [1] = {
368 .phy_config = &utmi_phy_config[1],
369 .operating_mode = TEGRA_USB_HOST,
370 .power_down_on_bus_suspend = 1,
371 },
372 [2] = {
373 .phy_config = &utmi_phy_config[2],
374 .operating_mode = TEGRA_USB_HOST,
375 .power_down_on_bus_suspend = 1,
376 },
377};
378
379static void p1852_usb_init(void)
380{
381 /* Need to parse sku info to decide host/device mode */
382 tegra_usb_phy_init(tegra_usb_phy_pdata,
383 ARRAY_SIZE(tegra_usb_phy_pdata));
384
385 tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0];
386 platform_device_register(&tegra_ehci1_device);
387
388 tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1];
389 platform_device_register(&tegra_ehci2_device);
390
391 tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2];
392 platform_device_register(&tegra_ehci3_device);
393
394}
395
396static struct tegra_nor_platform_data p1852_nor_data = {
397 .flash = {
398 .map_name = "cfi_probe",
399 .width = 2,
400 },
401 .chip_parms = {
402 /* FIXME: Need to use characterized value */
403 .timing_default = {
404 .timing0 = 0xA0400273,
405 .timing1 = 0x00030402,
406 },
407 .timing_read = {
408 .timing0 = 0xA0400273,
409 .timing1 = 0x00030402,
410 },
411 },
412};
413
414static void p1852_nor_init(void)
415{
416 tegra_nor_device.resource[2].end = TEGRA_NOR_FLASH_BASE + SZ_64M - 1;
417 tegra_nor_device.dev.platform_data = &p1852_nor_data;
418 platform_device_register(&tegra_nor_device);
419}
420
421static void __init tegra_p1852_init(void)
422{
423 tegra_init_board_info();
424 tegra_clk_init_from_table(p1852_clk_init_table);
425 p1852_pinmux_init();
426 p1852_i2c_init();
427 p1852_i2s_audio_init();
428 p1852_gpio_init();
429 p1852_uart_init();
430 p1852_usb_init();
431 p1852_sdhci_init();
432 p1852_spi_init();
433 platform_add_devices(p1852_devices, ARRAY_SIZE(p1852_devices));
434 p1852_panel_init();
435 p1852_nor_init();
436 p1852_pcie_init();
437}
438
439static void __init tegra_p1852_reserve(void)
440{
441#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM)
442 tegra_reserve(0, SZ_8M, 0);
443#else
444 tegra_reserve(SZ_128M, SZ_8M, 0);
445#endif
446}
447
448MACHINE_START(P1852, "p1852")
449 .boot_params = 0x80000100,
450 .init_irq = tegra_init_irq,
451 .init_early = tegra_init_early,
452 .init_machine = tegra_p1852_init,
453 .map_io = tegra_map_common_io,
454 .reserve = tegra_p1852_reserve,
455 .timer = &tegra_timer,
456MACHINE_END
diff --git a/arch/arm/mach-tegra/board-p1852.h b/arch/arm/mach-tegra/board-p1852.h
new file mode 100644
index 00000000000..f146f30ed2c
--- /dev/null
+++ b/arch/arm/mach-tegra/board-p1852.h
@@ -0,0 +1,99 @@
1/*
2 * arch/arm/mach-tegra/board-p1852.h
3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef _MACH_TEGRA_BOARD_P1852_H
20#define _MACH_TEGRA_BOARD_P1852_H
21
22#include <mach/gpio.h>
23#include <mach/irqs.h>
24#include <linux/gpio.h>
25#include <linux/mfd/tps6591x.h>
26
27
28/* External peripheral act as gpio */
29/* TPS6591x GPIOs */
30#define TPS6591X_GPIO_BASE TEGRA_NR_GPIOS
31#define TPS6591X_GPIO_GP0 (TPS6591X_GPIO_BASE + 0)
32#define TPS6591X_GPIO_GP1 (TPS6591X_GPIO_BASE + 1)
33#define TPS6591X_GPIO_GP2 (TPS6591X_GPIO_BASE + 2)
34#define TPS6591X_GPIO_GP3 (TPS6591X_GPIO_BASE + 3)
35#define TPS6591X_GPIO_GP4 (TPS6591X_GPIO_BASE + 4)
36#define TPS6591X_GPIO_GP5 (TPS6591X_GPIO_BASE + 5)
37#define TPS6591X_GPIO_GP6 (TPS6591X_GPIO_BASE + 6)
38#define TPS6591X_GPIO_GP7 (TPS6591X_GPIO_BASE + 7)
39#define TPS6591X_GPIO_GP8 (TPS6591X_GPIO_BASE + 8)
40#define TPS6591X_GPIO_END TPS6591X_GPIO_GP8
41
42/* CAM_TCA6416 GPIOs */
43#define CAM_TCA6416_GPIO_BASE (TPS6591X_GPIO_END + 1)
44#define CAM1_PWR_DN_GPIO (CAM_TCA6416_GPIO_BASE + 0)
45#define CAM1_RST_L_GPIO (CAM_TCA6416_GPIO_BASE + 1)
46#define CAM1_AF_PWR_DN_L_GPIO (CAM_TCA6416_GPIO_BASE + 2)
47#define CAM1_LDO_SHUTDN_L_GPIO (CAM_TCA6416_GPIO_BASE + 3)
48#define CAM2_PWR_DN_GPIO (CAM_TCA6416_GPIO_BASE + 4)
49#define CAM2_RST_L_GPIO (CAM_TCA6416_GPIO_BASE + 5)
50#define CAM2_AF_PWR_DN_L_GPIO (CAM_TCA6416_GPIO_BASE + 6)
51#define CAM2_LDO_SHUTDN_L_GPIO (CAM_TCA6416_GPIO_BASE + 7)
52#define CAM_FRONT_PWR_DN_GPIO (CAM_TCA6416_GPIO_BASE + 8)
53#define CAM_FRONT_RST_L_GPIO (CAM_TCA6416_GPIO_BASE + 9)
54#define CAM_FRONT_AF_PWR_DN_L_GPIO (CAM_TCA6416_GPIO_BASE + 10)
55#define CAM_FRONT_LDO_SHUTDN_L_GPIO (CAM_TCA6416_GPIO_BASE + 11)
56#define CAM_FRONT_LED_EXP (CAM_TCA6416_GPIO_BASE + 12)
57#define CAM_SNN_LED_REAR_EXP (CAM_TCA6416_GPIO_BASE + 13)
58/* PIN 19 NOT USED and is reserved */
59#define CAM_NOT_USED (CAM_TCA6416_GPIO_BASE + 14)
60#define CAM_I2C_MUX_RST_EXP (CAM_TCA6416_GPIO_BASE + 15)
61#define CAM_TCA6416_GPIO_END CAM_I2C_MUX_RST_EXP
62
63/* WM8903 gpios */
64#define WM8903_GPIO_BASE (CAM_TCA6416_GPIO_END + 1)
65#define WM8903_GP1 (WM8903_GPIO_BASE + 0)
66#define WM8903_GP2 (WM8903_GPIO_BASE + 1)
67#define WM8903_GP3 (WM8903_GPIO_BASE + 2)
68#define WM8903_GP4 (WM8903_GPIO_BASE + 3)
69#define WM8903_GP5 (WM8903_GPIO_BASE + 4)
70#define WM8903_GPIO_END WM8903_GP5
71
72/* CAMERA RELATED GPIOs on p1852 */
73#define OV5650_RESETN_GPIO TEGRA_GPIO_PBB0
74#define CAM1_POWER_DWN_GPIO TEGRA_GPIO_PBB5
75#define CAM2_POWER_DWN_GPIO TEGRA_GPIO_PBB6
76#define CAM3_POWER_DWN_GPIO TEGRA_GPIO_PBB7
77#define CAMERA_CSI_CAM_SEL_GPIO TEGRA_GPIO_PBB4
78#define CAMERA_CSI_MUX_SEL_GPIO TEGRA_GPIO_PCC1
79#define CAM1_LDO_EN_GPIO TEGRA_GPIO_PR6
80#define CAM2_LDO_EN_GPIO TEGRA_GPIO_PR7
81#define CAM3_LDO_EN_GPIO TEGRA_GPIO_PS0
82
83
84#define AC_PRESENT_GPIO TPS6591X_GPIO_GP4
85/*****************Interrupt tables ******************/
86/* External peripheral act as interrupt controller */
87/* TPS6591x IRQs */
88#define TPS6591X_IRQ_BASE TEGRA_NR_IRQS
89#define TPS6591X_IRQ_END (TPS6591X_IRQ_BASE + 18)
90
91#define AC_PRESENT_INT (TPS6591X_INT_GPIO4 + TPS6591X_IRQ_BASE)
92
93int p1852_sdhci_init(void);
94int p1852_pinmux_init(void);
95int p1852_panel_init(void);
96int p1852_gpio_init(void);
97int p1852_pins_state_init(void);
98
99#endif
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c
new file mode 100644
index 00000000000..bdd2627dd87
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00-pinmux.c
@@ -0,0 +1,155 @@
1/*
2 * arch/arm/mach-tegra/board-paz00-pinmux.c
3 *
4 * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/gpio.h>
19#include <mach/pinmux.h>
20
21#include "gpio-names.h"
22#include "board-paz00.h"
23
24static struct tegra_pingroup_config paz00_pinmux[] = {
25 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
26 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
27 {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
28 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
30 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
31 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
32 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
33 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
35 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
36 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
37 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
38 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
39 {TEGRA_PINGROUP_DTA, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
40 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
41 {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
42 {TEGRA_PINGROUP_DTD, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
43 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
44 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_GMC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
49 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
51 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
52 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
53 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
55 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
61 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
64 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
86 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
87 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
89 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
90 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
91 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
92 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
93 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
94 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
96 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
97 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
98 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
101 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
102 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
104 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_SDC, TEGRA_MUX_TWC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
109 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
112 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_SPID, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_RSVD4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_UAD, TEGRA_MUX_SPDIF, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
141};
142
143static struct tegra_gpio_table gpio_table[] = {
144 { .gpio = TEGRA_GPIO_SD1_CD, .enable = true },
145 { .gpio = TEGRA_GPIO_SD1_WP, .enable = true },
146 { .gpio = TEGRA_GPIO_SD1_POWER, .enable = true },
147 { .gpio = TEGRA_ULPI_RST, .enable = true },
148};
149
150void paz00_pinmux_init(void)
151{
152 tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
153
154 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
155}
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
new file mode 100644
index 00000000000..56dc2c27928
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -0,0 +1,179 @@
1/*
2 * Copyright (C) 2010 NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/gpio.h>
18
19#include <mach/pinmux.h>
20
21#include "gpio-names.h"
22#include "board-seaboard.h"
23
24#define DEFAULT_DRIVE(_name) \
25 { \
26 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
27 .hsm = TEGRA_HSM_DISABLE, \
28 .schmitt = TEGRA_SCHMITT_ENABLE, \
29 .drive = TEGRA_DRIVE_DIV_1, \
30 .pull_down = TEGRA_PULL_31, \
31 .pull_up = TEGRA_PULL_31, \
32 .slew_rising = TEGRA_SLEW_SLOWEST, \
33 .slew_falling = TEGRA_SLEW_SLOWEST, \
34 }
35
36static __initdata struct tegra_drive_pingroup_config seaboard_drive_pinmux[] = {
37 DEFAULT_DRIVE(SDIO1),
38};
39
40static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
41 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
42 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
43 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
44 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
46 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
49 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
50 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
51 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
52 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
53 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
55 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
60 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
61 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
63 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
64 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
69 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
70 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
80 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
85 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
92 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_LDC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_LM1, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
106 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
108 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
109 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
112 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
116 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
117 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
118 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
120 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
121 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
122 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
125 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
128 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
130 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
131 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
134 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
135 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
136 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
137 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
138 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
139 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
140 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
141 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
142 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
143 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
144 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
145 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
146 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
147 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
148 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
149 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
150 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
151 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
152 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
153 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
154 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
155 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
156 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
157};
158
159
160
161
162static struct tegra_gpio_table gpio_table[] = {
163 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
164 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
165 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
166 { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true },
167 { .gpio = TEGRA_GPIO_POWERKEY, .enable = true },
168 { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
169};
170
171void __init seaboard_pinmux_init(void)
172{
173 tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
174
175 tegra_drive_pinmux_config_table(seaboard_drive_pinmux,
176 ARRAY_SIZE(seaboard_drive_pinmux));
177
178 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
179}
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
new file mode 100644
index 00000000000..56cbabf6aa6
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -0,0 +1,228 @@
1/*
2 * Copyright (c) 2010, 2011 NVIDIA Corporation.
3 * Copyright (C) 2010, 2011 Google, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/serial_8250.h>
21#include <linux/i2c.h>
22#include <linux/delay.h>
23#include <linux/input.h>
24#include <linux/io.h>
25#include <linux/gpio.h>
26#include <linux/gpio_keys.h>
27
28#include <mach/iomap.h>
29#include <mach/irqs.h>
30#include <mach/sdhci.h>
31
32#include <asm/mach-types.h>
33#include <asm/mach/arch.h>
34
35#include "board.h"
36#include "board-seaboard.h"
37#include "clock.h"
38#include "devices.h"
39#include "gpio-names.h"
40
41static struct plat_serial8250_port debug_uart_platform_data[] = {
42 {
43 /* Memory and IRQ filled in before registration */
44 .flags = UPF_BOOT_AUTOCONF,
45 .iotype = UPIO_MEM,
46 .regshift = 2,
47 .uartclk = 216000000,
48 }, {
49 .flags = 0,
50 }
51};
52
53static struct platform_device debug_uart = {
54 .name = "serial8250",
55 .id = PLAT8250_DEV_PLATFORM,
56 .dev = {
57 .platform_data = debug_uart_platform_data,
58 },
59};
60
61static __initdata struct tegra_clk_init_table seaboard_clk_init_table[] = {
62 /* name parent rate enabled */
63 { "uartb", "pll_p", 216000000, true},
64 { "uartd", "pll_p", 216000000, true},
65 { NULL, NULL, 0, 0},
66};
67
68static struct gpio_keys_button seaboard_gpio_keys_buttons[] = {
69 {
70 .code = SW_LID,
71 .gpio = TEGRA_GPIO_LIDSWITCH,
72 .active_low = 0,
73 .desc = "Lid",
74 .type = EV_SW,
75 .wakeup = 1,
76 .debounce_interval = 1,
77 },
78 {
79 .code = KEY_POWER,
80 .gpio = TEGRA_GPIO_POWERKEY,
81 .active_low = 1,
82 .desc = "Power",
83 .type = EV_KEY,
84 .wakeup = 1,
85 },
86};
87
88static struct gpio_keys_platform_data seaboard_gpio_keys = {
89 .buttons = seaboard_gpio_keys_buttons,
90 .nbuttons = ARRAY_SIZE(seaboard_gpio_keys_buttons),
91};
92
93static struct platform_device seaboard_gpio_keys_device = {
94 .name = "gpio-keys",
95 .id = -1,
96 .dev = {
97 .platform_data = &seaboard_gpio_keys,
98 }
99};
100
101static struct tegra_sdhci_platform_data sdhci_pdata1 = {
102 .cd_gpio = -1,
103 .wp_gpio = -1,
104 .power_gpio = -1,
105};
106
107static struct tegra_sdhci_platform_data sdhci_pdata3 = {
108 .cd_gpio = TEGRA_GPIO_SD2_CD,
109 .wp_gpio = TEGRA_GPIO_SD2_WP,
110 .power_gpio = TEGRA_GPIO_SD2_POWER,
111};
112
113static struct tegra_sdhci_platform_data sdhci_pdata4 = {
114 .cd_gpio = -1,
115 .wp_gpio = -1,
116 .power_gpio = -1,
117 .is_8bit = 1,
118};
119
120static struct platform_device *seaboard_devices[] __initdata = {
121 &debug_uart,
122 &tegra_pmu_device,
123 &tegra_sdhci_device4,
124 &tegra_sdhci_device3,
125 &tegra_sdhci_device1,
126 &seaboard_gpio_keys_device,
127};
128
129static struct i2c_board_info __initdata isl29018_device = {
130 I2C_BOARD_INFO("isl29018", 0x44),
131 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
132};
133
134static struct i2c_board_info __initdata adt7461_device = {
135 I2C_BOARD_INFO("adt7461", 0x4c),
136};
137
138static void __init seaboard_i2c_init(void)
139{
140 gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
141 gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
142
143 i2c_register_board_info(0, &isl29018_device, 1);
144
145 i2c_register_board_info(3, &adt7461_device, 1);
146
147 platform_device_register(&tegra_i2c_device1);
148 platform_device_register(&tegra_i2c_device2);
149 platform_device_register(&tegra_i2c_device3);
150 platform_device_register(&tegra_i2c_device4);
151}
152
153static void __init seaboard_common_init(void)
154{
155 seaboard_pinmux_init();
156
157 tegra_clk_init_from_table(seaboard_clk_init_table);
158
159 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
160 tegra_sdhci_device3.dev.platform_data = &sdhci_pdata3;
161 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
162
163 platform_add_devices(seaboard_devices, ARRAY_SIZE(seaboard_devices));
164}
165
166static void __init tegra_seaboard_init(void)
167{
168 /* Seaboard uses UARTD for the debug port. */
169 debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTD_BASE);
170 debug_uart_platform_data[0].mapbase = TEGRA_UARTD_BASE;
171 debug_uart_platform_data[0].irq = INT_UARTD;
172
173 seaboard_common_init();
174
175 seaboard_i2c_init();
176}
177
178static void __init tegra_kaen_init(void)
179{
180 /* Kaen uses UARTB for the debug port. */
181 debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE);
182 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
183 debug_uart_platform_data[0].irq = INT_UARTB;
184
185 seaboard_common_init();
186
187 seaboard_i2c_init();
188}
189
190static void __init tegra_wario_init(void)
191{
192 /* Wario uses UARTB for the debug port. */
193 debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE);
194 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
195 debug_uart_platform_data[0].irq = INT_UARTB;
196
197 seaboard_common_init();
198
199 seaboard_i2c_init();
200}
201
202
203MACHINE_START(SEABOARD, "seaboard")
204 .boot_params = 0x00000100,
205 .map_io = tegra_map_common_io,
206 .init_early = tegra_init_early,
207 .init_irq = tegra_init_irq,
208 .timer = &tegra_timer,
209 .init_machine = tegra_seaboard_init,
210MACHINE_END
211
212MACHINE_START(KAEN, "kaen")
213 .boot_params = 0x00000100,
214 .map_io = tegra_map_common_io,
215 .init_early = tegra_init_early,
216 .init_irq = tegra_init_irq,
217 .timer = &tegra_timer,
218 .init_machine = tegra_kaen_init,
219MACHINE_END
220
221MACHINE_START(WARIO, "wario")
222 .boot_params = 0x00000100,
223 .map_io = tegra_map_common_io,
224 .init_early = tegra_init_early,
225 .init_irq = tegra_init_irq,
226 .timer = &tegra_timer,
227 .init_machine = tegra_wario_init,
228MACHINE_END
diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h
new file mode 100644
index 00000000000..d8415e1a843
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard.h
@@ -0,0 +1,41 @@
1/*
2 * arch/arm/mach-tegra/board-seaboard.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _MACH_TEGRA_BOARD_SEABOARD_H
18#define _MACH_TEGRA_BOARD_SEABOARD_H
19
20#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
21#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
22#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PI6
23#define TEGRA_GPIO_LIDSWITCH TEGRA_GPIO_PC7
24#define TEGRA_GPIO_USB1 TEGRA_GPIO_PD0
25#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2
26#define TEGRA_GPIO_BACKLIGHT TEGRA_GPIO_PD4
27#define TEGRA_GPIO_LVDS_SHUTDOWN TEGRA_GPIO_PB2
28#define TEGRA_GPIO_BACKLIGHT_PWM TEGRA_GPIO_PU5
29#define TEGRA_GPIO_BACKLIGHT_VDD TEGRA_GPIO_PW0
30#define TEGRA_GPIO_EN_VDD_PNL TEGRA_GPIO_PC6
31#define TEGRA_GPIO_MAGNETOMETER TEGRA_GPIO_PN5
32#define TEGRA_GPIO_ISL29018_IRQ TEGRA_GPIO_PZ2
33#define TEGRA_GPIO_AC_ONLINE TEGRA_GPIO_PV3
34
35#define TPS_GPIO_BASE TEGRA_NR_GPIOS
36
37#define TPS_GPIO_WWAN_PWR (TPS_GPIO_BASE + 2)
38
39void seaboard_pinmux_init(void);
40
41#endif
diff --git a/arch/arm/mach-tegra/board-touch-kai-synaptics-spi.c b/arch/arm/mach-tegra/board-touch-kai-synaptics-spi.c
new file mode 100644
index 00000000000..989cf3339be
--- /dev/null
+++ b/arch/arm/mach-tegra/board-touch-kai-synaptics-spi.c
@@ -0,0 +1,109 @@
1/*
2 * arch/arm/mach-tegra/board-touch-synaptics-spi.c
3 *
4 * Copyright (C) 2010-2012 NVIDIA Corporation
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/spi/spi.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21#include <linux/input.h>
22#include <linux/interrupt.h>
23#include <linux/spi/spi.h>
24#include <linux/rmi.h>
25#include "board.h"
26#include "board-kai.h"
27
28#define SYNAPTICS_SPI_CS 0
29#define SYNAPTICS_BUTTON_CODES {KEY_HOME, KEY_BACK,}
30
31static unsigned char synaptics_button_codes[] = SYNAPTICS_BUTTON_CODES;
32
33static struct rmi_f19_button_map synaptics_button_map = {
34 .nbuttons = ARRAY_SIZE(synaptics_button_codes),
35 .map = synaptics_button_codes,
36};
37
38static int synaptics_touchpad_gpio_setup(void *gpio_data, bool configure)
39{
40 if (configure) {
41 tegra_gpio_enable(SYNAPTICS_ATTN_GPIO);
42 gpio_request(SYNAPTICS_ATTN_GPIO, "synaptics-irq");
43 gpio_direction_input(SYNAPTICS_ATTN_GPIO);
44
45 tegra_gpio_enable(SYNAPTICS_RESET_GPIO);
46 gpio_request(SYNAPTICS_RESET_GPIO, "synaptics-reset");
47 gpio_direction_output(SYNAPTICS_RESET_GPIO, 0);
48
49 msleep(1);
50 gpio_set_value(SYNAPTICS_RESET_GPIO, 1);
51 msleep(100);
52 } else {
53 gpio_free(SYNAPTICS_ATTN_GPIO);
54 gpio_free(SYNAPTICS_RESET_GPIO);
55 tegra_gpio_disable(SYNAPTICS_ATTN_GPIO);
56 tegra_gpio_disable(SYNAPTICS_RESET_GPIO);
57 }
58 return 0;
59}
60
61static struct rmi_device_platform_data synaptics_platformdata = {
62 .driver_name = "rmi_generic",
63 .irq = SYNAPTICS_ATTN_GPIO,
64 .irq_polarity = RMI_IRQ_ACTIVE_LOW,
65 .gpio_config = synaptics_touchpad_gpio_setup,
66 .spi_data = {
67 .block_delay_us = 15,
68 .read_delay_us = 15,
69 .write_delay_us = 2,
70 },
71 .axis_align = {
72 .flip_y = true,
73 },
74 .button_map = &synaptics_button_map,
75};
76
77struct spi_board_info synaptics_2002_spi_board[] = {
78 {
79 .modalias = "rmi_spi",
80 .bus_num = 0,
81 .chip_select = 0,
82 .irq = 999, /* just to make sure this one is not being used */
83 .max_speed_hz = 1*1000*1000,
84 .mode = SPI_MODE_3,
85 .platform_data = &synaptics_platformdata,
86 },
87};
88
89int __init touch_init_synaptics_kai(void)
90{
91 pr_info("%s: registering synaptics_2002_spi_board\n", __func__);
92 pr_info(" modalias = %s\n",
93 synaptics_2002_spi_board->modalias);
94 pr_info(" bus_num = %d\n",
95 synaptics_2002_spi_board->bus_num);
96 pr_info(" chip_select = %d\n",
97 synaptics_2002_spi_board->chip_select);
98 pr_info(" irq = %d\n",
99 synaptics_2002_spi_board->irq);
100 pr_info(" max_speed_hz = %d\n",
101 synaptics_2002_spi_board->max_speed_hz);
102 pr_info(" mode = %d\n",
103 synaptics_2002_spi_board->mode);
104
105 msleep(100);
106 spi_register_board_info(synaptics_2002_spi_board,
107 ARRAY_SIZE(synaptics_2002_spi_board));
108 return 0;
109}
diff --git a/arch/arm/mach-tegra/board-touch-raydium_spi.c b/arch/arm/mach-tegra/board-touch-raydium_spi.c
new file mode 100644
index 00000000000..9f5843a0e62
--- /dev/null
+++ b/arch/arm/mach-tegra/board-touch-raydium_spi.c
@@ -0,0 +1,243 @@
1/*
2 * arch/arm/mach-tegra/board-touch-raydium_spi.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/spi/spi.h>
24#include <linux/delay.h>
25#include <linux/gpio.h>
26#include <linux/spi/rm31080a_ts.h>
27
28/* Raydium touchscreen Driver data */
29/*-----------------------------------------------------*/
30static const u8 rm31080_config_cardhu[] = {
31 0x00, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x20, 0x0f,
32 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x10, 0x10, 0x06, 0x06, 0x04, 0x01, 0x02, 0x00,
36 0x00, 0x0a, 0x00, 0xd5, 0x2b, 0x00, 0x00, 0x09,
37 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x28, 0xf8, 0x50, 0xce, 0x0a, 0x0c, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x16, 0x1b, 0x14, 0x16, 0x16, 0x18, 0x32, 0x19,
42 0x1d, 0x08, 0x30, 0x19, 0x10, 0xf6, 0xe2, 0x08,
43 0x28, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21,
47 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x80,
49 0x00, 0xc0, 0x00, 0xc2, 0x00, 0xf0, 0xed, 0x02,
50 0xed, 0x02, 0x00, 0x90, 0x0a, 0x06, 0x80, 0x02,
51 0x00, 0x04, 0x00, 0x20, 0x03, 0x02, 0x08, 0x03,
52 0x10, 0x20, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x10, 0x10, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x50, 0x80, 0x02, 0x02, 0x02, 0x00, 0x00, 0x33,
58 0x32, 0x00, 0x01, 0x4c, 0xfa, 0x00, 0x00, 0x43,
59 0x3c, 0x00, 0x01, 0x38, 0xe6, 0x00, 0x00, 0x26,
60 0x19, 0x00, 0x02, 0x66, 0x19, 0x00, 0x02, 0x50,
61 0x64, 0x00, 0x00, 0x36, 0x4a, 0x00, 0x00, 0x0c,
62 0x19, 0x00, 0x02, 0x64, 0x96, 0xab, 0x88, 0x78,
63 0x88, 0x78, 0x04, 0x0f, 0x38, 0xff, 0x02, 0x04,
64 0x80, 0xe0, 0x13, 0x01, 0x00, 0x44, 0x61, 0x12,
65 0x41, 0x00, 0x00, 0x00, 0x00, 0x97, 0x01, 0x0c,
66 0x44, 0x61, 0x12, 0x29, 0x29, 0x41, 0x00, 0x00,
67 0x97, 0x06, 0x0c, 0x12, 0x41, 0x44, 0x52, 0x52,
68 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x80, 0x80, 0x01, 0x80, 0x01, 0x80,
71 0x22, 0x33, 0x22, 0x33, 0x66, 0x20, 0xff, 0xc9,
72 0x19, 0xd0, 0xd0, 0x44, 0x00, 0x10, 0x00, 0x80,
73 0x05, 0x44, 0xff, 0x00, 0x00, 0x10, 0x50, 0x00,
74 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x18, 0x0f,
75 0x0f, 0xf0, 0xf0, 0x00, 0x00, 0x10, 0x10, 0x00,
76 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
77 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x10, 0x01, 0x10, 0x01, 0x02,
79};
80
81/* Wintek 7" MB (01.18.10.01.10) */
82static const u8 rm31080_config_kai_mainboard[] = {
83 0x00, 0x00, 0x00, 0x00, 0x1e, 0x12, 0x20, 0x0f,
84 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x07,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x19, 0x19, 0x06, 0x06, 0x04, 0x10, 0x02, 0x00,
88 0x00, 0x0a, 0x00, 0xd5, 0x2b, 0x00, 0x00, 0x09,
89 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x28, 0xec, 0x5f, 0xce, 0x14, 0x0a, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x14, 0x19, 0x14, 0x19, 0x10, 0x10, 0x32, 0x12,
94 0x1d, 0x08, 0x20, 0x19, 0x10, 0xf6, 0xe2, 0x08,
95 0x1c, 0x04, 0x04, 0x20, 0x0f, 0x1c, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x28, 0x00, 0x10, 0x22, 0x00, 0x00, 0x21,
99 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60,
101 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xd0, 0xed, 0x02,
102 0xed, 0x02, 0x00, 0x90, 0x0a, 0x06, 0x20, 0x02,
103 0x70, 0x03, 0x20, 0x1b, 0x03, 0x02, 0x08, 0x03,
104 0x10, 0x20, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x20, 0x20, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x50, 0x80, 0x02, 0x02, 0x02, 0x00, 0x00, 0x33,
110 0x32, 0x00, 0x01, 0x60, 0xfa, 0x00, 0x00, 0x43,
111 0x3c, 0x00, 0x01, 0x4c, 0xe6, 0x00, 0x00, 0x26,
112 0x19, 0x00, 0x02, 0x7a, 0x19, 0x00, 0x02, 0x50,
113 0x64, 0x00, 0x00, 0x36, 0x4a, 0x00, 0x00, 0x0c,
114 0x19, 0x00, 0x02, 0x64, 0x96, 0xab, 0x88, 0x78,
115 0x88, 0x78, 0x04, 0x0f, 0x38, 0xff, 0x02, 0x04,
116 0x80, 0xe0, 0x13, 0x02, 0x00, 0x2c, 0x1b, 0x4b,
117 0x2e, 0x00, 0x00, 0x00, 0x00, 0x97, 0x06, 0x0c,
118 0x2c, 0x1b, 0x2e, 0x3c, 0x3c, 0x4b, 0x00, 0x00,
119 0x97, 0x06, 0x0c, 0x12, 0x41, 0x44, 0x52, 0x52,
120 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x80, 0x80, 0x01, 0x80, 0x01, 0x80,
123 0x21, 0x33, 0x21, 0x33, 0x66, 0x20, 0xff, 0xc9,
124 0x19, 0xd0, 0xd0, 0x44, 0x00, 0x10, 0x00, 0x80,
125 0x05, 0x44, 0xff, 0x00, 0x00, 0x10, 0x50, 0x00,
126 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x18, 0x0f,
127 0x0f, 0xf0, 0xf0, 0x00, 0x00, 0x10, 0x10, 0x00,
128 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
129 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x10, 0x01, 0x10, 0x01, 0x02,
131};
132
133/* Wintek 7" PCB (01.18.10.01.10), TS IC is on the mainboard */
134static const u8 rm31080_config_kai_pcb[] = {
135 0x00, 0x00, 0x00, 0x00, 0x1e, 0x12, 0x20, 0x0f,
136 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x07,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x19, 0x19, 0x06, 0x06, 0x04, 0x10, 0x02, 0x00,
140 0x00, 0x0a, 0x00, 0xd5, 0x2b, 0x00, 0x00, 0x09,
141 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x28, 0xec, 0x5f, 0xce, 0x14, 0x0a, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x14, 0x19, 0x14, 0x19, 0x10, 0x10, 0x32, 0x12,
146 0x1d, 0x08, 0x20, 0x19, 0x10, 0xf6, 0xe2, 0x08,
147 0x1c, 0x04, 0x04, 0x20, 0x0f, 0x1c, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x28, 0x00, 0x10, 0x22, 0x00, 0x00, 0x21,
151 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60,
153 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xd0, 0xed, 0x02,
154 0xed, 0x02, 0x00, 0x90, 0x0a, 0x06, 0x20, 0x02,
155 0x70, 0x03, 0x20, 0x1b, 0x03, 0x02, 0x08, 0x03,
156 0x10, 0x20, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x20, 0x20, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x50, 0x80, 0x02, 0x02, 0x02, 0x00, 0x00, 0x33,
162 0x32, 0x00, 0x01, 0x60, 0xfa, 0x00, 0x00, 0x43,
163 0x3c, 0x00, 0x01, 0x4c, 0xe6, 0x00, 0x00, 0x26,
164 0x19, 0x00, 0x02, 0x7a, 0x19, 0x00, 0x02, 0x50,
165 0x64, 0x00, 0x00, 0x36, 0x4a, 0x00, 0x00, 0x0c,
166 0x19, 0x00, 0x02, 0x64, 0x96, 0xab, 0x88, 0x78,
167 0x88, 0x78, 0x04, 0x0f, 0x38, 0xff, 0x02, 0x04,
168 0x80, 0xe0, 0x13, 0x02, 0x00, 0x28, 0x17, 0x4b,
169 0x2e, 0x00, 0x00, 0x00, 0x00, 0x97, 0x06, 0x0c,
170 0x28, 0x17, 0x2e, 0x3c, 0x3c, 0x4b, 0x00, 0x00,
171 0x97, 0x06, 0x0c, 0x12, 0x41, 0x44, 0x52, 0x52,
172 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x80, 0x80, 0x01, 0x80, 0x01, 0x80,
175 0x21, 0x33, 0x21, 0x33, 0x66, 0x20, 0xff, 0xc9,
176 0x19, 0xd0, 0xd0, 0x44, 0x00, 0x10, 0x00, 0x80,
177 0x05, 0x44, 0xff, 0x00, 0x00, 0x10, 0x50, 0x00,
178 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x18, 0x0f,
179 0x0f, 0xf0, 0xf0, 0x00, 0x00, 0x10, 0x10, 0x00,
180 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
181 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x10, 0x01, 0x10, 0x01, 0x02,
183};
184
185struct rm_spi_ts_platform_data rm31080ts_data = {
186 .gpio_reset = 0,
187 .config = 0,
188};
189
190struct spi_board_info rm31080a_spi_board[1] = {
191 {
192 .modalias = "rm_ts_spidev",
193 .bus_num = 0,
194 .chip_select = 0,
195 .max_speed_hz = 13 * 1000 * 1000,
196 .mode = SPI_MODE_0,
197 .platform_data = &rm31080ts_data,
198 },
199};
200
201int __init touch_init_raydium(int irq_gpio, int reset_gpio, int platform)
202{
203 int err = 0;
204 tegra_gpio_enable(irq_gpio);
205 gpio_request(irq_gpio, "raydium-irq");
206 gpio_direction_input(irq_gpio);
207
208 tegra_gpio_enable(reset_gpio);
209 gpio_request(reset_gpio, "raydium-reset");
210 gpio_direction_output(reset_gpio, 0);
211
212 rm31080ts_data.gpio_reset = reset_gpio;
213
214 msleep(1);
215 gpio_set_value(reset_gpio, 1);
216 msleep(100);
217
218 rm31080a_spi_board[0].irq = TEGRA_GPIO_TO_IRQ(irq_gpio);
219
220 switch (platform) {
221 case 0:
222 pr_info("Raydium Kai PCB based touch init\n");
223 rm31080ts_data.config = rm31080_config_kai_pcb;
224 break;
225 case 1:
226 pr_info("Raydium Kai On-Board touch init\n");
227 rm31080ts_data.config = rm31080_config_kai_mainboard;
228 break;
229 case 2:
230 pr_info("Raydium cardhu touch init\n");
231 rm31080ts_data.config = rm31080_config_cardhu;
232 break;
233 default:
234 pr_err("touch_id error, no touch\n");
235 err = -ENODEV;
236 }
237
238 if(!err)
239 spi_register_board_info(rm31080a_spi_board,
240 ARRAY_SIZE(rm31080a_spi_board));
241
242 return err;
243}
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c
new file mode 100644
index 00000000000..47c596cdbf3
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c
@@ -0,0 +1,157 @@
1/*
2 * arch/arm/mach-tegra/board-trimslice-pinmux.c
3 *
4 * Copyright (C) 2011 CompuLab, Ltd.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19
20#include <mach/pinmux.h>
21#include <mach/gpio.h>
22
23#include "gpio-names.h"
24#include "board-trimslice.h"
25
26static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
27 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
28 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
30 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
31 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
32 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
33 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
35 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
36 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
37 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
38 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
39 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
40 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
41 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
42 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
43 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
44 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
45 {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
46 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_GMB, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
49 {TEGRA_PINGROUP_GMC, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
51 {TEGRA_PINGROUP_GME, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
52 {TEGRA_PINGROUP_GPU, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
53 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
55 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
56 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
57 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
58 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
59 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
60 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
61 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
62 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
63 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
64 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
65 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
66 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
92 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
95 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
98 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
100 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
101 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
103 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
106 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
107 {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
113 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
114 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
120 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
124 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
126 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
127 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
128 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
130 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
132 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
133 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
134 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
141 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
142 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
143};
144
145static struct tegra_gpio_table gpio_table[] = {
146 { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */
147 { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */
148
149 { .gpio = TRIMSLICE_GPIO_USB1_MODE, .enable = true }, /* USB1 mode */
150 { .gpio = TRIMSLICE_GPIO_USB2_RST, .enable = true }, /* USB2 PHY rst */
151};
152
153void __init trimslice_pinmux_init(void)
154{
155 tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
156 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
157}
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
new file mode 100644
index 00000000000..823060ec478
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -0,0 +1,182 @@
1/*
2 * arch/arm/mach-tegra/board-trimslice.c
3 *
4 * Copyright (C) 2011 CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on board-harmony.c
8 * Copyright (C) 2010 Google, Inc.
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/platform_device.h>
24#include <linux/serial_8250.h>
25#include <linux/io.h>
26#include <linux/i2c.h>
27#include <linux/gpio.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/setup.h>
32
33#include <mach/iomap.h>
34#include <mach/sdhci.h>
35#include <mach/gpio.h>
36#include <mach/pci.h>
37
38#include "board.h"
39#include "clock.h"
40#include "devices.h"
41#include "gpio-names.h"
42
43#include "board-trimslice.h"
44
45static struct plat_serial8250_port debug_uart_platform_data[] = {
46 {
47 .membase = IO_ADDRESS(TEGRA_UARTA_BASE),
48 .mapbase = TEGRA_UARTA_BASE,
49 .irq = INT_UARTA,
50 .flags = UPF_BOOT_AUTOCONF,
51 .iotype = UPIO_MEM,
52 .regshift = 2,
53 .uartclk = 216000000,
54 }, {
55 .flags = 0
56 }
57};
58
59static struct platform_device debug_uart = {
60 .name = "serial8250",
61 .id = PLAT8250_DEV_PLATFORM,
62 .dev = {
63 .platform_data = debug_uart_platform_data,
64 },
65};
66static struct tegra_sdhci_platform_data sdhci_pdata1 = {
67 .cd_gpio = -1,
68 .wp_gpio = -1,
69 .power_gpio = -1,
70};
71
72static struct tegra_sdhci_platform_data sdhci_pdata4 = {
73 .cd_gpio = TRIMSLICE_GPIO_SD4_CD,
74 .wp_gpio = TRIMSLICE_GPIO_SD4_WP,
75 .power_gpio = -1,
76};
77
78static struct platform_device trimslice_audio_device = {
79 .name = "tegra-snd-trimslice",
80 .id = 0,
81};
82
83static struct tegra_pci_platform_data trimslice_pci_platform_data = {
84 .port_status[0] = 1,
85 .port_status[1] = 1,
86 .use_dock_detect = 0,
87 .gpio = 0,
88};
89
90static struct platform_device *trimslice_devices[] __initdata = {
91 &debug_uart,
92 &tegra_sdhci_device1,
93 &tegra_sdhci_device4,
94 &tegra_i2s_device1,
95 &tegra_das_device,
96 &tegra_pcm_device,
97 &trimslice_audio_device,
98 &trimslice_pci_platform_data,
99};
100
101static struct i2c_board_info trimslice_i2c3_board_info[] = {
102 {
103 I2C_BOARD_INFO("tlv320aic23", 0x1a),
104 },
105 {
106 I2C_BOARD_INFO("em3027", 0x56),
107 },
108};
109
110static void trimslice_i2c_init(void)
111{
112 platform_device_register(&tegra_i2c_device1);
113 platform_device_register(&tegra_i2c_device2);
114 platform_device_register(&tegra_i2c_device3);
115
116 i2c_register_board_info(2, trimslice_i2c3_board_info,
117 ARRAY_SIZE(trimslice_i2c3_board_info));
118}
119
120static void trimslice_usb_init(void)
121{
122 int err;
123
124 platform_device_register(&tegra_ehci3_device);
125
126 platform_device_register(&tegra_ehci2_device);
127
128 err = gpio_request_one(TRIMSLICE_GPIO_USB1_MODE, GPIOF_OUT_INIT_HIGH,
129 "usb1mode");
130 if (err) {
131 pr_err("TrimSlice: failed to obtain USB1 mode gpio: %d\n", err);
132 return;
133 }
134
135 platform_device_register(&tegra_ehci1_device);
136}
137
138static void __init tegra_trimslice_fixup(struct machine_desc *desc,
139 struct tag *tags, char **cmdline, struct meminfo *mi)
140{
141 mi->nr_banks = 2;
142 mi->bank[0].start = PHYS_OFFSET;
143 mi->bank[0].size = 448 * SZ_1M;
144 mi->bank[1].start = SZ_512M;
145 mi->bank[1].size = SZ_512M;
146}
147
148static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = {
149 /* name parent rate enabled */
150 { "uarta", "pll_p", 216000000, true },
151 { "pll_a", "pll_p_out1", 56448000, true },
152 { "pll_a_out0", "pll_a", 11289600, true },
153 { "cdev1", NULL, 0, true },
154 { "i2s1", "pll_a_out0", 11289600, false},
155 { NULL, NULL, 0, 0},
156};
157
158static void __init tegra_trimslice_init(void)
159{
160 tegra_clk_init_from_table(trimslice_clk_init_table);
161
162 trimslice_pinmux_init();
163
164 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
165 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
166 tegra_pci_device.dev.platform_data = &trimslice_pci_platform_data;
167
168 platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices));
169
170 trimslice_i2c_init();
171 trimslice_usb_init();
172}
173
174MACHINE_START(TRIMSLICE, "trimslice")
175 .boot_params = 0x00000100,
176 .fixup = tegra_trimslice_fixup,
177 .map_io = tegra_map_common_io,
178 .init_early = tegra_init_early,
179 .init_irq = tegra_init_irq,
180 .timer = &tegra_timer,
181 .init_machine = tegra_trimslice_init,
182MACHINE_END
diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h
new file mode 100644
index 00000000000..7a7dee86b4d
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-tegra/board-trimslice.h
3 *
4 * Copyright (C) 2011 CompuLab, Ltd.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _MACH_TEGRA_BOARD_TRIMSLICE_H
18#define _MACH_TEGRA_BOARD_TRIMSLICE_H
19
20#define TRIMSLICE_GPIO_SD4_CD TEGRA_GPIO_PP1 /* mmc4 cd */
21#define TRIMSLICE_GPIO_SD4_WP TEGRA_GPIO_PP2 /* mmc4 wp */
22
23#define TRIMSLICE_GPIO_USB1_MODE TEGRA_GPIO_PV2 /* USB1 mode */
24#define TRIMSLICE_GPIO_USB2_RST TEGRA_GPIO_PV0 /* USB2 PHY reset */
25
26void trimslice_pinmux_init(void);
27
28#endif
diff --git a/arch/arm/mach-tegra/board-ventana-memory.c b/arch/arm/mach-tegra/board-ventana-memory.c
new file mode 100644
index 00000000000..9ef7c779734
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-memory.c
@@ -0,0 +1,592 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22#include "board-ventana.h"
23#include "tegra2_emc.h"
24#include "board.h"
25
26static const struct tegra_emc_table ventana_emc_tables_elpida_300Mhz[] = {
27 {
28 .rate = 25000, /* SDRAM frquency */
29 .regs = {
30 0x00000002, /* RC */
31 0x00000006, /* RFC */
32 0x00000003, /* RAS */
33 0x00000003, /* RP */
34 0x00000006, /* R2W */
35 0x00000004, /* W2R */
36 0x00000002, /* R2P */
37 0x00000009, /* W2P */
38 0x00000003, /* RD_RCD */
39 0x00000003, /* WR_RCD */
40 0x00000002, /* RRD */
41 0x00000002, /* REXT */
42 0x00000002, /* WDV */
43 0x00000004, /* QUSE */
44 0x00000003, /* QRST */
45 0x00000008, /* QSAFE */
46 0x0000000b, /* RDV */
47 0x0000004d, /* REFRESH */
48 0x00000000, /* BURST_REFRESH_NUM */
49 0x00000003, /* PDEX2WR */
50 0x00000003, /* PDEX2RD */
51 0x00000003, /* PCHG2PDEN */
52 0x00000008, /* ACT2PDEN */
53 0x00000001, /* AR2PDEN */
54 0x0000000a, /* RW2PDEN */
55 0x00000004, /* TXSR */
56 0x00000003, /* TCKE */
57 0x00000008, /* TFAW */
58 0x00000004, /* TRPAB */
59 0x00000006, /* TCLKSTABLE */
60 0x00000002, /* TCLKSTOP */
61 0x00000068, /* TREFBW */
62 0x00000003, /* QUSE_EXTRA */
63 0x00000003, /* FBIO_CFG6 */
64 0x00000000, /* ODT_WRITE */
65 0x00000000, /* ODT_READ */
66 0x00000082, /* FBIO_CFG5 */
67 0xa06a04ae, /* CFG_DIG_DLL */
68 0x0001f000, /* DLL_XFORM_DQS */
69 0x00000000, /* DLL_XFORM_QUSE */
70 0x00000000, /* ZCAL_REF_CNT */
71 0x00000003, /* ZCAL_WAIT_CNT */
72 0x00000000, /* AUTO_CAL_INTERVAL */
73 0x00000000, /* CFG_CLKTRIM_0 */
74 0x00000000, /* CFG_CLKTRIM_1 */
75 0x00000000, /* CFG_CLKTRIM_2 */
76 }
77 },
78 {
79 .rate = 50000, /* SDRAM frequency */
80 .regs = {
81 0x00000003, /* RC */
82 0x00000007, /* RFC */
83 0x00000003, /* RAS */
84 0x00000003, /* RP */
85 0x00000006, /* R2W */
86 0x00000004, /* W2R */
87 0x00000002, /* R2P */
88 0x00000009, /* W2P */
89 0x00000003, /* RD_RCD */
90 0x00000003, /* WR_RCD */
91 0x00000002, /* RRD */
92 0x00000002, /* REXT */
93 0x00000002, /* WDV */
94 0x00000005, /* QUSE */
95 0x00000003, /* QRST */
96 0x00000008, /* QSAFE */
97 0x0000000b, /* RDV */
98 0x0000009f, /* REFRESH */
99 0x00000000, /* BURST_REFRESH_NUM */
100 0x00000003, /* PDEX2WR */
101 0x00000003, /* PDEX2RD */
102 0x00000003, /* PCHG2PDEN */
103 0x00000008, /* ACT2PDEN */
104 0x00000001, /* AR2PDEN */
105 0x0000000a, /* RW2PDEN */
106 0x00000007, /* TXSR */
107 0x00000003, /* TCKE */
108 0x00000008, /* TFAW */
109 0x00000004, /* TRPAB */
110 0x00000006, /* TCLKSTABLE */
111 0x00000002, /* TCLKSTOP */
112 0x000000d0, /* TREFBW */
113 0x00000004, /* QUSE_EXTRA */
114 0x00000000, /* FBIO_CFG6 */
115 0x00000000, /* ODT_WRITE */
116 0x00000000, /* ODT_READ */
117 0x00000082, /* FBIO_CFG5 */
118 0xa06a04ae, /* CFG_DIG_DLL */
119 0x0001f000, /* DLL_XFORM_DQS */
120 0x00000000, /* DLL_XFORM_QUSE */
121 0x00000000, /* ZCAL_REF_CNT */
122 0x00000005, /* ZCAL_WAIT_CNT */
123 0x00000000, /* AUTO_CAL_INTERVAL */
124 0x00000000, /* CFG_CLKTRIM_0 */
125 0x00000000, /* CFG_CLKTRIM_1 */
126 0x00000000, /* CFG_CLKTRIM_2 */
127 }
128 },
129 {
130 .rate = 75000, /* SDRAM frequency */
131 .regs = {
132 0x00000005, /* RC */
133 0x0000000a, /* RFC */
134 0x00000004, /* RAS */
135 0x00000003, /* RP */
136 0x00000006, /* R2W */
137 0x00000004, /* W2R */
138 0x00000002, /* R2P */
139 0x00000009, /* W2P */
140 0x00000003, /* RD_RCD */
141 0x00000003, /* WR_RCD */
142 0x00000002, /* RRD */
143 0x00000002, /* REXT */
144 0x00000002, /* WDV */
145 0x00000005, /* QUSE */
146 0x00000003, /* QRST */
147 0x00000008, /* QSAFE */
148 0x0000000b, /* RDV */
149 0x000000ff, /* REFRESH */
150 0x00000000, /* BURST_REFRESH_NUM */
151 0x00000003, /* PDEX2WR */
152 0x00000003, /* PDEX2RD */
153 0x00000003, /* PCHG2PDEN */
154 0x00000008, /* ACT2PDEN */
155 0x00000001, /* AR2PDEN */
156 0x0000000a, /* RW2PDEN */
157 0x0000000b, /* TXSR */
158 0x00000003, /* TCKE */
159 0x00000008, /* TFAW */
160 0x00000004, /* TRPAB */
161 0x00000006, /* TCLKSTABLE */
162 0x00000002, /* TCLKSTOP */
163 0x00000138, /* TREFBW */
164 0x00000004, /* QUSE_EXTRA */
165 0x00000000, /* FBIO_CFG6 */
166 0x00000000, /* ODT_WRITE */
167 0x00000000, /* ODT_READ */
168 0x00000082, /* FBIO_CFG5 */
169 0xa06a04ae, /* CFG_DIG_DLL */
170 0x0001f000, /* DLL_XFORM_DQS */
171 0x00000000, /* DLL_XFORM_QUSE */
172 0x00000000, /* ZCAL_REF_CNT */
173 0x00000007, /* ZCAL_WAIT_CNT */
174 0x00000000, /* AUTO_CAL_INTERVAL */
175 0x00000000, /* CFG_CLKTRIM_0 */
176 0x00000000, /* CFG_CLKTRIM_1 */
177 0x00000000, /* CFG_CLKTRIM_2 */
178 }
179 },
180 {
181 .rate = 150000, /* SDRAM frequency */
182 .regs = {
183 0x00000009, /* RC */
184 0x00000014, /* RFC */
185 0x00000007, /* RAS */
186 0x00000004, /* RP */
187 0x00000006, /* R2W */
188 0x00000004, /* W2R */
189 0x00000002, /* R2P */
190 0x00000009, /* W2P */
191 0x00000003, /* RD_RCD */
192 0x00000003, /* WR_RCD */
193 0x00000002, /* RRD */
194 0x00000002, /* REXT */
195 0x00000002, /* WDV */
196 0x00000005, /* QUSE */
197 0x00000003, /* QRST */
198 0x00000008, /* QSAFE */
199 0x0000000b, /* RDV */
200 0x0000021f, /* REFRESH */
201 0x00000000, /* BURST_REFRESH_NUM */
202 0x00000003, /* PDEX2WR */
203 0x00000003, /* PDEX2RD */
204 0x00000004, /* PCHG2PDEN */
205 0x00000008, /* ACT2PDEN */
206 0x00000001, /* AR2PDEN */
207 0x0000000a, /* RW2PDEN */
208 0x00000015, /* TXSR */
209 0x00000003, /* TCKE */
210 0x00000008, /* TFAW */
211 0x00000004, /* TRPAB */
212 0x00000006, /* TCLKSTABLE */
213 0x00000002, /* TCLKSTOP */
214 0x00000270, /* TREFBW */
215 0x00000000, /* QUSE_EXTRA */
216 0x00000001, /* FBIO_CFG6 */
217 0x00000000, /* ODT_WRITE */
218 0x00000000, /* ODT_READ */
219 0x00000082, /* FBIO_CFG5 */
220 0xA04C04AE, /* CFG_DIG_DLL */
221 0x007FC010, /* DLL_XFORM_DQS */
222 0x00000000, /* DLL_XFORM_QUSE */
223 0x00000000, /* ZCAL_REF_CNT */
224 0x0000000e, /* ZCAL_WAIT_CNT */
225 0x00000000, /* AUTO_CAL_INTERVAL */
226 0x00000000, /* CFG_CLKTRIM_0 */
227 0x00000000, /* CFG_CLKTRIM_1 */
228 0x00000000, /* CFG_CLKTRIM_2 */
229 }
230 },
231 {
232 .rate = 300000, /* SDRAM frequency */
233 .regs = {
234 0x00000012, /* RC */
235 0x00000027, /* RFC */
236 0x0000000D, /* RAS */
237 0x00000007, /* RP */
238 0x00000007, /* R2W */
239 0x00000005, /* W2R */
240 0x00000003, /* R2P */
241 0x00000009, /* W2P */
242 0x00000006, /* RD_RCD */
243 0x00000006, /* WR_RCD */
244 0x00000003, /* RRD */
245 0x00000003, /* REXT */
246 0x00000002, /* WDV */
247 0x00000006, /* QUSE */
248 0x00000003, /* QRST */
249 0x00000009, /* QSAFE */
250 0x0000000c, /* RDV */
251 0x0000045f, /* REFRESH */
252 0x00000000, /* BURST_REFRESH_NUM */
253 0x00000004, /* PDEX2WR */
254 0x00000004, /* PDEX2RD */
255 0x00000007, /* PCHG2PDEN */
256 0x00000008, /* ACT2PDEN */
257 0x00000001, /* AR2PDEN */
258 0x0000000e, /* RW2PDEN */
259 0x0000002A, /* TXSR */
260 0x00000003, /* TCKE */
261 0x0000000F, /* TFAW */
262 0x00000008, /* TRPAB */
263 0x00000005, /* TCLKSTABLE */
264 0x00000002, /* TCLKSTOP */
265 0x000004E1, /* TREFBW */
266 0x00000005, /* QUSE_EXTRA */
267 0x00000002, /* FBIO_CFG6 */
268 0x00000000, /* ODT_WRITE */
269 0x00000000, /* ODT_READ */
270 0x00000282, /* FBIO_CFG5 */
271 0xE03C048B, /* CFG_DIG_DLL */
272 0x007FC010, /* DLL_XFORM_DQS */
273 0x00000000, /* DLL_XFORM_QUSE */
274 0x00000000, /* ZCAL_REF_CNT */
275 0x0000001B, /* ZCAL_WAIT_CNT */
276 0x00000000, /* AUTO_CAL_INTERVAL */
277 0x00000000, /* CFG_CLKTRIM_0 */
278 0x00000000, /* CFG_CLKTRIM_1 */
279 0x00000000, /* CFG_CLKTRIM_2 */
280 }
281 }
282};
283
284static const struct tegra_emc_table ventana_emc_tables_elpida_400Mhz[] = {
285 {
286 .rate = 23750, /* SDRAM frquency */
287 .regs = {
288 0x00000002, /* RC */
289 0x00000006, /* RFC */
290 0x00000003, /* RAS */
291 0x00000003, /* RP */
292 0x00000006, /* R2W */
293 0x00000004, /* W2R */
294 0x00000002, /* R2P */
295 0x0000000b, /* W2P */
296 0x00000003, /* RD_RCD */
297 0x00000003, /* WR_RCD */
298 0x00000002, /* RRD */
299 0x00000002, /* REXT */
300 0x00000003, /* WDV */
301 0x00000005, /* QUSE */
302 0x00000004, /* QRST */
303 0x00000008, /* QSAFE */
304 0x0000000c, /* RDV */
305 0x00000047, /* REFRESH */
306 0x00000000, /* BURST_REFRESH_NUM */
307 0x00000003, /* PDEX2WR */
308 0x00000003, /* PDEX2RD */
309 0x00000003, /* PCHG2PDEN */
310 0x00000008, /* ACT2PDEN */
311 0x00000001, /* AR2PDEN */
312 0x0000000b, /* RW2PDEN */
313 0x00000004, /* TXSR */
314 0x00000003, /* TCKE */
315 0x00000008, /* TFAW */
316 0x00000004, /* TRPAB */
317 0x00000008, /* TCLKSTABLE */
318 0x00000002, /* TCLKSTOP */
319 0x00000060, /* TREFBW */
320 0x00000004, /* QUSE_EXTRA */
321 0x00000003, /* FBIO_CFG6 */
322 0x00000000, /* ODT_WRITE */
323 0x00000000, /* ODT_READ */
324 0x00000082, /* FBIO_CFG5 */
325 0xa0ae04ae, /* CFG_DIG_DLL */
326 0x0001f800, /* DLL_XFORM_DQS */
327 0x00000000, /* DLL_XFORM_QUSE */
328 0x00000000, /* ZCAL_REF_CNT */
329 0x00000003, /* ZCAL_WAIT_CNT */
330 0x00000000, /* AUTO_CAL_INTERVAL */
331 0x00000000, /* CFG_CLKTRIM_0 */
332 0x00000000, /* CFG_CLKTRIM_1 */
333 0x00000000, /* CFG_CLKTRIM_2 */
334 }
335 },
336 {
337 .rate = 63333, /* SDRAM frquency */
338 .regs = {
339 0x00000004, /* RC */
340 0x00000009, /* RFC */
341 0x00000003, /* RAS */
342 0x00000003, /* RP */
343 0x00000006, /* R2W */
344 0x00000004, /* W2R */
345 0x00000002, /* R2P */
346 0x0000000b, /* W2P */
347 0x00000003, /* RD_RCD */
348 0x00000003, /* WR_RCD */
349 0x00000002, /* RRD */
350 0x00000002, /* REXT */
351 0x00000003, /* WDV */
352 0x00000006, /* QUSE */
353 0x00000004, /* QRST */
354 0x00000008, /* QSAFE */
355 0x0000000c, /* RDV */
356 0x000000c4, /* REFRESH */
357 0x00000000, /* BURST_REFRESH_NUM */
358 0x00000003, /* PDEX2WR */
359 0x00000003, /* PDEX2RD */
360 0x00000003, /* PCHG2PDEN */
361 0x00000008, /* ACT2PDEN */
362 0x00000001, /* AR2PDEN */
363 0x0000000b, /* RW2PDEN */
364 0x00000009, /* TXSR */
365 0x00000003, /* TCKE */
366 0x00000008, /* TFAW */
367 0x00000004, /* TRPAB */
368 0x00000008, /* TCLKSTABLE */
369 0x00000002, /* TCLKSTOP */
370 0x00000107, /* TREFBW */
371 0x00000005, /* QUSE_EXTRA */
372 0x00000000, /* FBIO_CFG6 */
373 0x00000000, /* ODT_WRITE */
374 0x00000000, /* ODT_READ */
375 0x00000082, /* FBIO_CFG5 */
376 0xa0ae04ae, /* CFG_DIG_DLL */
377 0x0001f800, /* DLL_XFORM_DQS */
378 0x00000000, /* DLL_XFORM_QUSE */
379 0x00000000, /* ZCAL_REF_CNT */
380 0x00000006, /* ZCAL_WAIT_CNT */
381 0x00000000, /* AUTO_CAL_INTERVAL */
382 0x00000000, /* CFG_CLKTRIM_0 */
383 0x00000000, /* CFG_CLKTRIM_1 */
384 0x00000000, /* CFG_CLKTRIM_2 */
385 }
386 },
387 {
388 .rate = 95000, /* SDRAM frquency */
389 .regs = {
390 0x00000006, /* RC */
391 0x0000000d, /* RFC */
392 0x00000004, /* RAS */
393 0x00000003, /* RP */
394 0x00000006, /* R2W */
395 0x00000004, /* W2R */
396 0x00000002, /* R2P */
397 0x0000000b, /* W2P */
398 0x00000003, /* RD_RCD */
399 0x00000003, /* WR_RCD */
400 0x00000002, /* RRD */
401 0x00000002, /* REXT */
402 0x00000003, /* WDV */
403 0x00000006, /* QUSE */
404 0x00000004, /* QRST */
405 0x00000008, /* QSAFE */
406 0x0000000c, /* RDV */
407 0x0000013f, /* REFRESH */
408 0x00000000, /* BURST_REFRESH_NUM */
409 0x00000003, /* PDEX2WR */
410 0x00000003, /* PDEX2RD */
411 0x00000003, /* PCHG2PDEN */
412 0x00000008, /* ACT2PDEN */
413 0x00000001, /* AR2PDEN */
414 0x0000000b, /* RW2PDEN */
415 0x0000000e, /* TXSR */
416 0x00000003, /* TCKE */
417 0x00000008, /* TFAW */
418 0x00000004, /* TRPAB */
419 0x00000008, /* TCLKSTABLE */
420 0x00000002, /* TCLKSTOP */
421 0x0000018c, /* TREFBW */
422 0x00000005, /* QUSE_EXTRA */
423 0x00000001, /* FBIO_CFG6 */
424 0x00000000, /* ODT_WRITE */
425 0x00000000, /* ODT_READ */
426 0x00000082, /* FBIO_CFG5 */
427 0xa0ae04ae, /* CFG_DIG_DLL */
428 0x0001f000, /* DLL_XFORM_DQS */
429 0x00000000, /* DLL_XFORM_QUSE */
430 0x00000000, /* ZCAL_REF_CNT */
431 0x00000009, /* ZCAL_WAIT_CNT */
432 0x00000000, /* AUTO_CAL_INTERVAL */
433 0x00000000, /* CFG_CLKTRIM_0 */
434 0x00000000, /* CFG_CLKTRIM_1 */
435 0x00000000, /* CFG_CLKTRIM_2 */
436 }
437 },
438 {
439 .rate = 190000, /* SDRAM frquency */
440 .regs = {
441 0x0000000c, /* RC */
442 0x00000019, /* RFC */
443 0x00000008, /* RAS */
444 0x00000004, /* RP */
445 0x00000007, /* R2W */
446 0x00000004, /* W2R */
447 0x00000002, /* R2P */
448 0x0000000b, /* W2P */
449 0x00000004, /* RD_RCD */
450 0x00000004, /* WR_RCD */
451 0x00000002, /* RRD */
452 0x00000003, /* REXT */
453 0x00000003, /* WDV */
454 0x00000006, /* QUSE */
455 0x00000004, /* QRST */
456 0x00000009, /* QSAFE */
457 0x0000000d, /* RDV */
458 0x000002bf, /* REFRESH */
459 0x00000000, /* BURST_REFRESH_NUM */
460 0x00000003, /* PDEX2WR */
461 0x00000003, /* PDEX2RD */
462 0x00000004, /* PCHG2PDEN */
463 0x00000008, /* ACT2PDEN */
464 0x00000001, /* AR2PDEN */
465 0x0000000c, /* RW2PDEN */
466 0x0000001b, /* TXSR */
467 0x00000003, /* TCKE */
468 0x0000000a, /* TFAW */
469 0x00000004, /* TRPAB */
470 0x00000008, /* TCLKSTABLE */
471 0x00000002, /* TCLKSTOP */
472 0x00000317, /* TREFBW */
473 0x00000005, /* QUSE_EXTRA */
474 0x00000002, /* FBIO_CFG6 */
475 0x00000000, /* ODT_WRITE */
476 0x00000000, /* ODT_READ */
477 0x00000082, /* FBIO_CFG5 */
478 0xa06204ae, /* CFG_DIG_DLL */
479 0x007f7010, /* DLL_XFORM_DQS */
480 0x00000000, /* DLL_XFORM_QUSE */
481 0x00000000, /* ZCAL_REF_CNT */
482 0x00000012, /* ZCAL_WAIT_CNT */
483 0x00000000, /* AUTO_CAL_INTERVAL */
484 0x00000000, /* CFG_CLKTRIM_0 */
485 0x00000000, /* CFG_CLKTRIM_1 */
486 0x00000000, /* CFG_CLKTRIM_2 */
487 }
488 },
489 {
490 .rate = 380000, /* SDRAM frquency */
491 .regs = {
492 0x00000017, /* RC */
493 0x00000032, /* RFC */
494 0x00000010, /* RAS */
495 0x00000007, /* RP */
496 0x00000008, /* R2W */
497 0x00000005, /* W2R */
498 0x00000003, /* R2P */
499 0x0000000b, /* W2P */
500 0x00000007, /* RD_RCD */
501 0x00000007, /* WR_RCD */
502 0x00000004, /* RRD */
503 0x00000003, /* REXT */
504 0x00000003, /* WDV */
505 0x00000007, /* QUSE */
506 0x00000004, /* QRST */
507 0x0000000a, /* QSAFE */
508 0x0000000e, /* RDV */
509 0x0000059f, /* REFRESH */
510 0x00000000, /* BURST_REFRESH_NUM */
511 0x00000004, /* PDEX2WR */
512 0x00000004, /* PDEX2RD */
513 0x00000007, /* PCHG2PDEN */
514 0x00000008, /* ACT2PDEN */
515 0x00000001, /* AR2PDEN */
516 0x00000011, /* RW2PDEN */
517 0x00000036, /* TXSR */
518 0x00000003, /* TCKE */
519 0x00000013, /* TFAW */
520 0x00000008, /* TRPAB */
521 0x00000007, /* TCLKSTABLE */
522 0x00000002, /* TCLKSTOP */
523 0x0000062d, /* TREFBW */
524 0x00000006, /* QUSE_EXTRA */
525 0x00000003, /* FBIO_CFG6 */
526 0x00000000, /* ODT_WRITE */
527 0x00000000, /* ODT_READ */
528 0x00000282, /* FBIO_CFG5 */
529 0xe044048b, /* CFG_DIG_DLL */
530 0x007fb010, /* DLL_XFORM_DQS */
531 0x00000000, /* DLL_XFORM_QUSE */
532 0x00000000, /* ZCAL_REF_CNT */
533 0x00000023, /* ZCAL_WAIT_CNT */
534 0x00000000, /* AUTO_CAL_INTERVAL */
535 0x00000000, /* CFG_CLKTRIM_0 */
536 0x00000000, /* CFG_CLKTRIM_1 */
537 0x00000000, /* CFG_CLKTRIM_2 */
538 }
539 }
540};
541
542static const struct tegra_emc_chip ventana_emc_chips[] = {
543 {
544 .description = "Elpida 300MHz",
545 .mem_manufacturer_id = 0x0303,
546 .mem_revision_id1 = -1,
547 .mem_revision_id2 = -1,
548 .mem_pid = -1,
549 .table = ventana_emc_tables_elpida_300Mhz,
550 .table_size = ARRAY_SIZE(ventana_emc_tables_elpida_300Mhz)
551 },
552};
553
554static const struct tegra_emc_chip ventana_t25_emc_chips[] = {
555 {
556 .description = "Elpida 400MHz",
557 .mem_manufacturer_id = 0x0303,
558 .mem_revision_id1 = -1,
559 .mem_revision_id2 = -1,
560 .mem_pid = -1,
561 .table = ventana_emc_tables_elpida_400Mhz,
562 .table_size = ARRAY_SIZE(ventana_emc_tables_elpida_400Mhz)
563 },
564};
565
566static const struct tegra_emc_chip ventana_siblings_emc_chips[] = {
567};
568
569#define TEGRA25_SKU 0x0B00
570#define board_is_ventana(bi) (bi.board_id == 0x24b || bi.board_id == 0x252)
571
572int ventana_emc_init(void)
573{
574 struct board_info BoardInfo;
575
576 tegra_get_board_info(&BoardInfo);
577
578 if (board_is_ventana(BoardInfo)) {
579 if (BoardInfo.sku == TEGRA25_SKU)
580 tegra_init_emc(ventana_t25_emc_chips,
581 ARRAY_SIZE(ventana_t25_emc_chips));
582 else
583 tegra_init_emc(ventana_emc_chips,
584 ARRAY_SIZE(ventana_emc_chips));
585 } else {
586 pr_info("ventana_emc_init: using ventana_siblings_emc_chips\n");
587 tegra_init_emc(ventana_siblings_emc_chips,
588 ARRAY_SIZE(ventana_siblings_emc_chips));
589 }
590
591 return 0;
592}
diff --git a/arch/arm/mach-tegra/board-ventana-panel.c b/arch/arm/mach-tegra/board-ventana-panel.c
new file mode 100644
index 00000000000..4cacd3dc421
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-panel.c
@@ -0,0 +1,457 @@
1/*
2 * arch/arm/mach-tegra/board-ventana-panel.c
3 *
4 * Copyright (c) 2010-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/resource.h>
25#include <asm/mach-types.h>
26#include <linux/platform_device.h>
27#include <linux/earlysuspend.h>
28#include <linux/pwm_backlight.h>
29#include <linux/nvhost.h>
30#include <mach/nvmap.h>
31#include <mach/irqs.h>
32#include <mach/iomap.h>
33#include <mach/dc.h>
34#include <mach/fb.h>
35
36#include "devices.h"
37#include "gpio-names.h"
38#include "board.h"
39
40#define ventana_bl_enb TEGRA_GPIO_PD4
41#define ventana_lvds_shutdown TEGRA_GPIO_PB2
42#define ventana_hdmi_hpd TEGRA_GPIO_PN7
43#define ventana_hdmi_enb TEGRA_GPIO_PV5
44
45/*panel power on sequence timing*/
46#define ventana_pnl_to_lvds_ms 0
47#define ventana_lvds_to_bl_ms 200
48
49static struct regulator *pnl_pwr;
50
51#ifdef CONFIG_TEGRA_DC
52static struct regulator *ventana_hdmi_reg = NULL;
53static struct regulator *ventana_hdmi_pll = NULL;
54#endif
55
56static int ventana_backlight_init(struct device *dev) {
57 int ret;
58
59 ret = gpio_request(ventana_bl_enb, "backlight_enb");
60 if (ret < 0)
61 return ret;
62
63 ret = gpio_direction_output(ventana_bl_enb, 1);
64 if (ret < 0)
65 gpio_free(ventana_bl_enb);
66 else
67 tegra_gpio_enable(ventana_bl_enb);
68
69 return ret;
70};
71
72static void ventana_backlight_exit(struct device *dev) {
73 gpio_set_value(ventana_bl_enb, 0);
74 gpio_free(ventana_bl_enb);
75 tegra_gpio_disable(ventana_bl_enb);
76}
77
78static int ventana_backlight_notify(struct device *unused, int brightness)
79{
80 gpio_set_value(ventana_bl_enb, !!brightness);
81 return brightness;
82}
83
84static int ventana_disp1_check_fb(struct device *dev, struct fb_info *info);
85
86static struct platform_pwm_backlight_data ventana_backlight_data = {
87 .pwm_id = 2,
88 .max_brightness = 255,
89 .dft_brightness = 224,
90 .pwm_period_ns = 5000000,
91 .init = ventana_backlight_init,
92 .exit = ventana_backlight_exit,
93 .notify = ventana_backlight_notify,
94 /* Only toggle backlight on fb blank notifications for disp1 */
95 .check_fb = ventana_disp1_check_fb,
96};
97
98static struct platform_device ventana_backlight_device = {
99 .name = "pwm-backlight",
100 .id = -1,
101 .dev = {
102 .platform_data = &ventana_backlight_data,
103 },
104};
105
106#ifdef CONFIG_TEGRA_DC
107static int ventana_panel_enable(void)
108{
109 struct regulator *reg = regulator_get(NULL, "vdd_ldo4");
110
111 if (!reg) {
112 regulator_enable(reg);
113 regulator_put(reg);
114 }
115
116 if (pnl_pwr == NULL) {
117 pnl_pwr = regulator_get(NULL, "pnl_pwr");
118 if (WARN_ON(IS_ERR(pnl_pwr)))
119 pr_err("%s: couldn't get regulator pnl_pwr: %ld\n",
120 __func__, PTR_ERR(pnl_pwr));
121 else
122 regulator_enable(pnl_pwr);
123 } else {
124 regulator_enable(pnl_pwr);
125 }
126
127 mdelay(ventana_pnl_to_lvds_ms);
128 gpio_set_value(ventana_lvds_shutdown, 1);
129 mdelay(ventana_lvds_to_bl_ms);
130 return 0;
131}
132
133static int ventana_panel_disable(void)
134{
135 gpio_set_value(ventana_lvds_shutdown, 0);
136 regulator_disable(pnl_pwr);
137 return 0;
138}
139
140static int ventana_hdmi_enable(void)
141{
142 if (!ventana_hdmi_reg) {
143 ventana_hdmi_reg = regulator_get(NULL, "avdd_hdmi"); /* LD07 */
144 if (IS_ERR_OR_NULL(ventana_hdmi_reg)) {
145 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
146 ventana_hdmi_reg = NULL;
147 return PTR_ERR(ventana_hdmi_reg);
148 }
149 }
150 regulator_enable(ventana_hdmi_reg);
151
152 if (!ventana_hdmi_pll) {
153 ventana_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll"); /* LD08 */
154 if (IS_ERR_OR_NULL(ventana_hdmi_pll)) {
155 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
156 ventana_hdmi_pll = NULL;
157 regulator_disable(ventana_hdmi_reg);
158 ventana_hdmi_reg = NULL;
159 return PTR_ERR(ventana_hdmi_pll);
160 }
161 }
162 regulator_enable(ventana_hdmi_pll);
163 return 0;
164}
165
166static int ventana_hdmi_disable(void)
167{
168 regulator_disable(ventana_hdmi_reg);
169 regulator_disable(ventana_hdmi_pll);
170 return 0;
171}
172
173static struct resource ventana_disp1_resources[] = {
174 {
175 .name = "irq",
176 .start = INT_DISPLAY_GENERAL,
177 .end = INT_DISPLAY_GENERAL,
178 .flags = IORESOURCE_IRQ,
179 },
180 {
181 .name = "regs",
182 .start = TEGRA_DISPLAY_BASE,
183 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
184 .flags = IORESOURCE_MEM,
185 },
186 {
187 .name = "fbmem",
188 .flags = IORESOURCE_MEM,
189 },
190};
191
192static struct resource ventana_disp2_resources[] = {
193 {
194 .name = "irq",
195 .start = INT_DISPLAY_B_GENERAL,
196 .end = INT_DISPLAY_B_GENERAL,
197 .flags = IORESOURCE_IRQ,
198 },
199 {
200 .name = "regs",
201 .start = TEGRA_DISPLAY2_BASE,
202 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
203 .flags = IORESOURCE_MEM,
204 },
205 {
206 .name = "fbmem",
207 .flags = IORESOURCE_MEM,
208 },
209 {
210 .name = "hdmi_regs",
211 .start = TEGRA_HDMI_BASE,
212 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
213 .flags = IORESOURCE_MEM,
214 },
215};
216
217static struct tegra_dc_mode ventana_panel_modes[] = {
218 {
219 .pclk = 72072000,
220 .h_ref_to_sync = 11,
221 .v_ref_to_sync = 1,
222 .h_sync_width = 58,
223 .v_sync_width = 4,
224 .h_back_porch = 58,
225 .v_back_porch = 4,
226 .h_active = 1366,
227 .v_active = 768,
228 .h_front_porch = 58,
229 .v_front_porch = 4,
230 },
231};
232
233static struct tegra_fb_data ventana_fb_data = {
234 .win = 0,
235 .xres = 1366,
236 .yres = 768,
237 .bits_per_pixel = 32,
238 .flags = TEGRA_FB_FLIP_ON_PROBE,
239};
240
241static struct tegra_fb_data ventana_hdmi_fb_data = {
242 .win = 0,
243 .xres = 1366,
244 .yres = 768,
245 .bits_per_pixel = 32,
246 .flags = TEGRA_FB_FLIP_ON_PROBE,
247};
248
249static struct tegra_dc_out ventana_disp1_out = {
250 .type = TEGRA_DC_OUT_RGB,
251
252 .align = TEGRA_DC_ALIGN_MSB,
253 .order = TEGRA_DC_ORDER_RED_BLUE,
254 .depth = 18,
255 .dither = TEGRA_DC_ORDERED_DITHER,
256
257 .modes = ventana_panel_modes,
258 .n_modes = ARRAY_SIZE(ventana_panel_modes),
259
260 .enable = ventana_panel_enable,
261 .disable = ventana_panel_disable,
262};
263
264static struct tegra_dc_out ventana_disp2_out = {
265 .type = TEGRA_DC_OUT_HDMI,
266 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
267
268 .dcc_bus = 1,
269 .hotplug_gpio = ventana_hdmi_hpd,
270
271 .max_pixclock = KHZ2PICOS(148500),
272
273 .align = TEGRA_DC_ALIGN_MSB,
274 .order = TEGRA_DC_ORDER_RED_BLUE,
275
276 .enable = ventana_hdmi_enable,
277 .disable = ventana_hdmi_disable,
278};
279
280static struct tegra_dc_platform_data ventana_disp1_pdata = {
281 .flags = TEGRA_DC_FLAG_ENABLED,
282 .default_out = &ventana_disp1_out,
283 .fb = &ventana_fb_data,
284};
285
286static struct tegra_dc_platform_data ventana_disp2_pdata = {
287 .flags = 0,
288 .default_out = &ventana_disp2_out,
289 .fb = &ventana_hdmi_fb_data,
290};
291
292static struct nvhost_device ventana_disp1_device = {
293 .name = "tegradc",
294 .id = 0,
295 .resource = ventana_disp1_resources,
296 .num_resources = ARRAY_SIZE(ventana_disp1_resources),
297 .dev = {
298 .platform_data = &ventana_disp1_pdata,
299 },
300};
301
302static int ventana_disp1_check_fb(struct device *dev, struct fb_info *info)
303{
304 return info->device == &ventana_disp1_device.dev;
305}
306
307static struct nvhost_device ventana_disp2_device = {
308 .name = "tegradc",
309 .id = 1,
310 .resource = ventana_disp2_resources,
311 .num_resources = ARRAY_SIZE(ventana_disp2_resources),
312 .dev = {
313 .platform_data = &ventana_disp2_pdata,
314 },
315};
316#else
317static int ventana_disp1_check_fb(struct device *dev, struct fb_info *info)
318{
319 return 0;
320}
321#endif
322
323#if defined(CONFIG_TEGRA_NVMAP)
324static struct nvmap_platform_carveout ventana_carveouts[] = {
325 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
326 [1] = {
327 .name = "generic-0",
328 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
329 .buddy_size = SZ_32K,
330 },
331};
332
333static struct nvmap_platform_data ventana_nvmap_data = {
334 .carveouts = ventana_carveouts,
335 .nr_carveouts = ARRAY_SIZE(ventana_carveouts),
336};
337
338static struct platform_device ventana_nvmap_device = {
339 .name = "tegra-nvmap",
340 .id = -1,
341 .dev = {
342 .platform_data = &ventana_nvmap_data,
343 },
344};
345#endif
346
347static struct platform_device *ventana_gfx_devices[] __initdata = {
348#if defined(CONFIG_TEGRA_NVMAP)
349 &ventana_nvmap_device,
350#endif
351 &tegra_pwfm2_device,
352 &ventana_backlight_device,
353};
354
355#ifdef CONFIG_HAS_EARLYSUSPEND
356/* put early_suspend/late_resume handlers here for the display in order
357 * to keep the code out of the display driver, keeping it closer to upstream
358 */
359struct early_suspend ventana_panel_early_suspender;
360
361static void ventana_panel_early_suspend(struct early_suspend *h)
362{
363 /* power down LCD, add use a black screen for HDMI */
364 if (num_registered_fb > 0)
365 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
366 if (num_registered_fb > 1)
367 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
368#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
369 cpufreq_save_default_governor();
370 cpufreq_set_conservative_governor();
371 cpufreq_set_conservative_governor_param("up_threshold",
372 SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
373
374 cpufreq_set_conservative_governor_param("down_threshold",
375 SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
376
377 cpufreq_set_conservative_governor_param("freq_step",
378 SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
379#endif
380}
381
382static void ventana_panel_late_resume(struct early_suspend *h)
383{
384 unsigned i;
385#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
386 cpufreq_restore_default_governor();
387#endif
388 for (i = 0; i < num_registered_fb; i++)
389 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
390}
391#endif
392
393int __init ventana_panel_init(void)
394{
395 int err;
396 struct resource __maybe_unused *res;
397
398 gpio_request(ventana_lvds_shutdown, "lvds_shdn");
399 gpio_direction_output(ventana_lvds_shutdown, 1);
400 tegra_gpio_enable(ventana_lvds_shutdown);
401
402 tegra_gpio_enable(ventana_hdmi_enb);
403 gpio_request(ventana_hdmi_enb, "hdmi_5v_en");
404 gpio_direction_output(ventana_hdmi_enb, 1);
405
406 tegra_gpio_enable(ventana_hdmi_hpd);
407 gpio_request(ventana_hdmi_hpd, "hdmi_hpd");
408 gpio_direction_input(ventana_hdmi_hpd);
409
410#ifdef CONFIG_HAS_EARLYSUSPEND
411 ventana_panel_early_suspender.suspend = ventana_panel_early_suspend;
412 ventana_panel_early_suspender.resume = ventana_panel_late_resume;
413 ventana_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
414 register_early_suspend(&ventana_panel_early_suspender);
415#endif
416
417#if defined(CONFIG_TEGRA_NVMAP)
418 ventana_carveouts[1].base = tegra_carveout_start;
419 ventana_carveouts[1].size = tegra_carveout_size;
420#endif
421
422#ifdef CONFIG_TEGRA_GRHOST
423 err = nvhost_device_register(&tegra_grhost_device);
424 if (err)
425 return err;
426#endif
427
428 err = platform_add_devices(ventana_gfx_devices,
429 ARRAY_SIZE(ventana_gfx_devices));
430
431#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
432 res = nvhost_get_resource_byname(&ventana_disp1_device,
433 IORESOURCE_MEM, "fbmem");
434 res->start = tegra_fb_start;
435 res->end = tegra_fb_start + tegra_fb_size - 1;
436
437 res = nvhost_get_resource_byname(&ventana_disp2_device,
438 IORESOURCE_MEM, "fbmem");
439 res->start = tegra_fb2_start;
440 res->end = tegra_fb2_start + tegra_fb2_size - 1;
441#endif
442
443 /* Copy the bootloader fb to the fb. */
444 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
445 min(tegra_fb_size, tegra_bootloader_fb_size));
446
447#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
448 if (!err)
449 err = nvhost_device_register(&ventana_disp1_device);
450
451 if (!err)
452 err = nvhost_device_register(&ventana_disp2_device);
453#endif
454
455 return err;
456}
457
diff --git a/arch/arm/mach-tegra/board-ventana-pinmux.c b/arch/arm/mach-tegra/board-ventana-pinmux.c
new file mode 100644
index 00000000000..9f344726459
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-pinmux.c
@@ -0,0 +1,194 @@
1/*
2 * arch/arm/mach-tegra/board-ventana-pinmux.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation
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/gpio.h>
20#include <mach/pinmux.h>
21
22#include "board-ventana.h"
23#include "gpio-names.h"
24
25#define DEFAULT_DRIVE(_name) \
26 { \
27 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
28 .hsm = TEGRA_HSM_DISABLE, \
29 .schmitt = TEGRA_SCHMITT_ENABLE, \
30 .drive = TEGRA_DRIVE_DIV_1, \
31 .pull_down = TEGRA_PULL_31, \
32 .pull_up = TEGRA_PULL_31, \
33 .slew_rising = TEGRA_SLEW_SLOWEST, \
34 .slew_falling = TEGRA_SLEW_SLOWEST, \
35 }
36
37#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
38 { \
39 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
40 .hsm = TEGRA_HSM_##_hsm, \
41 .schmitt = TEGRA_SCHMITT_##_schmitt, \
42 .drive = TEGRA_DRIVE_##_drive, \
43 .pull_down = TEGRA_PULL_##_pulldn_drive, \
44 .pull_up = TEGRA_PULL_##_pullup_drive, \
45 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
46 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
47 }
48
49static __initdata struct tegra_drive_pingroup_config ventana_drive_pinmux[] = {
50 DEFAULT_DRIVE(DDC),
51 DEFAULT_DRIVE(VI1),
52 DEFAULT_DRIVE(SDIO1),
53
54 SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
55 SET_DRIVE(VI2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
56 SET_DRIVE(AT1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
57 SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
58};
59
60static __initdata struct tegra_pingroup_config ventana_pinmux[] = {
61 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
64 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
66 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
69 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
72 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
73 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
83 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
90 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
92 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
99 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
100 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
108 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
113 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
114 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
116 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
118 {TEGRA_PINGROUP_LDC, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
121 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
122 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
125 {TEGRA_PINGROUP_LM1, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
126 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
130 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
131 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
133 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
134 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
135 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
137 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
140 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
141 {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
142 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
143 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
144 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
145 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
146 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
147 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
148 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
149 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
150 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
151 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
152 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
153 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
154 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
155 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
156 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
157 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
158 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
159 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
160 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
161 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
162 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
163 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
164 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
165 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
166 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
167 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
168 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
169 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
170 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
171 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
172 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
173 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
174 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
175 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
176 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
177};
178
179static struct tegra_gpio_table gpio_table[] = {
180 { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
181 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
182 { .gpio = TEGRA_GPIO_INT_MIC_EN, .enable = true },
183 { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true },
184};
185
186int __init ventana_pinmux_init(void)
187{
188 tegra_pinmux_config_table(ventana_pinmux, ARRAY_SIZE(ventana_pinmux));
189 tegra_drive_pinmux_config_table(ventana_drive_pinmux,
190 ARRAY_SIZE(ventana_drive_pinmux));
191
192 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
193 return 0;
194}
diff --git a/arch/arm/mach-tegra/board-ventana-power.c b/arch/arm/mach-tegra/board-ventana-power.c
new file mode 100644
index 00000000000..e36a4e7c279
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-power.c
@@ -0,0 +1,373 @@
1/*
2 * Copyright (C) 2010-2012 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/pda_power.h>
20#include <linux/platform_device.h>
21#include <linux/resource.h>
22#include <linux/regulator/machine.h>
23#include <linux/mfd/tps6586x.h>
24#include <linux/gpio.h>
25#include <linux/io.h>
26#include <linux/power/gpio-charger.h>
27#include <linux/regulator/fixed.h>
28
29#include <mach/iomap.h>
30#include <mach/irqs.h>
31
32#include <generated/mach-types.h>
33
34#include "gpio-names.h"
35#include "fuse.h"
36#include "pm.h"
37#include "wakeups-t2.h"
38#include "board.h"
39#include "board-ventana.h"
40
41#define PMC_CTRL 0x0
42#define PMC_CTRL_INTR_LOW (1 << 17)
43
44#define CHARGING_DISABLE TEGRA_GPIO_PR6
45
46int __init ventana_charge_init(void)
47{
48 gpio_request(CHARGING_DISABLE, "chg_disable");
49 gpio_direction_output(CHARGING_DISABLE, 0);
50 tegra_gpio_enable(CHARGING_DISABLE);
51 return 0;
52}
53
54static struct regulator_consumer_supply tps658621_sm0_supply[] = {
55 REGULATOR_SUPPLY("vdd_core", NULL),
56};
57static struct regulator_consumer_supply tps658621_sm1_supply[] = {
58 REGULATOR_SUPPLY("vdd_cpu", NULL),
59};
60static struct regulator_consumer_supply tps658621_sm2_supply[] = {
61 REGULATOR_SUPPLY("vdd_sm2", NULL),
62};
63static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
64 REGULATOR_SUPPLY("vdd_ldo0", NULL),
65 REGULATOR_SUPPLY("p_cam_avdd", NULL),
66};
67static struct regulator_consumer_supply tps658621_ldo1_supply[] = {
68 REGULATOR_SUPPLY("vdd_ldo1", NULL),
69 REGULATOR_SUPPLY("avdd_pll", NULL),
70};
71static struct regulator_consumer_supply tps658621_ldo2_supply[] = {
72 REGULATOR_SUPPLY("vdd_ldo2", NULL),
73 REGULATOR_SUPPLY("vdd_rtc", NULL),
74 REGULATOR_SUPPLY("vdd_aon", NULL),
75};
76static struct regulator_consumer_supply tps658621_ldo3_supply[] = {
77 REGULATOR_SUPPLY("vdd_ldo3", NULL),
78 REGULATOR_SUPPLY("avdd_usb", NULL),
79 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
80};
81static struct regulator_consumer_supply tps658621_ldo4_supply[] = {
82 REGULATOR_SUPPLY("vdd_ldo4", NULL),
83 REGULATOR_SUPPLY("avdd_osc", NULL),
84 REGULATOR_SUPPLY("vddio_sys", "panjit_touch"),
85};
86static struct regulator_consumer_supply tps658621_ldo5_supply[] = {
87 REGULATOR_SUPPLY("vdd_ldo5", NULL),
88 REGULATOR_SUPPLY("vmmc", "sdhci-tegra.3"),
89};
90static struct regulator_consumer_supply tps658621_ldo6_supply[] = {
91 REGULATOR_SUPPLY("vdd_ldo6", NULL),
92 REGULATOR_SUPPLY("vcsi", "tegra_camera"),
93 REGULATOR_SUPPLY("vdd_dmic", "tegra-snd-wm8903.0"),
94 REGULATOR_SUPPLY("vdd_i2c", "3-0030"),
95 REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
96 REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
97};
98static struct regulator_consumer_supply tps658621_ldo7_supply[] = {
99 REGULATOR_SUPPLY("vdd_ldo7", NULL),
100 REGULATOR_SUPPLY("avdd_hdmi", NULL),
101 REGULATOR_SUPPLY("vdd_fuse", NULL),
102};
103static struct regulator_consumer_supply tps658621_ldo8_supply[] = {
104 REGULATOR_SUPPLY("vdd_ldo8", NULL),
105 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
106};
107static struct regulator_consumer_supply tps658621_ldo9_supply[] = {
108 REGULATOR_SUPPLY("vdd_ldo9", NULL),
109 REGULATOR_SUPPLY("avdd_2v85", NULL),
110 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
111 REGULATOR_SUPPLY("vdd_spk_amp", "tegra-snd-wm8903.0"),
112};
113
114static struct tps6586x_settings sm0_config = {
115 .sm_pwm_mode = PWM_DEFAULT_VALUE,
116 .slew_rate = SLEW_RATE_3520UV_PER_SEC,
117};
118
119static struct tps6586x_settings sm1_config = {
120 /*
121 * Current TPS6586x is known for having a voltage glitch if current load
122 * changes from low to high in auto PWM/PFM mode for CPU's Vdd line.
123 */
124 .sm_pwm_mode = PWM_ONLY,
125 .slew_rate = SLEW_RATE_3520UV_PER_SEC,
126};
127
128#define REGULATOR_INIT(_id, _minmv, _maxmv, on, config) \
129 { \
130 .constraints = { \
131 .min_uV = (_minmv)*1000, \
132 .max_uV = (_maxmv)*1000, \
133 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
134 REGULATOR_MODE_STANDBY), \
135 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
136 REGULATOR_CHANGE_STATUS | \
137 REGULATOR_CHANGE_VOLTAGE), \
138 .always_on = on, \
139 .apply_uV = 1, \
140 }, \
141 .num_consumer_supplies = ARRAY_SIZE(tps658621_##_id##_supply),\
142 .consumer_supplies = tps658621_##_id##_supply, \
143 .driver_data = config, \
144 }
145
146#define ON 1
147#define OFF 0
148
149static struct regulator_init_data sm0_data = REGULATOR_INIT(sm0, 725, 1500, ON, &sm0_config);
150static struct regulator_init_data sm1_data = REGULATOR_INIT(sm1, 725, 1500, ON, &sm1_config);
151static struct regulator_init_data sm2_data = REGULATOR_INIT(sm2, 3000, 4550, ON, NULL);
152static struct regulator_init_data ldo0_data = REGULATOR_INIT(ldo0, 1250, 3300, OFF, NULL);
153static struct regulator_init_data ldo1_data = REGULATOR_INIT(ldo1, 725, 1500, ON, NULL);
154static struct regulator_init_data ldo2_data = REGULATOR_INIT(ldo2, 725, 1500, OFF, NULL);
155static struct regulator_init_data ldo3_data = REGULATOR_INIT(ldo3, 1250, 3300, OFF, NULL);
156static struct regulator_init_data ldo4_data = REGULATOR_INIT(ldo4, 1700, 2475, ON, NULL);
157static struct regulator_init_data ldo5_data = REGULATOR_INIT(ldo5, 1250, 3300, ON, NULL);
158static struct regulator_init_data ldo6_data = REGULATOR_INIT(ldo6, 1800, 1800, OFF, NULL);
159static struct regulator_init_data ldo7_data = REGULATOR_INIT(ldo7, 1250, 3300, OFF, NULL);
160static struct regulator_init_data ldo8_data = REGULATOR_INIT(ldo8, 1250, 3300, OFF, NULL);
161static struct regulator_init_data ldo9_data = REGULATOR_INIT(ldo9, 1250, 3300, ON, NULL);
162
163static struct tps6586x_rtc_platform_data rtc_data = {
164 .irq = TEGRA_NR_IRQS + TPS6586X_INT_RTC_ALM1,
165 .start = {
166 .year = 2009,
167 .month = 1,
168 .day = 1,
169 },
170 .cl_sel = TPS6586X_RTC_CL_SEL_1_5PF /* use lowest (external 20pF cap) */
171};
172
173#define TPS_REG(_id, _data) \
174 { \
175 .id = TPS6586X_ID_##_id, \
176 .name = "tps6586x-regulator", \
177 .platform_data = _data, \
178 }
179
180static struct tps6586x_subdev_info tps_devs[] = {
181 TPS_REG(SM_0, &sm0_data),
182 TPS_REG(SM_1, &sm1_data),
183 TPS_REG(SM_2, &sm2_data),
184 TPS_REG(LDO_0, &ldo0_data),
185 TPS_REG(LDO_1, &ldo1_data),
186 TPS_REG(LDO_2, &ldo2_data),
187 TPS_REG(LDO_3, &ldo3_data),
188 TPS_REG(LDO_4, &ldo4_data),
189 TPS_REG(LDO_5, &ldo5_data),
190 TPS_REG(LDO_6, &ldo6_data),
191 TPS_REG(LDO_7, &ldo7_data),
192 TPS_REG(LDO_8, &ldo8_data),
193 TPS_REG(LDO_9, &ldo9_data),
194 {
195 .id = 0,
196 .name = "tps6586x-rtc",
197 .platform_data = &rtc_data,
198 },
199};
200
201static struct tps6586x_platform_data tps_platform = {
202 .irq_base = TPS6586X_INT_BASE,
203 .num_subdevs = ARRAY_SIZE(tps_devs),
204 .subdevs = tps_devs,
205 .gpio_base = TPS6586X_GPIO_BASE,
206 .use_power_off = true,
207};
208
209static struct i2c_board_info __initdata ventana_regulators[] = {
210 {
211 I2C_BOARD_INFO("tps6586x", 0x34),
212 .irq = INT_EXTERNAL_PMU,
213 .platform_data = &tps_platform,
214 },
215};
216
217static void ventana_board_suspend(int lp_state, enum suspend_stage stg)
218{
219 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
220 tegra_console_uart_suspend();
221}
222
223static void ventana_board_resume(int lp_state, enum resume_stage stg)
224{
225 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
226 tegra_console_uart_resume();
227}
228
229static struct tegra_suspend_platform_data ventana_suspend_data = {
230 /*
231 * Check power on time and crystal oscillator start time
232 * for appropriate settings.
233 */
234 .cpu_timer = 2000,
235 .cpu_off_timer = 100,
236 .suspend_mode = TEGRA_SUSPEND_LP0,
237 .core_timer = 0x7e7e,
238 .core_off_timer = 0xf,
239 .corereq_high = false,
240 .sysclkreq_high = true,
241 .board_suspend = ventana_board_suspend,
242 .board_resume = ventana_board_resume,
243};
244
245static struct regulator_consumer_supply pnl_pwr_consumer_supply[] = {
246 REGULATOR_SUPPLY("pnl_pwr", NULL),
247};
248
249FIXED_VOLTAGE_REG_INIT(2, pnl_pwr, 2800000, PANEL_POWER_EN_GPIO,
250 0, 1, 0, REGULATOR_CHANGE_STATUS, 0);
251
252static struct platform_device *fixed_voltage_regulators[] __initdata = {
253 ADD_FIXED_VOLTAGE_REG(pnl_pwr),
254};
255
256int __init ventana_fixed_voltage_regulator_init(void)
257{
258 int i;
259
260 for (i = 0; i < ARRAY_SIZE(fixed_voltage_regulators); ++i) {
261 struct fixed_voltage_config *fixed_voltage_regulators_pdata =
262 fixed_voltage_regulators[i]->dev.platform_data;
263 if (fixed_voltage_regulators_pdata->gpio < TEGRA_NR_GPIOS)
264 tegra_gpio_enable(fixed_voltage_regulators_pdata->gpio);
265 }
266 return platform_add_devices(fixed_voltage_regulators,
267 ARRAY_SIZE(fixed_voltage_regulators));
268}
269
270int __init ventana_regulator_init(void)
271{
272 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
273 void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
274 u32 pmc_ctrl;
275 u32 minor;
276
277 minor = (readl(chip_id) >> 16) & 0xf;
278 /* A03 (but not A03p) chips do not support LP0 */
279 if (minor == 3 && !(tegra_spare_fuse(18) || tegra_spare_fuse(19)))
280 ventana_suspend_data.suspend_mode = TEGRA_SUSPEND_LP1;
281
282 /* configure the power management controller to trigger PMU
283 * interrupts when low */
284 pmc_ctrl = readl(pmc + PMC_CTRL);
285 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
286
287 i2c_register_board_info(4, ventana_regulators, 1);
288
289// regulator_has_full_constraints();
290
291 tegra_init_suspend(&ventana_suspend_data);
292
293 ventana_fixed_voltage_regulator_init();
294
295 return 0;
296}
297
298static char *ventana_battery[] = {
299 "battery",
300};
301
302static struct gpio_charger_platform_data ventana_charger_pdata = {
303 .name = "ac",
304 .type = POWER_SUPPLY_TYPE_MAINS,
305 .gpio = AC_PRESENT_GPIO,
306 .gpio_active_low = 1,
307 .supplied_to = ventana_battery,
308 .num_supplicants = ARRAY_SIZE(ventana_battery),
309};
310
311static struct platform_device ventana_charger_device = {
312 .name = "gpio-charger",
313 .dev = {
314 .platform_data = &ventana_charger_pdata,
315 },
316};
317
318int __init ventana_charger_init(void)
319{
320 tegra_gpio_enable(AC_PRESENT_GPIO);
321 platform_device_register(&ventana_charger_device);
322 return 0;
323}
324
325static int __init ventana_pcie_init(void)
326{
327 int ret;
328
329 if (!machine_is_ventana())
330 return 0;
331
332 ret = gpio_request(TPS6586X_GPIO_BASE, "pcie_vdd");
333 if (ret < 0)
334 goto fail;
335
336 ret = gpio_direction_output(TPS6586X_GPIO_BASE, 1);
337 if (ret < 0)
338 goto fail;
339
340 gpio_export(TPS6586X_GPIO_BASE, false);
341 return 0;
342
343fail:
344 pr_err("%s: gpio_request failed #%d\n", __func__, TPS6586X_GPIO_BASE);
345 gpio_free(TPS6586X_GPIO_BASE);
346 return ret;
347}
348
349static struct regulator_consumer_supply cam1_2v8_consumer_supply[] = {
350 REGULATOR_SUPPLY("cam1_2v8", NULL),
351};
352
353static struct regulator_consumer_supply cam2_2v8_consumer_supply[] = {
354 REGULATOR_SUPPLY("cam2_2v8", NULL),
355};
356
357FIXED_VOLTAGE_REG_INIT(0, cam1_2v8, 2800000, CAM1_LDO_SHUTDN_L_GPIO,
358 0, 1, 0, REGULATOR_CHANGE_STATUS, 0);
359FIXED_VOLTAGE_REG_INIT(1, cam2_2v8, 2800000, CAM2_LDO_SHUTDN_L_GPIO,
360 0, 1, 0, REGULATOR_CHANGE_STATUS, 0);
361
362static struct platform_device *cam_fixed_voltage_regulators[] __initdata = {
363 ADD_FIXED_VOLTAGE_REG(cam1_2v8),
364 ADD_FIXED_VOLTAGE_REG(cam2_2v8),
365};
366
367int __init ventana_cam_fixed_voltage_regulator_init(void)
368{
369 return platform_add_devices(cam_fixed_voltage_regulators,
370 ARRAY_SIZE(cam_fixed_voltage_regulators));
371}
372
373late_initcall(ventana_pcie_init);
diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c
new file mode 100644
index 00000000000..49720cd7a6d
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-sdhci.c
@@ -0,0 +1,267 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-sdhci.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/resource.h>
18#include <linux/platform_device.h>
19#include <linux/wlan_plat.h>
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/mmc/host.h>
25
26#include <asm/mach-types.h>
27#include <mach/irqs.h>
28#include <mach/iomap.h>
29#include <mach/sdhci.h>
30
31#include "gpio-names.h"
32#include "board.h"
33
34#define VENTANA_WLAN_PWR TEGRA_GPIO_PK5
35#define VENTANA_WLAN_RST TEGRA_GPIO_PK6
36#define VENTANA_WLAN_WOW TEGRA_GPIO_PS0
37
38static void (*wifi_status_cb)(int card_present, void *dev_id);
39static void *wifi_status_cb_devid;
40static int ventana_wifi_status_register(void (*callback)(int , void *), void *);
41static struct clk *wifi_32k_clk;
42
43static int ventana_wifi_reset(int on);
44static int ventana_wifi_power(int on);
45static int ventana_wifi_set_carddetect(int val);
46
47static struct wifi_platform_data ventana_wifi_control = {
48 .set_power = ventana_wifi_power,
49 .set_reset = ventana_wifi_reset,
50 .set_carddetect = ventana_wifi_set_carddetect,
51};
52
53static struct resource wifi_resource[] = {
54 [0] = {
55 .name = "bcm4329_wlan_irq",
56 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0),
57 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0),
58 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
59 },
60};
61
62static struct platform_device ventana_wifi_device = {
63 .name = "bcm4329_wlan",
64 .id = 1,
65 .num_resources = 1,
66 .resource = wifi_resource,
67 .dev = {
68 .platform_data = &ventana_wifi_control,
69 },
70};
71
72static struct resource sdhci_resource0[] = {
73 [0] = {
74 .start = INT_SDMMC1,
75 .end = INT_SDMMC1,
76 .flags = IORESOURCE_IRQ,
77 },
78 [1] = {
79 .start = TEGRA_SDMMC1_BASE,
80 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
81 .flags = IORESOURCE_MEM,
82 },
83};
84
85static struct resource sdhci_resource2[] = {
86 [0] = {
87 .start = INT_SDMMC3,
88 .end = INT_SDMMC3,
89 .flags = IORESOURCE_IRQ,
90 },
91 [1] = {
92 .start = TEGRA_SDMMC3_BASE,
93 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
94 .flags = IORESOURCE_MEM,
95 },
96};
97
98static struct resource sdhci_resource3[] = {
99 [0] = {
100 .start = INT_SDMMC4,
101 .end = INT_SDMMC4,
102 .flags = IORESOURCE_IRQ,
103 },
104 [1] = {
105 .start = TEGRA_SDMMC4_BASE,
106 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
107 .flags = IORESOURCE_MEM,
108 },
109};
110
111static struct embedded_sdio_data embedded_sdio_data0 = {
112 .cccr = {
113 .sdio_vsn = 2,
114 .multi_block = 1,
115 .low_speed = 0,
116 .wide_bus = 0,
117 .high_power = 1,
118 .high_speed = 1,
119 },
120 .cis = {
121 .vendor = 0x02d0,
122 .device = 0x4329,
123 },
124};
125
126static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
127 .mmc_data = {
128 .register_status_notify = ventana_wifi_status_register,
129 .embedded_sdio = &embedded_sdio_data0,
130 .built_in = 1,
131 },
132 .cd_gpio = -1,
133 .wp_gpio = -1,
134 .power_gpio = -1,
135};
136
137static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
138 .cd_gpio = TEGRA_GPIO_PI5,
139 .wp_gpio = TEGRA_GPIO_PH1,
140 .power_gpio = TEGRA_GPIO_PI6,
141};
142
143static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
144 .is_8bit = 1,
145 .cd_gpio = -1,
146 .wp_gpio = -1,
147 .power_gpio = -1,
148 .mmc_data = {
149 .built_in = 1,
150 }
151};
152
153static struct platform_device tegra_sdhci_device0 = {
154 .name = "sdhci-tegra",
155 .id = 0,
156 .resource = sdhci_resource0,
157 .num_resources = ARRAY_SIZE(sdhci_resource0),
158 .dev = {
159 .platform_data = &tegra_sdhci_platform_data0,
160 },
161};
162
163static struct platform_device tegra_sdhci_device2 = {
164 .name = "sdhci-tegra",
165 .id = 2,
166 .resource = sdhci_resource2,
167 .num_resources = ARRAY_SIZE(sdhci_resource2),
168 .dev = {
169 .platform_data = &tegra_sdhci_platform_data2,
170 },
171};
172
173static struct platform_device tegra_sdhci_device3 = {
174 .name = "sdhci-tegra",
175 .id = 3,
176 .resource = sdhci_resource3,
177 .num_resources = ARRAY_SIZE(sdhci_resource3),
178 .dev = {
179 .platform_data = &tegra_sdhci_platform_data3,
180 },
181};
182
183static int ventana_wifi_status_register(
184 void (*callback)(int card_present, void *dev_id),
185 void *dev_id)
186{
187 if (wifi_status_cb)
188 return -EAGAIN;
189 wifi_status_cb = callback;
190 wifi_status_cb_devid = dev_id;
191 return 0;
192}
193
194static int ventana_wifi_set_carddetect(int val)
195{
196 pr_debug("%s: %d\n", __func__, val);
197 if (wifi_status_cb)
198 wifi_status_cb(val, wifi_status_cb_devid);
199 else
200 pr_warning("%s: Nobody to notify\n", __func__);
201 return 0;
202}
203
204static int ventana_wifi_power(int on)
205{
206 pr_debug("%s: %d\n", __func__, on);
207
208 gpio_set_value(VENTANA_WLAN_PWR, on);
209 mdelay(100);
210 gpio_set_value(VENTANA_WLAN_RST, on);
211 mdelay(200);
212
213 if (on)
214 clk_enable(wifi_32k_clk);
215 else
216 clk_disable(wifi_32k_clk);
217
218 return 0;
219}
220
221static int ventana_wifi_reset(int on)
222{
223 pr_debug("%s: do nothing\n", __func__);
224 return 0;
225}
226
227static int __init ventana_wifi_init(void)
228{
229 wifi_32k_clk = clk_get_sys(NULL, "blink");
230 if (IS_ERR(wifi_32k_clk)) {
231 pr_err("%s: unable to get blink clock\n", __func__);
232 return PTR_ERR(wifi_32k_clk);
233 }
234
235 gpio_request(VENTANA_WLAN_PWR, "wlan_power");
236 gpio_request(VENTANA_WLAN_RST, "wlan_rst");
237 gpio_request(VENTANA_WLAN_WOW, "bcmsdh_sdmmc");
238
239 tegra_gpio_enable(VENTANA_WLAN_PWR);
240 tegra_gpio_enable(VENTANA_WLAN_RST);
241 tegra_gpio_enable(VENTANA_WLAN_WOW);
242
243 gpio_direction_output(VENTANA_WLAN_PWR, 0);
244 gpio_direction_output(VENTANA_WLAN_RST, 0);
245 gpio_direction_input(VENTANA_WLAN_WOW);
246
247 platform_device_register(&ventana_wifi_device);
248
249 device_init_wakeup(&ventana_wifi_device.dev, 1);
250 device_set_wakeup_enable(&ventana_wifi_device.dev, 0);
251
252 return 0;
253}
254int __init ventana_sdhci_init(void)
255{
256 tegra_gpio_enable(tegra_sdhci_platform_data2.power_gpio);
257 tegra_gpio_enable(tegra_sdhci_platform_data2.cd_gpio);
258 tegra_gpio_enable(tegra_sdhci_platform_data2.wp_gpio);
259 tegra_gpio_enable(tegra_sdhci_platform_data3.power_gpio);
260
261 platform_device_register(&tegra_sdhci_device3);
262 platform_device_register(&tegra_sdhci_device2);
263 platform_device_register(&tegra_sdhci_device0);
264
265 ventana_wifi_init();
266 return 0;
267}
diff --git a/arch/arm/mach-tegra/board-ventana-sensors.c b/arch/arm/mach-tegra/board-ventana-sensors.c
new file mode 100644
index 00000000000..81184d54599
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-sensors.c
@@ -0,0 +1,585 @@
1/*
2 * arch/arm/mach-tegra/board-ventana-sensors.c
3 *
4 * Copyright (c) 2011-2012, NVIDIA CORPORATION, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/delay.h>
35#include <linux/i2c.h>
36#include <linux/mpu.h>
37#include <linux/i2c/pca954x.h>
38#include <linux/i2c/pca953x.h>
39#include <linux/nct1008.h>
40#include <linux/err.h>
41#include <linux/regulator/consumer.h>
42
43#include <mach/gpio.h>
44
45#include <media/ov5650.h>
46#include <media/ov2710.h>
47#include <media/sh532u.h>
48#include <media/ssl3250a.h>
49#include <generated/mach-types.h>
50
51#include "gpio-names.h"
52#include "board.h"
53#include "board-ventana.h"
54#include "cpu-tegra.h"
55
56static struct regulator *cam1_2v8, *cam2_2v8;
57
58/* left ov5650 is CAM2 which is on csi_a */
59static int ventana_left_ov5650_power_on(void)
60{
61 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0);
62 gpio_direction_output(AVDD_DSI_CSI_ENB_GPIO, 1);
63 regulator_enable(cam2_2v8);
64 mdelay(5);
65 gpio_direction_output(CAM2_PWR_DN_GPIO, 0);
66 mdelay(5);
67 gpio_direction_output(CAM2_RST_L_GPIO, 0);
68 mdelay(1);
69 gpio_direction_output(CAM2_RST_L_GPIO, 1);
70 mdelay(20);
71 return 0;
72}
73
74static int ventana_left_ov5650_power_off(void)
75{
76 gpio_direction_output(AVDD_DSI_CSI_ENB_GPIO, 0);
77 gpio_direction_output(CAM2_RST_L_GPIO, 0);
78 gpio_direction_output(CAM2_PWR_DN_GPIO, 1);
79 regulator_disable(cam2_2v8);
80 return 0;
81}
82
83struct ov5650_platform_data ventana_left_ov5650_data = {
84 .power_on = ventana_left_ov5650_power_on,
85 .power_off = ventana_left_ov5650_power_off,
86};
87
88/* right ov5650 is CAM1 which is on csi_b */
89static int ventana_right_ov5650_power_on(void)
90{
91 gpio_direction_output(AVDD_DSI_CSI_ENB_GPIO, 1);
92 regulator_enable(cam1_2v8);
93 mdelay(5);
94 gpio_direction_output(CAM1_PWR_DN_GPIO, 0);
95 mdelay(5);
96 gpio_direction_output(CAM1_RST_L_GPIO, 0);
97 mdelay(1);
98 gpio_direction_output(CAM1_RST_L_GPIO, 1);
99 mdelay(20);
100 return 0;
101}
102
103static int ventana_right_ov5650_power_off(void)
104{
105 gpio_direction_output(AVDD_DSI_CSI_ENB_GPIO, 0);
106 gpio_direction_output(CAM1_RST_L_GPIO, 0);
107 gpio_direction_output(CAM1_PWR_DN_GPIO, 1);
108 regulator_disable(cam1_2v8);
109 return 0;
110}
111
112struct ov5650_platform_data ventana_right_ov5650_data = {
113 .power_on = ventana_right_ov5650_power_on,
114 .power_off = ventana_right_ov5650_power_off,
115};
116
117static int ventana_ov2710_power_on(void)
118{
119 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
120 gpio_direction_output(AVDD_DSI_CSI_ENB_GPIO, 1);
121 mdelay(5);
122 gpio_direction_output(CAM3_PWR_DN_GPIO, 0);
123 mdelay(5);
124 gpio_direction_output(CAM3_RST_L_GPIO, 0);
125 mdelay(1);
126 gpio_direction_output(CAM3_RST_L_GPIO, 1);
127 mdelay(20);
128 return 0;
129}
130
131static int ventana_ov2710_power_off(void)
132{
133 gpio_direction_output(CAM3_RST_L_GPIO, 0);
134 gpio_direction_output(CAM3_PWR_DN_GPIO, 1);
135 gpio_direction_output(AVDD_DSI_CSI_ENB_GPIO, 0);
136 gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0);
137 return 0;
138}
139
140struct ov2710_platform_data ventana_ov2710_data = {
141 .power_on = ventana_ov2710_power_on,
142 .power_off = ventana_ov2710_power_off,
143};
144
145
146static struct sh532u_platform_data sh532u_left_pdata = {
147 .num = 1,
148 .sync = 2,
149 .dev_name = "focuser",
150 .gpio_reset = CAM2_RST_L_GPIO,
151 .gpio_en = CAM2_LDO_SHUTDN_L_GPIO,
152};
153
154static struct sh532u_platform_data sh532u_right_pdata = {
155 .num = 2,
156 .sync = 1,
157 .dev_name = "focuser",
158 .gpio_reset = CAM1_RST_L_GPIO,
159 .gpio_en = CAM1_LDO_SHUTDN_L_GPIO,
160};
161
162
163static struct nvc_torch_pin_state ventana_ssl3250a_pinstate = {
164 .mask = 0x0040, /* VGP6 */
165 .values = 0x0040,
166};
167
168static struct ssl3250a_platform_data ventana_ssl3250a_pdata = {
169 .dev_name = "torch",
170 .pinstate = &ventana_ssl3250a_pinstate,
171 .gpio_act = CAMERA_FLASH_ACT_GPIO,
172};
173
174
175static void ventana_isl29018_init(void)
176{
177 tegra_gpio_enable(ISL29018_IRQ_GPIO);
178 gpio_request(ISL29018_IRQ_GPIO, "isl29018");
179 gpio_direction_input(ISL29018_IRQ_GPIO);
180}
181
182#ifdef CONFIG_SENSORS_AK8975
183static void ventana_akm8975_init(void)
184{
185 tegra_gpio_enable(AKM8975_IRQ_GPIO);
186 gpio_request(AKM8975_IRQ_GPIO, "akm8975");
187 gpio_direction_input(AKM8975_IRQ_GPIO);
188}
189#endif
190
191static void ventana_nct1008_init(void)
192{
193 tegra_gpio_enable(NCT1008_THERM2_GPIO);
194 gpio_request(NCT1008_THERM2_GPIO, "temp_alert");
195 gpio_direction_input(NCT1008_THERM2_GPIO);
196}
197
198static struct nct1008_platform_data ventana_nct1008_pdata = {
199 .supported_hwrev = true,
200 .ext_range = false,
201 .conv_rate = 0x08,
202 .offset = 0,
203 .hysteresis = 0,
204 .shutdown_ext_limit = 115,
205 .shutdown_local_limit = 120,
206 .throttling_ext_limit = 90,
207 .alarm_fn = tegra_throttling_enable,
208};
209
210static const struct i2c_board_info ventana_i2c0_board_info[] = {
211 {
212 I2C_BOARD_INFO("isl29018", 0x44),
213 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PZ2),
214 },
215};
216
217static const struct i2c_board_info ventana_i2c2_board_info[] = {
218 {
219 I2C_BOARD_INFO("bq20z75", 0x0B),
220 },
221};
222
223static struct pca953x_platform_data ventana_tca6416_data = {
224 .gpio_base = TCA6416_GPIO_BASE,
225};
226
227static struct pca954x_platform_mode ventana_pca9546_modes[] = {
228 { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = 1 }, /* REAR CAM1 */
229 { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = 1 }, /* REAR CAM2 */
230 { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = 1 }, /* FRONT CAM3 */
231};
232
233static struct pca954x_platform_data ventana_pca9546_data = {
234 .modes = ventana_pca9546_modes,
235 .num_modes = ARRAY_SIZE(ventana_pca9546_modes),
236};
237
238static const struct i2c_board_info ventana_i2c3_board_info_tca6416[] = {
239 {
240 I2C_BOARD_INFO("tca6416", 0x20),
241 .platform_data = &ventana_tca6416_data,
242 },
243};
244
245static const struct i2c_board_info ventana_i2c3_board_info_pca9546[] = {
246 {
247 I2C_BOARD_INFO("pca9546", 0x70),
248 .platform_data = &ventana_pca9546_data,
249 },
250};
251
252static const struct i2c_board_info ventana_i2c3_board_info_ssl3250a[] = {
253 {
254 I2C_BOARD_INFO("ssl3250a", 0x30),
255 .platform_data = &ventana_ssl3250a_pdata,
256 },
257};
258
259static struct i2c_board_info ventana_i2c4_board_info[] = {
260 {
261 I2C_BOARD_INFO("nct1008", 0x4C),
262 .irq = TEGRA_GPIO_TO_IRQ(NCT1008_THERM2_GPIO),
263 .platform_data = &ventana_nct1008_pdata,
264 },
265
266#ifdef CONFIG_SENSORS_AK8975
267 {
268 I2C_BOARD_INFO("akm8975", 0x0C),
269 .irq = TEGRA_GPIO_TO_IRQ(AKM8975_IRQ_GPIO),
270 },
271#endif
272};
273
274static struct i2c_board_info ventana_i2c6_board_info[] = {
275 {
276 I2C_BOARD_INFO("ov5650R", 0x36),
277 .platform_data = &ventana_right_ov5650_data,
278 },
279 {
280 I2C_BOARD_INFO("sh532u", 0x72),
281 .platform_data = &sh532u_right_pdata,
282 },
283};
284
285static struct i2c_board_info ventana_i2c7_board_info[] = {
286 {
287 I2C_BOARD_INFO("ov5650L", 0x36),
288 .platform_data = &ventana_left_ov5650_data,
289 },
290 {
291 I2C_BOARD_INFO("sh532u", 0x72),
292 .platform_data = &sh532u_left_pdata,
293 },
294};
295
296static struct i2c_board_info ventana_i2c8_board_info[] = {
297 {
298 I2C_BOARD_INFO("ov2710", 0x36),
299 .platform_data = &ventana_ov2710_data,
300 },
301};
302
303/* MPU board file definition */
304#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
305#define MPU_GYRO_NAME "mpu3050"
306#endif
307#if (MPU_GYRO_TYPE == MPU_TYPE_MPU6050)
308#define MPU_GYRO_NAME "mpu6050"
309#endif
310static struct mpu_platform_data mpu_gyro_data = {
311 .int_config = 0x10,
312 .level_shifter = 0,
313 .orientation = MPU_GYRO_ORIENTATION, /* Located in board_[platformname].h */
314};
315
316#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
317static struct ext_slave_platform_data mpu_accel_data = {
318 .address = MPU_ACCEL_ADDR,
319 .irq = 0,
320 .adapt_num = MPU_ACCEL_BUS_NUM,
321 .bus = EXT_SLAVE_BUS_SECONDARY,
322 .orientation = MPU_ACCEL_ORIENTATION, /* Located in board_[platformname].h */
323};
324#endif
325
326static struct ext_slave_platform_data mpu_compass_data = {
327 .address = MPU_COMPASS_ADDR,
328 .irq = 0,
329 .adapt_num = MPU_COMPASS_BUS_NUM,
330 .bus = EXT_SLAVE_BUS_PRIMARY,
331 .orientation = MPU_COMPASS_ORIENTATION, /* Located in board_[platformname].h */
332};
333
334static struct i2c_board_info __initdata inv_mpu_i2c2_board_info[] = {
335 {
336 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
337 .irq = TEGRA_GPIO_TO_IRQ(MPU_GYRO_IRQ_GPIO),
338 .platform_data = &mpu_gyro_data,
339 },
340#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
341 {
342 I2C_BOARD_INFO(MPU_ACCEL_NAME, MPU_ACCEL_ADDR),
343#if MPU_ACCEL_IRQ_GPIO
344 .irq = TEGRA_GPIO_TO_IRQ(MPU_ACCEL_IRQ_GPIO),
345#endif
346 .platform_data = &mpu_accel_data,
347 },
348#endif
349};
350
351static struct i2c_board_info __initdata inv_mpu_i2c4_board_info[] = {
352 {
353 I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
354#if MPU_COMPASS_IRQ_GPIO
355 .irq = TEGRA_GPIO_TO_IRQ(MPU_COMPASS_IRQ_GPIO),
356#endif
357 .platform_data = &mpu_compass_data,
358 },
359};
360
361static void mpuirq_init(void)
362{
363 int ret = 0;
364
365 pr_info("*** MPU START *** mpuirq_init...\n");
366
367#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
368#if MPU_ACCEL_IRQ_GPIO
369 /* ACCEL-IRQ assignment */
370 tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
371 ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
372 if (ret < 0) {
373 pr_err("%s: gpio_request failed %d\n", __func__, ret);
374 return;
375 }
376
377 ret = gpio_direction_input(MPU_ACCEL_IRQ_GPIO);
378 if (ret < 0) {
379 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
380 gpio_free(MPU_ACCEL_IRQ_GPIO);
381 return;
382 }
383#endif
384#endif
385
386 /* MPU-IRQ assignment */
387 tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
388 ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
389 if (ret < 0) {
390 pr_err("%s: gpio_request failed %d\n", __func__, ret);
391 return;
392 }
393
394 ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO);
395 if (ret < 0) {
396 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
397 gpio_free(MPU_GYRO_IRQ_GPIO);
398 return;
399 }
400 pr_info("*** MPU END *** mpuirq_init...\n");
401
402 i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c2_board_info,
403 ARRAY_SIZE(inv_mpu_i2c2_board_info));
404 i2c_register_board_info(MPU_COMPASS_BUS_NUM, inv_mpu_i2c4_board_info,
405 ARRAY_SIZE(inv_mpu_i2c4_board_info));
406}
407
408int __init ventana_sensors_init(void)
409{
410 struct board_info BoardInfo;
411
412 ventana_isl29018_init();
413#ifdef CONFIG_SENSORS_AK8975
414 ventana_akm8975_init();
415#endif
416 mpuirq_init();
417 ventana_nct1008_init();
418
419 i2c_register_board_info(0, ventana_i2c0_board_info,
420 ARRAY_SIZE(ventana_i2c0_board_info));
421
422 tegra_get_board_info(&BoardInfo);
423
424 /*
425 * battery driver is supported on FAB.D boards and above only,
426 * since they have the necessary hardware rework
427 */
428 if (BoardInfo.sku > 0) {
429 i2c_register_board_info(2, ventana_i2c2_board_info,
430 ARRAY_SIZE(ventana_i2c2_board_info));
431 }
432
433 i2c_register_board_info(3, ventana_i2c3_board_info_ssl3250a,
434 ARRAY_SIZE(ventana_i2c3_board_info_ssl3250a));
435
436 i2c_register_board_info(4, ventana_i2c4_board_info,
437 ARRAY_SIZE(ventana_i2c4_board_info));
438
439 i2c_register_board_info(6, ventana_i2c6_board_info,
440 ARRAY_SIZE(ventana_i2c6_board_info));
441
442 i2c_register_board_info(7, ventana_i2c7_board_info,
443 ARRAY_SIZE(ventana_i2c7_board_info));
444
445 i2c_register_board_info(8, ventana_i2c8_board_info,
446 ARRAY_SIZE(ventana_i2c8_board_info));
447
448 return 0;
449}
450
451#ifdef CONFIG_TEGRA_CAMERA
452
453struct tegra_camera_gpios {
454 const char *name;
455 int gpio;
456 bool tegra_internal_gpio;
457 int enabled;
458};
459
460#define TEGRA_CAMERA_GPIO(_name, _gpio, _tegra_internal_gpio, _enabled) \
461 { \
462 .name = _name, \
463 .gpio = _gpio, \
464 .tegra_internal_gpio = _tegra_internal_gpio, \
465 .enabled = _enabled, \
466 }
467
468static struct tegra_camera_gpios ventana_camera_gpio_keys[] = {
469 [0] = TEGRA_CAMERA_GPIO("camera_power_en", CAMERA_POWER_GPIO, true, 1),
470 [1] = TEGRA_CAMERA_GPIO("camera_csi_sel", CAMERA_CSI_MUX_SEL_GPIO, true, 0),
471 [2] = TEGRA_CAMERA_GPIO("torch_gpio_act", CAMERA_FLASH_ACT_GPIO, true, 0),
472
473 [3] = TEGRA_CAMERA_GPIO("en_avdd_csi", AVDD_DSI_CSI_ENB_GPIO, false, 1),
474 [4] = TEGRA_CAMERA_GPIO("cam_i2c_mux_rst_lo", CAM_I2C_MUX_RST_GPIO, false, 1),
475
476 [5] = TEGRA_CAMERA_GPIO("cam2_af_pwdn_lo", CAM2_AF_PWR_DN_L_GPIO, false, 0),
477 [6] = TEGRA_CAMERA_GPIO("cam2_pwdn", CAM2_PWR_DN_GPIO, false, 0),
478 [7] = TEGRA_CAMERA_GPIO("cam2_rst_lo", CAM2_RST_L_GPIO, false, 1),
479
480 [8] = TEGRA_CAMERA_GPIO("cam3_af_pwdn_lo", CAM3_AF_PWR_DN_L_GPIO, false, 0),
481 [9] = TEGRA_CAMERA_GPIO("cam3_pwdn", CAM3_PWR_DN_GPIO, false, 0),
482 [10] = TEGRA_CAMERA_GPIO("cam3_rst_lo", CAM3_RST_L_GPIO, false, 1),
483
484 [11] = TEGRA_CAMERA_GPIO("cam1_af_pwdn_lo", CAM1_AF_PWR_DN_L_GPIO, false, 0),
485 [12] = TEGRA_CAMERA_GPIO("cam1_pwdn", CAM1_PWR_DN_GPIO, false, 0),
486 [13] = TEGRA_CAMERA_GPIO("cam1_rst_lo", CAM1_RST_L_GPIO, false, 1),
487};
488
489int __init ventana_camera_late_init(void)
490{
491 int ret;
492 int i;
493 struct regulator *cam_ldo6 = NULL;
494
495 if (!machine_is_ventana())
496 return 0;
497
498 cam_ldo6 = regulator_get(NULL, "vdd_ldo6");
499 if (IS_ERR_OR_NULL(cam_ldo6)) {
500 pr_err("%s: Couldn't get regulator ldo6\n", __func__);
501 return PTR_ERR(cam_ldo6);
502 }
503
504 ret = regulator_enable(cam_ldo6);
505 if (ret){
506 pr_err("%s: Failed to enable ldo6\n", __func__);
507 goto fail_put_regulator_ldo6;
508 }
509
510 i2c_new_device(i2c_get_adapter(3), ventana_i2c3_board_info_tca6416);
511
512 for (i = 0; i < ARRAY_SIZE(ventana_camera_gpio_keys); i++) {
513
514 if (ventana_camera_gpio_keys[i].tegra_internal_gpio)
515 tegra_gpio_enable(ventana_camera_gpio_keys[i].gpio);
516
517 ret = gpio_request(ventana_camera_gpio_keys[i].gpio,
518 ventana_camera_gpio_keys[i].name);
519 if (ret < 0) {
520 pr_err("%s: gpio_request failed for gpio #%d\n",
521 __func__, i);
522 goto fail_free_gpio;
523 }
524
525 gpio_direction_output(ventana_camera_gpio_keys[i].gpio,
526 ventana_camera_gpio_keys[i].enabled);
527
528 gpio_export(ventana_camera_gpio_keys[i].gpio, false);
529 }
530
531 ventana_cam_fixed_voltage_regulator_init();
532
533 cam1_2v8 = regulator_get(NULL, "cam1_2v8");
534 if (WARN_ON(IS_ERR(cam1_2v8))) {
535 pr_err("%s: couldn't get regulator cam1_2v8: %ld\n",
536 __func__, PTR_ERR(cam1_2v8));
537 ret = PTR_ERR(cam1_2v8);
538 goto fail_free_gpio;
539 } else {
540 regulator_enable(cam1_2v8);
541 }
542
543 cam2_2v8 = regulator_get(NULL, "cam2_2v8");
544 if (WARN_ON(IS_ERR(cam2_2v8))) {
545 pr_err("%s: couldn't get regulator cam2_2v8: %ld\n",
546 __func__, PTR_ERR(cam2_2v8));
547 ret = PTR_ERR(cam2_2v8);
548 goto fail_put_regulator_cam1_2v8;
549 } else {
550 regulator_enable(cam2_2v8);
551 }
552
553 i2c_new_device(i2c_get_adapter(3), ventana_i2c3_board_info_pca9546);
554
555 ventana_ov2710_power_off();
556 ventana_left_ov5650_power_off();
557 ventana_right_ov5650_power_off();
558
559 ret = regulator_disable(cam_ldo6);
560 if (ret){
561 pr_err("%s: Failed to disable ldo6\n", __func__);
562 goto fail_put_regulator_cam2_2v8;
563 }
564
565 regulator_put(cam_ldo6);
566 return 0;
567
568fail_put_regulator_cam2_2v8:
569 regulator_put(cam2_2v8);
570
571fail_put_regulator_cam1_2v8:
572 regulator_put(cam1_2v8);
573
574fail_free_gpio:
575 while (i--)
576 gpio_free(ventana_camera_gpio_keys[i].gpio);
577
578fail_put_regulator_ldo6:
579 regulator_put(cam_ldo6);
580 return ret;
581}
582
583late_initcall(ventana_camera_late_init);
584
585#endif /* CONFIG_TEGRA_CAMERA */
diff --git a/arch/arm/mach-tegra/board-ventana.c b/arch/arm/mach-tegra/board-ventana.c
new file mode 100644
index 00000000000..a7f051a6c72
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana.c
@@ -0,0 +1,641 @@
1/*
2 * arch/arm/mach-tegra/board-ventana.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/serial_8250.h>
28#include <linux/i2c.h>
29#include <linux/i2c/panjit_ts.h>
30#include <linux/dma-mapping.h>
31#include <linux/delay.h>
32#include <linux/i2c-tegra.h>
33#include <linux/gpio.h>
34#include <linux/gpio_keys.h>
35#include <linux/input.h>
36#include <linux/platform_data/tegra_usb.h>
37#include <linux/mfd/tps6586x.h>
38#include <linux/memblock.h>
39#include <linux/i2c/atmel_mxt_ts.h>
40#include <linux/tegra_uart.h>
41
42#include <sound/wm8903.h>
43
44#include <mach/clk.h>
45#include <mach/iomap.h>
46#include <mach/irqs.h>
47#include <mach/pinmux.h>
48#include <mach/iomap.h>
49#include <mach/io.h>
50#include <mach/i2s.h>
51#include <mach/tegra_wm8903_pdata.h>
52
53#include <asm/mach-types.h>
54#include <asm/mach/arch.h>
55#include <mach/usb_phy.h>
56
57#include "board.h"
58#include "clock.h"
59#include "board-ventana.h"
60#include "devices.h"
61#include "gpio-names.h"
62#include "fuse.h"
63#include "wakeups-t2.h"
64#include "pm.h"
65
66static struct tegra_utmip_config utmi_phy_config[] = {
67 [0] = {
68 .hssync_start_delay = 9,
69 .idle_wait_delay = 17,
70 .elastic_limit = 16,
71 .term_range_adj = 6,
72 .xcvr_setup = 15,
73 .xcvr_setup_offset = 0,
74 .xcvr_use_fuses = 1,
75 .xcvr_lsfslew = 2,
76 .xcvr_lsrslew = 2,
77 },
78 [1] = {
79 .hssync_start_delay = 9,
80 .idle_wait_delay = 17,
81 .elastic_limit = 16,
82 .term_range_adj = 6,
83 .xcvr_setup = 8,
84 .xcvr_setup_offset = 0,
85 .xcvr_use_fuses = 1,
86 .xcvr_lsfslew = 2,
87 .xcvr_lsrslew = 2,
88 },
89};
90
91static struct tegra_ulpi_config ulpi_phy_config = {
92 .reset_gpio = TEGRA_GPIO_PG2,
93 .clk = "cdev2",
94};
95
96static struct resource ventana_bcm4329_rfkill_resources[] = {
97 {
98 .name = "bcm4329_nshutdown_gpio",
99 .start = TEGRA_GPIO_PU0,
100 .end = TEGRA_GPIO_PU0,
101 .flags = IORESOURCE_IO,
102 },
103};
104
105static struct platform_device ventana_bcm4329_rfkill_device = {
106 .name = "bcm4329_rfkill",
107 .id = -1,
108 .num_resources = ARRAY_SIZE(ventana_bcm4329_rfkill_resources),
109 .resource = ventana_bcm4329_rfkill_resources,
110};
111
112static void __init ventana_bt_rfkill(void)
113{
114 /*Add Clock Resource*/
115 clk_add_alias("bcm4329_32k_clk", ventana_bcm4329_rfkill_device.name, \
116 "blink", NULL);
117 return;
118}
119
120static struct resource ventana_bluesleep_resources[] = {
121 [0] = {
122 .name = "gpio_host_wake",
123 .start = TEGRA_GPIO_PU6,
124 .end = TEGRA_GPIO_PU6,
125 .flags = IORESOURCE_IO,
126 },
127 [1] = {
128 .name = "gpio_ext_wake",
129 .start = TEGRA_GPIO_PU1,
130 .end = TEGRA_GPIO_PU1,
131 .flags = IORESOURCE_IO,
132 },
133 [2] = {
134 .name = "host_wake",
135 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
136 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
137 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
138 },
139};
140
141static struct platform_device ventana_bluesleep_device = {
142 .name = "bluesleep",
143 .id = -1,
144 .num_resources = ARRAY_SIZE(ventana_bluesleep_resources),
145 .resource = ventana_bluesleep_resources,
146};
147
148static void __init ventana_setup_bluesleep(void)
149{
150 platform_device_register(&ventana_bluesleep_device);
151 tegra_gpio_enable(TEGRA_GPIO_PU6);
152 tegra_gpio_enable(TEGRA_GPIO_PU1);
153 return;
154}
155
156static __initdata struct tegra_clk_init_table ventana_clk_init_table[] = {
157 /* name parent rate enabled */
158 { "blink", "clk_32k", 32768, false},
159 { "pll_p_out4", "pll_p", 24000000, true },
160 { "pwm", "clk_32k", 32768, false},
161 { "i2s1", "pll_a_out0", 0, false},
162 { "i2s2", "pll_a_out0", 0, false},
163 { "spdif_out", "pll_a_out0", 0, false},
164 { NULL, NULL, 0, 0},
165};
166
167static struct tegra_ulpi_config ventana_ehci2_ulpi_phy_config = {
168 .reset_gpio = TEGRA_GPIO_PV1,
169 .clk = "cdev2",
170};
171
172static struct tegra_ehci_platform_data ventana_ehci2_ulpi_platform_data = {
173 .operating_mode = TEGRA_USB_HOST,
174 .power_down_on_bus_suspend = 1,
175 .phy_config = &ventana_ehci2_ulpi_phy_config,
176 .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI,
177 .default_enable = true,
178};
179
180static struct tegra_i2c_platform_data ventana_i2c1_platform_data = {
181 .adapter_nr = 0,
182 .bus_count = 1,
183 .bus_clk_rate = { 400000, 0 },
184 .slave_addr = 0x00FC,
185 .scl_gpio = {TEGRA_GPIO_PC4, 0},
186 .sda_gpio = {TEGRA_GPIO_PC5, 0},
187 .arb_recovery = arb_lost_recovery,
188};
189
190static const struct tegra_pingroup_config i2c2_ddc = {
191 .pingroup = TEGRA_PINGROUP_DDC,
192 .func = TEGRA_MUX_I2C2,
193};
194
195static const struct tegra_pingroup_config i2c2_gen2 = {
196 .pingroup = TEGRA_PINGROUP_PTA,
197 .func = TEGRA_MUX_I2C2,
198};
199
200static struct tegra_i2c_platform_data ventana_i2c2_platform_data = {
201 .adapter_nr = 1,
202 .bus_count = 2,
203 .bus_clk_rate = { 100000, 10000 },
204 .bus_mux = { &i2c2_ddc, &i2c2_gen2 },
205 .bus_mux_len = { 1, 1 },
206 .slave_addr = 0x00FC,
207 .scl_gpio = {0, TEGRA_GPIO_PT5},
208 .sda_gpio = {0, TEGRA_GPIO_PT6},
209 .arb_recovery = arb_lost_recovery,
210};
211
212static struct tegra_i2c_platform_data ventana_i2c3_platform_data = {
213 .adapter_nr = 3,
214 .bus_count = 1,
215 .bus_clk_rate = { 400000, 0 },
216 .slave_addr = 0x00FC,
217 .scl_gpio = {TEGRA_GPIO_PBB2, 0},
218 .sda_gpio = {TEGRA_GPIO_PBB3, 0},
219 .arb_recovery = arb_lost_recovery,
220};
221
222static struct tegra_i2c_platform_data ventana_dvc_platform_data = {
223 .adapter_nr = 4,
224 .bus_count = 1,
225 .bus_clk_rate = { 400000, 0 },
226 .is_dvc = true,
227 .scl_gpio = {TEGRA_GPIO_PZ6, 0},
228 .sda_gpio = {TEGRA_GPIO_PZ7, 0},
229 .arb_recovery = arb_lost_recovery,
230};
231
232static struct wm8903_platform_data ventana_wm8903_pdata = {
233 .irq_active_low = 0,
234 .micdet_cfg = 0,
235 .micdet_delay = 100,
236 .gpio_base = WM8903_GPIO_BASE,
237 .gpio_cfg = {
238 (WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT << WM8903_GP1_FN_SHIFT),
239 (WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT << WM8903_GP2_FN_SHIFT) |
240 WM8903_GP2_DIR,
241 0,
242 WM8903_GPIO_NO_CONFIG,
243 WM8903_GPIO_NO_CONFIG,
244 },
245};
246
247static struct i2c_board_info __initdata wm8903_board_info = {
248 I2C_BOARD_INFO("wm8903", 0x1a),
249 .platform_data = &ventana_wm8903_pdata,
250 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
251};
252
253static void ventana_i2c_init(void)
254{
255 tegra_i2c_device1.dev.platform_data = &ventana_i2c1_platform_data;
256 tegra_i2c_device2.dev.platform_data = &ventana_i2c2_platform_data;
257 tegra_i2c_device3.dev.platform_data = &ventana_i2c3_platform_data;
258 tegra_i2c_device4.dev.platform_data = &ventana_dvc_platform_data;
259
260 platform_device_register(&tegra_i2c_device1);
261 platform_device_register(&tegra_i2c_device2);
262 platform_device_register(&tegra_i2c_device3);
263 platform_device_register(&tegra_i2c_device4);
264
265 i2c_register_board_info(0, &wm8903_board_info, 1);
266}
267static struct platform_device *ventana_uart_devices[] __initdata = {
268 &tegra_uartb_device,
269 &tegra_uartc_device,
270 &tegra_uartd_device,
271};
272
273static struct uart_clk_parent uart_parent_clk[] = {
274 [0] = {.name = "pll_p"},
275 [1] = {.name = "pll_m"},
276 [2] = {.name = "clk_m"},
277};
278
279static struct tegra_uart_platform_data ventana_uart_pdata;
280
281static void __init uart_debug_init(void)
282{
283 unsigned long rate;
284 struct clk *c;
285
286 /* UARTD is the debug port. */
287 pr_info("Selecting UARTD as the debug console\n");
288 ventana_uart_devices[2] = &debug_uartd_device;
289 debug_uart_port_base = ((struct plat_serial8250_port *)(
290 debug_uartd_device.dev.platform_data))->mapbase;
291 debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
292
293 /* Clock enable for the debug channel */
294 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
295 rate = ((struct plat_serial8250_port *)(
296 debug_uartd_device.dev.platform_data))->uartclk;
297 pr_info("The debug console clock name is %s\n",
298 debug_uart_clk->name);
299 c = tegra_get_clock_by_name("pll_p");
300 if (IS_ERR_OR_NULL(c))
301 pr_err("Not getting the parent clock pll_p\n");
302 else
303 clk_set_parent(debug_uart_clk, c);
304
305 clk_enable(debug_uart_clk);
306 clk_set_rate(debug_uart_clk, rate);
307 } else {
308 pr_err("Not getting the clock %s for debug console\n",
309 debug_uart_clk->name);
310 }
311}
312
313static void __init ventana_uart_init(void)
314{
315 int i;
316 struct clk *c;
317
318 for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
319 c = tegra_get_clock_by_name(uart_parent_clk[i].name);
320 if (IS_ERR_OR_NULL(c)) {
321 pr_err("Not able to get the clock for %s\n",
322 uart_parent_clk[i].name);
323 continue;
324 }
325 uart_parent_clk[i].parent_clk = c;
326 uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
327 }
328 ventana_uart_pdata.parent_clk_list = uart_parent_clk;
329 ventana_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
330 tegra_uartb_device.dev.platform_data = &ventana_uart_pdata;
331 tegra_uartc_device.dev.platform_data = &ventana_uart_pdata;
332 tegra_uartd_device.dev.platform_data = &ventana_uart_pdata;
333
334 /* Register low speed only if it is selected */
335 if (!is_tegra_debug_uartport_hs())
336 uart_debug_init();
337
338 platform_add_devices(ventana_uart_devices,
339 ARRAY_SIZE(ventana_uart_devices));
340}
341
342#ifdef CONFIG_KEYBOARD_GPIO
343#define GPIO_KEY(_id, _gpio, _iswake) \
344 { \
345 .code = _id, \
346 .gpio = TEGRA_GPIO_##_gpio, \
347 .active_low = 1, \
348 .desc = #_id, \
349 .type = EV_KEY, \
350 .wakeup = _iswake, \
351 .debounce_interval = 10, \
352 }
353
354static struct gpio_keys_button ventana_keys[] = {
355 [0] = GPIO_KEY(KEY_FIND, PQ3, 0),
356 [1] = GPIO_KEY(KEY_HOME, PQ1, 0),
357 [2] = GPIO_KEY(KEY_BACK, PQ2, 0),
358 [3] = GPIO_KEY(KEY_VOLUMEUP, PQ5, 0),
359 [4] = GPIO_KEY(KEY_VOLUMEDOWN, PQ4, 0),
360 [5] = GPIO_KEY(KEY_POWER, PV2, 1),
361 [6] = GPIO_KEY(KEY_MENU, PC7, 0),
362};
363
364#define PMC_WAKE_STATUS 0x14
365
366static int ventana_wakeup_key(void)
367{
368 unsigned long status =
369 readl(IO_ADDRESS(TEGRA_PMC_BASE) + PMC_WAKE_STATUS);
370
371 return status & TEGRA_WAKE_GPIO_PV2 ? KEY_POWER : KEY_RESERVED;
372}
373
374static struct gpio_keys_platform_data ventana_keys_platform_data = {
375 .buttons = ventana_keys,
376 .nbuttons = ARRAY_SIZE(ventana_keys),
377 .wakeup_key = ventana_wakeup_key,
378};
379
380static struct platform_device ventana_keys_device = {
381 .name = "gpio-keys",
382 .id = 0,
383 .dev = {
384 .platform_data = &ventana_keys_platform_data,
385 },
386};
387
388static void ventana_keys_init(void)
389{
390 int i;
391
392 for (i = 0; i < ARRAY_SIZE(ventana_keys); i++)
393 tegra_gpio_enable(ventana_keys[i].gpio);
394}
395#endif
396
397static struct platform_device tegra_camera = {
398 .name = "tegra_camera",
399 .id = -1,
400};
401
402static struct tegra_wm8903_platform_data ventana_audio_pdata = {
403 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
404 .gpio_hp_det = TEGRA_GPIO_HP_DET,
405 .gpio_hp_mute = -1,
406 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
407 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
408};
409
410static struct platform_device ventana_audio_device = {
411 .name = "tegra-snd-wm8903",
412 .id = 0,
413 .dev = {
414 .platform_data = &ventana_audio_pdata,
415 },
416};
417
418static struct platform_device *ventana_devices[] __initdata = {
419 &tegra_pmu_device,
420 &tegra_gart_device,
421 &tegra_aes_device,
422#ifdef CONFIG_KEYBOARD_GPIO
423 &ventana_keys_device,
424#endif
425 &tegra_wdt_device,
426 &tegra_avp_device,
427 &tegra_camera,
428 &tegra_i2s_device1,
429 &tegra_i2s_device2,
430 &tegra_spdif_device,
431 &tegra_das_device,
432 &spdif_dit_device,
433 &bluetooth_dit_device,
434 &ventana_bcm4329_rfkill_device,
435 &tegra_pcm_device,
436 &ventana_audio_device,
437};
438
439
440static struct mxt_platform_data atmel_mxt_info = {
441 .x_line = 27,
442 .y_line = 42,
443 .x_size = 768,
444 .y_size = 1366,
445 .blen = 0x20,
446 .threshold = 0x3C,
447 .voltage = 3300000,
448 .orient = MXT_ROTATED_90,
449 .irqflags = IRQF_TRIGGER_FALLING,
450};
451
452static struct i2c_board_info __initdata i2c_info[] = {
453 {
454 I2C_BOARD_INFO("atmel_mxt_ts", 0x5A),
455 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6),
456 .platform_data = &atmel_mxt_info,
457 },
458};
459
460static int __init ventana_touch_init_atmel(void)
461{
462 tegra_gpio_enable(TEGRA_GPIO_PV6);
463 tegra_gpio_enable(TEGRA_GPIO_PQ7);
464
465 gpio_request(TEGRA_GPIO_PV6, "atmel-irq");
466 gpio_direction_input(TEGRA_GPIO_PV6);
467
468 gpio_request(TEGRA_GPIO_PQ7, "atmel-reset");
469 gpio_direction_output(TEGRA_GPIO_PQ7, 0);
470 msleep(1);
471 gpio_set_value(TEGRA_GPIO_PQ7, 1);
472 msleep(100);
473
474 i2c_register_board_info(0, i2c_info, 1);
475
476 return 0;
477}
478
479static struct panjit_i2c_ts_platform_data panjit_data = {
480 .gpio_reset = TEGRA_GPIO_PQ7,
481};
482
483static struct i2c_board_info __initdata ventana_i2c_bus1_touch_info[] = {
484 {
485 I2C_BOARD_INFO("panjit_touch", 0x3),
486 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6),
487 .platform_data = &panjit_data,
488 },
489};
490
491static int __init ventana_touch_init_panjit(void)
492{
493 tegra_gpio_enable(TEGRA_GPIO_PV6);
494
495 tegra_gpio_enable(TEGRA_GPIO_PQ7);
496 i2c_register_board_info(0, ventana_i2c_bus1_touch_info, 1);
497
498 return 0;
499}
500
501static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
502 [0] = {
503 .instance = 0,
504 .vbus_irq = TPS6586X_INT_BASE + TPS6586X_INT_USB_DET,
505 .vbus_gpio = TEGRA_GPIO_PD0,
506 },
507 [1] = {
508 .instance = 1,
509 .vbus_gpio = -1,
510 },
511 [2] = {
512 .instance = 2,
513 .vbus_gpio = TEGRA_GPIO_PD3,
514 },
515};
516
517static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
518 [0] = {
519 .phy_config = &utmi_phy_config[0],
520 .operating_mode = TEGRA_USB_HOST,
521 .power_down_on_bus_suspend = 1,
522 .default_enable = true,
523 },
524 [1] = {
525 .phy_config = &ulpi_phy_config,
526 .operating_mode = TEGRA_USB_HOST,
527 .power_down_on_bus_suspend = 1,
528 .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI,
529 .default_enable = true,
530 },
531 [2] = {
532 .phy_config = &utmi_phy_config[1],
533 .operating_mode = TEGRA_USB_HOST,
534 .power_down_on_bus_suspend = 1,
535 .hotplug = 1,
536 .default_enable = true,
537 },
538};
539
540static struct tegra_otg_platform_data tegra_otg_pdata = {
541 .ehci_device = &tegra_ehci1_device,
542 .ehci_pdata = &tegra_ehci_pdata[0],
543};
544
545static int __init ventana_gps_init(void)
546{
547 struct clk *clk32 = clk_get_sys(NULL, "blink");
548 if (!IS_ERR(clk32)) {
549 clk_set_rate(clk32,clk32->parent->rate);
550 clk_enable(clk32);
551 }
552
553 tegra_gpio_enable(TEGRA_GPIO_PZ3);
554 return 0;
555}
556
557static void ventana_usb_init(void)
558{
559 tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata));
560 /* OTG should be the first to be registered */
561 tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
562 platform_device_register(&tegra_otg_device);
563
564 platform_device_register(&tegra_udc_device);
565 platform_device_register(&tegra_ehci2_device);
566
567 tegra_ehci3_device.dev.platform_data=&tegra_ehci_pdata[2];
568 platform_device_register(&tegra_ehci3_device);
569}
570
571static void __init tegra_ventana_init(void)
572{
573 struct board_info BoardInfo;
574
575 tegra_clk_init_from_table(ventana_clk_init_table);
576 ventana_pinmux_init();
577 ventana_i2c_init();
578 ventana_uart_init();
579 tegra_ehci2_device.dev.platform_data
580 = &ventana_ehci2_ulpi_platform_data;
581 platform_add_devices(ventana_devices, ARRAY_SIZE(ventana_devices));
582 tegra_ram_console_debug_init();
583 ventana_sdhci_init();
584 ventana_charge_init();
585 ventana_regulator_init();
586 ventana_charger_init();
587
588 tegra_get_board_info(&BoardInfo);
589
590 /* boards with sku > 0 have atmel touch panels */
591 if (BoardInfo.sku) {
592 pr_info("Initializing Atmel touch driver\n");
593 ventana_touch_init_atmel();
594 } else {
595 pr_info("Initializing Panjit touch driver\n");
596 ventana_touch_init_panjit();
597 }
598
599#ifdef CONFIG_KEYBOARD_GPIO
600 ventana_keys_init();
601#endif
602
603 ventana_usb_init();
604 ventana_gps_init();
605 ventana_panel_init();
606 ventana_sensors_init();
607 ventana_bt_rfkill();
608 ventana_emc_init();
609
610 ventana_setup_bluesleep();
611 tegra_release_bootloader_fb();
612}
613
614int __init tegra_ventana_protected_aperture_init(void)
615{
616 if (!machine_is_ventana())
617 return 0;
618
619 tegra_protected_aperture_init(tegra_grhost_aperture);
620 return 0;
621}
622late_initcall(tegra_ventana_protected_aperture_init);
623
624void __init tegra_ventana_reserve(void)
625{
626 if (memblock_reserve(0x0, 4096) < 0)
627 pr_warn("Cannot reserve first 4K of memory for safety\n");
628
629 tegra_reserve(SZ_256M, SZ_8M + SZ_1M, SZ_16M);
630 tegra_ram_console_debug_reserve(SZ_1M);
631}
632
633MACHINE_START(VENTANA, "ventana")
634 .boot_params = 0x00000100,
635 .map_io = tegra_map_common_io,
636 .reserve = tegra_ventana_reserve,
637 .init_early = tegra_init_early,
638 .init_irq = tegra_init_irq,
639 .timer = &tegra_timer,
640 .init_machine = tegra_ventana_init,
641MACHINE_END
diff --git a/arch/arm/mach-tegra/board-ventana.h b/arch/arm/mach-tegra/board-ventana.h
new file mode 100644
index 00000000000..b8d8040d187
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana.h
@@ -0,0 +1,116 @@
1/*
2 * arch/arm/mach-tegra/board-ventana.h
3 *
4 * Copyright (C) 2011 Google, Inc.
5 * Copyright (C) 2012 NVIDIA Corporation.
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#ifndef _MACH_TEGRA_BOARD_VENTANA_H
19#define _MACH_TEGRA_BOARD_VENTANA_H
20
21int ventana_charge_init(void);
22int ventana_regulator_init(void);
23int ventana_sdhci_init(void);
24int ventana_pinmux_init(void);
25int ventana_panel_init(void);
26int ventana_sensors_init(void);
27int ventana_kbc_init(void);
28int ventana_emc_init(void);
29int ventana_charger_init(void);
30int ventana_cam_fixed_voltage_regulator_init(void);
31
32/* PCA954x I2C bus expander bus addresses */
33#define PCA954x_I2C_BUS_BASE 6
34#define PCA954x_I2C_BUS0 (PCA954x_I2C_BUS_BASE + 0)
35#define PCA954x_I2C_BUS1 (PCA954x_I2C_BUS_BASE + 1)
36#define PCA954x_I2C_BUS2 (PCA954x_I2C_BUS_BASE + 2)
37
38/* Sensor gpios */
39#define ISL29018_IRQ_GPIO TEGRA_GPIO_PZ2
40#define AKM8975_IRQ_GPIO TEGRA_GPIO_PN5
41#define NCT1008_THERM2_GPIO TEGRA_GPIO_PN6
42
43#define CAMERA_POWER_GPIO TEGRA_GPIO_PV4
44#define CAMERA_CSI_MUX_SEL_GPIO TEGRA_GPIO_PBB4
45#define CAMERA_FLASH_ACT_GPIO TEGRA_GPIO_PD2
46
47#define PANEL_POWER_EN_GPIO TEGRA_GPIO_PC6
48
49/* TPS6586X gpios */
50#define TPS6586X_GPIO_BASE TEGRA_NR_GPIOS
51#define TPS6586X_GPIO(_x_) (TPS6586X_GPIO_BASE + (_x_))
52#define TPS6586X_NR_GPIOS 4
53#define AVDD_DSI_CSI_ENB_GPIO TPS6586X_GPIO(1) /* gpio2 */
54#define TPS6586X_GPIO_END TPS6586X_GPIO(TPS6586X_NR_GPIOS - 1)
55
56/* TCA6416 gpios */
57#define TCA6416_GPIO_BASE (TPS6586X_GPIO_END + 1)
58#define TCA6416_GPIO(_x_) (TCA6416_GPIO_BASE + (_x_))
59#define TCA6416_NR_GPIOS 16
60#define CAM1_PWR_DN_GPIO TCA6416_GPIO(0) /* gpio0 */
61#define CAM1_RST_L_GPIO TCA6416_GPIO(1) /* gpio1 */
62#define CAM1_AF_PWR_DN_L_GPIO TCA6416_GPIO(2) /* gpio2 */
63#define CAM1_LDO_SHUTDN_L_GPIO TCA6416_GPIO(3) /* gpio3 */
64#define CAM2_PWR_DN_GPIO TCA6416_GPIO(4) /* gpio4 */
65#define CAM2_RST_L_GPIO TCA6416_GPIO(5) /* gpio5 */
66#define CAM2_AF_PWR_DN_L_GPIO TCA6416_GPIO(6) /* gpio6 */
67#define CAM2_LDO_SHUTDN_L_GPIO TCA6416_GPIO(7) /* gpio7 */
68#define CAM3_PWR_DN_GPIO TCA6416_GPIO(8) /* gpio8 */
69#define CAM3_RST_L_GPIO TCA6416_GPIO(9) /* gpio9 */
70#define CAM3_AF_PWR_DN_L_GPIO TCA6416_GPIO(10) /* gpio10 */
71#define CAM3_LDO_SHUTDN_L_GPIO TCA6416_GPIO(11) /* gpio11 */
72#define CAM_LED_GPIO TCA6416_GPIO(12) /* gpio12 */
73#define CAM_I2C_MUX_RST_GPIO TCA6416_GPIO(15) /* gpio15 */
74#define TCA6416_GPIO_END TCA6416_GPIO(TCA6416_NR_GPIOS - 1)
75
76/* WM8903 GPIOs */
77#define WM8903_GPIO_BASE (TCA6416_GPIO_END + 1)
78#define WM8903_GPIO(_x_) (WM8903_GPIO_BASE + (_x_))
79#define WM8903_NR_GPIOS 4
80#define WM8903_GPIO_END WM8903_GPIO(WM8903_NR_GPIOS - 1)
81
82/* Audio-related GPIOs */
83#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3
84#define TEGRA_GPIO_SPKR_EN WM8903_GPIO(2)
85#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
86#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
87#define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PX0
88#define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1
89
90/* AC detect GPIO */
91#define AC_PRESENT_GPIO TEGRA_GPIO_PV3
92
93/* Interrupt numbers from external peripherals */
94#define TPS6586X_INT_BASE TEGRA_NR_IRQS
95#define TPS6586X_INT_END (TPS6586X_INT_BASE + 32)
96
97/* Invensense MPU Definitions */
98#define MPU_TYPE_MPU3050 1
99#define MPU_TYPE_MPU6050 2
100#define MPU_GYRO_TYPE MPU_TYPE_MPU3050
101#define MPU_GYRO_IRQ_GPIO TEGRA_GPIO_PZ4
102#define MPU_GYRO_ADDR 0x68
103#define MPU_GYRO_BUS_NUM 0
104#define MPU_GYRO_ORIENTATION { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
105#define MPU_ACCEL_NAME "kxtf9"
106#define MPU_ACCEL_IRQ_GPIO 0 /* Disable ACCELIRQ: TEGRA_GPIO_PN4 */
107#define MPU_ACCEL_ADDR 0x0F
108#define MPU_ACCEL_BUS_NUM 0
109#define MPU_ACCEL_ORIENTATION { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
110#define MPU_COMPASS_NAME "ak8975"
111#define MPU_COMPASS_IRQ_GPIO TEGRA_GPIO_PN5
112#define MPU_COMPASS_ADDR 0x0C
113#define MPU_COMPASS_BUS_NUM 4
114#define MPU_COMPASS_ORIENTATION { 1, 0, 0, 0, 1, 0, 0, 0, 1 }
115
116#endif
diff --git a/arch/arm/mach-tegra/board-whistler-baseband.c b/arch/arm/mach-tegra/board-whistler-baseband.c
new file mode 100644
index 00000000000..143d14a8721
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-baseband.c
@@ -0,0 +1,230 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-baseband.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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/module.h>
20#include <linux/moduleparam.h>
21#include <linux/tegra_caif.h>
22#include <mach/tegra_usb_modem_power.h>
23
24#include "board.h"
25#include "board-whistler-baseband.h"
26
27static int baseband_phy_on(void);
28static int baseband_phy_off(void);
29static void baseband_phy_restore_start(void);
30static void baseband_phy_restore_end(void);
31
32static struct wake_lock mdm_wake_lock;
33
34static struct gpio modem_gpios[] = {
35 {MODEM_PWR_ON, GPIOF_OUT_INIT_LOW, "MODEM PWR ON"},
36 {MODEM_RESET, GPIOF_IN, "MODEM RESET"},
37 {BB_RST_OUT, GPIOF_IN, "BB RST OUT"},
38 {MDM2AP_ACK, GPIOF_IN, "MDM2AP_ACK"},
39 {AP2MDM_ACK2, GPIOF_OUT_INIT_HIGH, "AP2MDM ACK2"},
40 {AP2MDM_ACK, GPIOF_OUT_INIT_LOW, "AP2MDM ACK"},
41 {ULPI_STP, GPIOF_IN, "ULPI_STP"},
42 {ULPI_DIR, GPIOF_OUT_INIT_LOW, "ULPI_DIR"},
43 {ULPI_D0, GPIOF_OUT_INIT_LOW, "ULPI_D0"},
44 {ULPI_D1, GPIOF_OUT_INIT_LOW, "ULPI_D1"},
45};
46
47static __initdata struct tegra_pingroup_config whistler_null_ulpi_pinmux[] = {
48 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL,
49 TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL,
51 TEGRA_TRI_NORMAL},
52 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL,
53 TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL,
55 TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP,
57 TEGRA_TRI_NORMAL},
58};
59
60static struct tegra_ulpi_trimmer e1219_trimmer = { 10, 1, 1, 1 };
61
62static struct tegra_ulpi_config ehci2_null_ulpi_phy_config = {
63 .trimmer = &e1219_trimmer,
64 .post_phy_on = baseband_phy_on,
65 .pre_phy_off = baseband_phy_off,
66 .phy_restore_start = baseband_phy_restore_start,
67 .phy_restore_end = baseband_phy_restore_end,
68 .phy_restore_gpio = MDM2AP_ACK,
69 .ulpi_dir_gpio = ULPI_DIR,
70 .ulpi_d0_gpio = ULPI_D0,
71 .ulpi_d1_gpio = ULPI_D1,
72};
73
74static struct tegra_ehci_platform_data ehci2_null_ulpi_platform_data = {
75 .operating_mode = TEGRA_USB_HOST,
76 .power_down_on_bus_suspend = 0,
77 .phy_config = &ehci2_null_ulpi_phy_config,
78 .phy_type = TEGRA_USB_PHY_TYPE_NULL_ULPI,
79};
80
81static int __init tegra_null_ulpi_init(void)
82{
83 tegra_ehci2_device.dev.platform_data = &ehci2_null_ulpi_platform_data;
84 platform_device_register(&tegra_ehci2_device);
85 return 0;
86}
87
88static irqreturn_t mdm_start_thread(int irq, void *data)
89{
90 if (gpio_get_value(BB_RST_OUT)) {
91 pr_info("BB_RST_OUT high\n");
92 } else {
93 pr_info("BB_RST_OUT low\n");
94 /* hold wait lock to complete the enumeration */
95 wake_lock_timeout(&mdm_wake_lock, HZ * 10);
96 }
97
98 return IRQ_HANDLED;
99}
100
101static int baseband_phy_on(void)
102{
103 static bool phy_init;
104
105 if (!phy_init) {
106 /* set AP2MDM_ACK2 low */
107 gpio_set_value(AP2MDM_ACK2, 0);
108 phy_init = true;
109 }
110 pr_info("%s\n", __func__);
111 return 0;
112}
113
114static int baseband_phy_off(void)
115{
116 pr_info("%s\n", __func__);
117 return 0;
118}
119
120static void baseband_phy_restore_start(void)
121{
122 /* set AP2MDM_ACK2 high */
123 gpio_set_value(AP2MDM_ACK2, 1);
124}
125
126static void baseband_phy_restore_end(void)
127{
128 /* set AP2MDM_ACK2 low */
129 gpio_set_value(AP2MDM_ACK2, 0);
130}
131
132static void baseband_start(void)
133{
134 /*
135 * Leave baseband powered OFF.
136 * User-space daemons will take care of powering it up.
137 */
138 pr_info("%s\n", __func__);
139 gpio_set_value(MODEM_PWR_ON, 0);
140}
141
142static void baseband_reset(void)
143{
144 /* Initiate power cycle on baseband sub system */
145 pr_info("%s\n", __func__);
146 gpio_set_value(MODEM_PWR_ON, 0);
147 mdelay(200);
148 gpio_set_value(MODEM_PWR_ON, 1);
149}
150
151static int baseband_init(void)
152{
153 int irq;
154 int ret;
155
156 ret = gpio_request_array(modem_gpios, ARRAY_SIZE(modem_gpios));
157 if (ret)
158 return ret;
159
160 /* enable pull-up for BB_RST_OUT */
161 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_UAC,
162 TEGRA_PUPD_PULL_UP);
163
164 tegra_gpio_enable(MODEM_PWR_ON);
165 tegra_gpio_enable(MODEM_RESET);
166 tegra_gpio_enable(AP2MDM_ACK2);
167 tegra_gpio_enable(BB_RST_OUT);
168 tegra_gpio_enable(AP2MDM_ACK);
169 tegra_gpio_enable(MDM2AP_ACK);
170 tegra_gpio_enable(TEGRA_GPIO_PY3);
171 tegra_gpio_enable(TEGRA_GPIO_PY1);
172 tegra_gpio_enable(TEGRA_GPIO_PO1);
173 tegra_gpio_enable(TEGRA_GPIO_PO2);
174
175 /* export GPIO for user space access through sysfs */
176 gpio_export(MODEM_PWR_ON, false);
177
178 /* phy init */
179 tegra_null_ulpi_init();
180
181 wake_lock_init(&mdm_wake_lock, WAKE_LOCK_SUSPEND, "mdm_lock");
182
183 /* enable IRQ for BB_RST_OUT */
184 irq = gpio_to_irq(BB_RST_OUT);
185
186 ret = request_threaded_irq(irq, NULL, mdm_start_thread,
187 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
188 "mdm_start", NULL);
189 if (ret < 0) {
190 pr_err("%s: request_threaded_irq error\n", __func__);
191 return ret;
192 }
193
194 ret = enable_irq_wake(irq);
195 if (ret) {
196 pr_err("%s: enable_irq_wake error\n", __func__);
197 free_irq(irq, NULL);
198 return ret;
199 }
200
201 return 0;
202}
203
204static const struct tegra_modem_operations baseband_operations = {
205 .init = baseband_init,
206 .start = baseband_start,
207 .reset = baseband_reset,
208};
209
210static struct tegra_usb_modem_power_platform_data baseband_pdata = {
211 .ops = &baseband_operations,
212 .wake_gpio = MDM2AP_ACK2,
213 .flags = IRQF_TRIGGER_FALLING,
214};
215
216static struct platform_device icera_baseband_device = {
217 .name = "tegra_usb_modem_power",
218 .id = -1,
219 .dev = {
220 .platform_data = &baseband_pdata,
221 },
222};
223
224int __init whistler_baseband_init(void)
225{
226 tegra_pinmux_config_table(whistler_null_ulpi_pinmux,
227 ARRAY_SIZE(whistler_null_ulpi_pinmux));
228 platform_device_register(&icera_baseband_device);
229 return 0;
230}
diff --git a/arch/arm/mach-tegra/board-whistler-baseband.h b/arch/arm/mach-tegra/board-whistler-baseband.h
new file mode 100644
index 00000000000..aceef6cd967
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-baseband.h
@@ -0,0 +1,81 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-baseband.h
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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 BOARD_WHISTLER_BASEBAND_H
18#define BOARD_WHISTLER_BASEBAND_H
19
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/spi/spi.h>
23#include <linux/platform_data/tegra_usb.h>
24#include <mach/usb_phy.h>
25#include <linux/resource.h>
26#include <linux/platform_device.h>
27#include <linux/err.h>
28#include <linux/interrupt.h>
29#include <linux/irq.h>
30#include <linux/wakelock.h>
31#include <asm/mach-types.h>
32#include <mach/pinmux.h>
33#include <mach/spi.h>
34#include "clock.h"
35#include "devices.h"
36#include "gpio-names.h"
37
38#define BOARD_WHISTLER_BASEBAND_U3XX 0
39#define BOARD_WHISTLER_BASEBAND_N731 1
40#define BOARD_WHISTLER_BASEBAND_SPI_LOOPBACK 2
41#define BOARD_WHISTLER_BASEBAND_HSIC 3
42
43#define TEGRA_CAIF_SSPI_GPIO_RESET TEGRA_GPIO_PV0
44#define TEGRA_CAIF_SSPI_GPIO_POWER TEGRA_GPIO_PV1
45#define TEGRA_CAIF_SSPI_GPIO_AWR TEGRA_GPIO_PZ0
46#define TEGRA_CAIF_SSPI_GPIO_CWR TEGRA_GPIO_PY6
47#define TEGRA_CAIF_SSPI_GPIO_SPI_INT TEGRA_GPIO_PO6
48#define TEGRA_CAIF_SSPI_GPIO_SS TEGRA_GPIO_PV2
49
50#define MODEM_PWR_ON TEGRA_GPIO_PV1
51#define MODEM_RESET TEGRA_GPIO_PV0
52
53/* Rainbow1 and 570 */
54#define AWR TEGRA_GPIO_PZ0
55#define CWR TEGRA_GPIO_PY6
56#define SPI_INT TEGRA_GPIO_PO6
57#define SPI_SLAVE_SEL TEGRA_GPIO_PV2
58
59/* Icera 450 GPIO */
60#define AP2MDM_ACK TEGRA_GPIO_PZ0
61#define MDM2AP_ACK TEGRA_GPIO_PY6
62#define AP2MDM_ACK2 TEGRA_GPIO_PU2
63#define MDM2AP_ACK2 TEGRA_GPIO_PV2
64#define BB_RST_OUT TEGRA_GPIO_PV3
65
66/* ULPI GPIO */
67#define ULPI_STP TEGRA_GPIO_PY3
68#define ULPI_DIR TEGRA_GPIO_PY1
69#define ULPI_D0 TEGRA_GPIO_PO1
70#define ULPI_D1 TEGRA_GPIO_PO2
71
72struct whistler_baseband {
73 struct tegra_clk_init_table *clk_init;
74 struct platform_device **platform_device;
75 int platform_device_size;
76 struct spi_board_info *spi_board_info;
77 int spi_board_info_size;
78};
79
80int whistler_baseband_init(void);
81#endif /* BOARD_WHISTLER_BASEBAND_H */
diff --git a/arch/arm/mach-tegra/board-whistler-kbc.c b/arch/arm/mach-tegra/board-whistler-kbc.c
new file mode 100644
index 00000000000..0dbcbbcdc31
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-kbc.c
@@ -0,0 +1,138 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19
20#include <linux/kernel.h>
21#include <linux/platform_device.h>
22#include <linux/input.h>
23#include <linux/device.h>
24
25#include <mach/clk.h>
26#include <mach/iomap.h>
27#include <mach/irqs.h>
28#include <mach/pinmux.h>
29#include <mach/iomap.h>
30#include <mach/io.h>
31#include <mach/kbc.h>
32
33#include <asm/mach-types.h>
34#include <asm/mach/arch.h>
35
36/*
37* Scrollwheel is connected to KBC pins but has it's own
38* driver using those pins as gpio.
39* In case of using scrollwheel Row3 and Col3/4/5
40* should NOT be configured as KBC
41*/
42#ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
43#define WHISTLER_ROW_COUNT 3
44#define WHISTLER_COL_COUNT 2
45#else
46#define WHISTLER_ROW_COUNT 4
47#define WHISTLER_COL_COUNT 2
48#endif
49
50#ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
51static const u32 whistler_keymap[] = {
52 KEY(0, 0, KEY_POWER),
53 KEY(0, 1, KEY_RESERVED),
54 KEY(1, 0, KEY_HOME),
55 KEY(1, 1, KEY_BACK),
56 KEY(2, 0, KEY_RESERVED),
57 KEY(2, 1, KEY_MENU),
58};
59#else
60static const u32 whistler_keymap[] = {
61 KEY(0, 0, KEY_POWER),
62 KEY(0, 1, KEY_RESERVED),
63 KEY(1, 0, KEY_HOME),
64 KEY(1, 1, KEY_BACK),
65 KEY(2, 0, KEY_RESERVED),
66 KEY(2, 1, KEY_MENU),
67 KEY(3, 0, KEY_RESERVED),
68 KEY(3, 1, KEY_RESERVED),
69};
70#endif
71
72static const struct matrix_keymap_data whistler_keymap_data = {
73 .keymap = whistler_keymap,
74 .keymap_size = ARRAY_SIZE(whistler_keymap),
75};
76
77static struct tegra_kbc_wake_key whistler_wake_cfg[] = {
78 [0] = {
79 .row = 0,
80 .col = 0,
81 },
82};
83
84static struct tegra_kbc_platform_data whistler_kbc_platform_data = {
85 .debounce_cnt = 20,
86 .repeat_cnt = 50 * 32,
87 .wake_cnt = 1,
88 .wake_cfg = &whistler_wake_cfg[0],
89 .keymap_data = &whistler_keymap_data,
90 .use_fn_map = false,
91 .wakeup = true,
92#ifdef CONFIG_ANDROID
93 .disable_ev_rep = true,
94#endif
95};
96
97static struct resource whistler_kbc_resources[] = {
98 [0] = {
99 .start = TEGRA_KBC_BASE,
100 .end = TEGRA_KBC_BASE + TEGRA_KBC_SIZE - 1,
101 .flags = IORESOURCE_MEM,
102 },
103 [1] = {
104 .start = INT_KBC,
105 .end = INT_KBC,
106 .flags = IORESOURCE_IRQ,
107 },
108};
109
110struct platform_device whistler_kbc_device = {
111 .name = "tegra-kbc",
112 .id = -1,
113 .dev = {
114 .platform_data = &whistler_kbc_platform_data,
115 },
116 .resource = whistler_kbc_resources,
117 .num_resources = ARRAY_SIZE(whistler_kbc_resources),
118};
119
120int __init whistler_kbc_init(void)
121{
122 struct tegra_kbc_platform_data *data = &whistler_kbc_platform_data;
123 int i;
124
125 pr_info("KBC: whistler_kbc_init\n");
126 for (i = 0; i < WHISTLER_ROW_COUNT; i++) {
127 data->pin_cfg[i].num = i;
128 data->pin_cfg[i].is_row = true;
129 data->pin_cfg[i].en = true;
130 }
131 for (i = 0; i < WHISTLER_COL_COUNT; i++) {
132 data->pin_cfg[i + KBC_PIN_GPIO_16].num = i;
133 data->pin_cfg[i + KBC_PIN_GPIO_16].en = true;
134 }
135
136 platform_device_register(&whistler_kbc_device);
137 return 0;
138}
diff --git a/arch/arm/mach-tegra/board-whistler-memory.c b/arch/arm/mach-tegra/board-whistler-memory.c
new file mode 100644
index 00000000000..8dd4c8fe225
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-memory.c
@@ -0,0 +1,632 @@
1/*
2 * Copyright (C) 2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22#include "board-whistler.h"
23#include "tegra2_emc.h"
24#include "board.h"
25#include "fuse.h"
26
27static const struct tegra_emc_table whistler_emc_tables_elpida_300Mhz[] = {
28 {
29 .rate = 25000, /* SDRAM frquency */
30 .regs = {
31 0x00000002, /* RC */
32 0x00000006, /* RFC */
33 0x00000003, /* RAS */
34 0x00000003, /* RP */
35 0x00000006, /* R2W */
36 0x00000004, /* W2R */
37 0x00000002, /* R2P */
38 0x00000009, /* W2P */
39 0x00000003, /* RD_RCD */
40 0x00000003, /* WR_RCD */
41 0x00000002, /* RRD */
42 0x00000002, /* REXT */
43 0x00000002, /* WDV */
44 0x00000004, /* QUSE */
45 0x00000003, /* QRST */
46 0x00000008, /* QSAFE */
47 0x0000000b, /* RDV */
48 0x0000004d, /* REFRESH */
49 0x00000000, /* BURST_REFRESH_NUM */
50 0x00000003, /* PDEX2WR */
51 0x00000003, /* PDEX2RD */
52 0x00000003, /* PCHG2PDEN */
53 0x00000008, /* ACT2PDEN */
54 0x00000001, /* AR2PDEN */
55 0x0000000a, /* RW2PDEN */
56 0x00000004, /* TXSR */
57 0x00000003, /* TCKE */
58 0x00000008, /* TFAW */
59 0x00000004, /* TRPAB */
60 0x00000006, /* TCLKSTABLE */
61 0x00000002, /* TCLKSTOP */
62 0x00000068, /* TREFBW */
63 0x00000000, /* QUSE_EXTRA */
64 0x00000003, /* FBIO_CFG6 */
65 0x00000000, /* ODT_WRITE */
66 0x00000000, /* ODT_READ */
67 0x00000282, /* FBIO_CFG5 */
68 0xa06a04ae, /* CFG_DIG_DLL */
69 0x0001f000, /* DLL_XFORM_DQS */
70 0x00000000, /* DLL_XFORM_QUSE */
71 0x00000000, /* ZCAL_REF_CNT */
72 0x00000003, /* ZCAL_WAIT_CNT */
73 0x00000000, /* AUTO_CAL_INTERVAL */
74 0x00000000, /* CFG_CLKTRIM_0 */
75 0x00000000, /* CFG_CLKTRIM_1 */
76 0x00000000, /* CFG_CLKTRIM_2 */
77 }
78 },
79 {
80 .rate = 50000, /* SDRAM frequency */
81 .regs = {
82 0x00000003, /* RC */
83 0x00000007, /* RFC */
84 0x00000003, /* RAS */
85 0x00000003, /* RP */
86 0x00000006, /* R2W */
87 0x00000004, /* W2R */
88 0x00000002, /* R2P */
89 0x00000009, /* W2P */
90 0x00000003, /* RD_RCD */
91 0x00000003, /* WR_RCD */
92 0x00000002, /* RRD */
93 0x00000002, /* REXT */
94 0x00000002, /* WDV */
95 0x00000005, /* QUSE */
96 0x00000003, /* QRST */
97 0x00000008, /* QSAFE */
98 0x0000000b, /* RDV */
99 0x0000009f, /* REFRESH */
100 0x00000000, /* BURST_REFRESH_NUM */
101 0x00000003, /* PDEX2WR */
102 0x00000003, /* PDEX2RD */
103 0x00000003, /* PCHG2PDEN */
104 0x00000008, /* ACT2PDEN */
105 0x00000001, /* AR2PDEN */
106 0x0000000a, /* RW2PDEN */
107 0x00000007, /* TXSR */
108 0x00000003, /* TCKE */
109 0x00000008, /* TFAW */
110 0x00000004, /* TRPAB */
111 0x00000006, /* TCLKSTABLE */
112 0x00000002, /* TCLKSTOP */
113 0x000000d0, /* TREFBW */
114 0x00000000, /* QUSE_EXTRA */
115 0x00000000, /* FBIO_CFG6 */
116 0x00000000, /* ODT_WRITE */
117 0x00000000, /* ODT_READ */
118 0x00000282, /* FBIO_CFG5 */
119 0xa06a04ae, /* CFG_DIG_DLL */
120 0x0001f000, /* DLL_XFORM_DQS */
121 0x00000000, /* DLL_XFORM_QUSE */
122 0x00000000, /* ZCAL_REF_CNT */
123 0x00000005, /* ZCAL_WAIT_CNT */
124 0x00000000, /* AUTO_CAL_INTERVAL */
125 0x00000000, /* CFG_CLKTRIM_0 */
126 0x00000000, /* CFG_CLKTRIM_1 */
127 0x00000000, /* CFG_CLKTRIM_2 */
128 }
129 },
130 {
131 .rate = 75000, /* SDRAM frequency */
132 .regs = {
133 0x00000005, /* RC */
134 0x0000000a, /* RFC */
135 0x00000004, /* RAS */
136 0x00000003, /* RP */
137 0x00000006, /* R2W */
138 0x00000004, /* W2R */
139 0x00000002, /* R2P */
140 0x00000009, /* W2P */
141 0x00000003, /* RD_RCD */
142 0x00000003, /* WR_RCD */
143 0x00000002, /* RRD */
144 0x00000002, /* REXT */
145 0x00000002, /* WDV */
146 0x00000005, /* QUSE */
147 0x00000003, /* QRST */
148 0x00000008, /* QSAFE */
149 0x0000000b, /* RDV */
150 0x000000ff, /* REFRESH */
151 0x00000000, /* BURST_REFRESH_NUM */
152 0x00000003, /* PDEX2WR */
153 0x00000003, /* PDEX2RD */
154 0x00000003, /* PCHG2PDEN */
155 0x00000008, /* ACT2PDEN */
156 0x00000001, /* AR2PDEN */
157 0x0000000a, /* RW2PDEN */
158 0x0000000b, /* TXSR */
159 0x00000003, /* TCKE */
160 0x00000008, /* TFAW */
161 0x00000004, /* TRPAB */
162 0x00000006, /* TCLKSTABLE */
163 0x00000002, /* TCLKSTOP */
164 0x00000138, /* TREFBW */
165 0x00000000, /* QUSE_EXTRA */
166 0x00000000, /* FBIO_CFG6 */
167 0x00000000, /* ODT_WRITE */
168 0x00000000, /* ODT_READ */
169 0x00000282, /* FBIO_CFG5 */
170 0xa06a04ae, /* CFG_DIG_DLL */
171 0x0001f000, /* DLL_XFORM_DQS */
172 0x00000000, /* DLL_XFORM_QUSE */
173 0x00000000, /* ZCAL_REF_CNT */
174 0x00000007, /* ZCAL_WAIT_CNT */
175 0x00000000, /* AUTO_CAL_INTERVAL */
176 0x00000000, /* CFG_CLKTRIM_0 */
177 0x00000000, /* CFG_CLKTRIM_1 */
178 0x00000000, /* CFG_CLKTRIM_2 */
179 }
180 },
181 {
182 .rate = 150000, /* SDRAM frequency */
183 .regs = {
184 0x00000009, /* RC */
185 0x00000014, /* RFC */
186 0x00000007, /* RAS */
187 0x00000004, /* RP */
188 0x00000006, /* R2W */
189 0x00000004, /* W2R */
190 0x00000002, /* R2P */
191 0x00000009, /* W2P */
192 0x00000003, /* RD_RCD */
193 0x00000003, /* WR_RCD */
194 0x00000002, /* RRD */
195 0x00000002, /* REXT */
196 0x00000002, /* WDV */
197 0x00000005, /* QUSE */
198 0x00000003, /* QRST */
199 0x00000008, /* QSAFE */
200 0x0000000b, /* RDV */
201 0x0000021f, /* REFRESH */
202 0x00000000, /* BURST_REFRESH_NUM */
203 0x00000003, /* PDEX2WR */
204 0x00000003, /* PDEX2RD */
205 0x00000004, /* PCHG2PDEN */
206 0x00000008, /* ACT2PDEN */
207 0x00000001, /* AR2PDEN */
208 0x0000000a, /* RW2PDEN */
209 0x00000015, /* TXSR */
210 0x00000003, /* TCKE */
211 0x00000008, /* TFAW */
212 0x00000004, /* TRPAB */
213 0x00000006, /* TCLKSTABLE */
214 0x00000002, /* TCLKSTOP */
215 0x00000270, /* TREFBW */
216 0x00000000, /* QUSE_EXTRA */
217 0x00000001, /* FBIO_CFG6 */
218 0x00000000, /* ODT_WRITE */
219 0x00000000, /* ODT_READ */
220 0x00000282, /* FBIO_CFG5 */
221 0xA04C04AE, /* CFG_DIG_DLL */
222 0x007FC010, /* DLL_XFORM_DQS */
223 0x00000000, /* DLL_XFORM_QUSE */
224 0x00000000, /* ZCAL_REF_CNT */
225 0x0000000e, /* ZCAL_WAIT_CNT */
226 0x00000000, /* AUTO_CAL_INTERVAL */
227 0x00000000, /* CFG_CLKTRIM_0 */
228 0x00000000, /* CFG_CLKTRIM_1 */
229 0x00000000, /* CFG_CLKTRIM_2 */
230 }
231 },
232 {
233 .rate = 300000, /* SDRAM frequency */
234 .regs = {
235 0x00000012, /* RC */
236 0x00000027, /* RFC */
237 0x0000000D, /* RAS */
238 0x00000007, /* RP */
239 0x00000007, /* R2W */
240 0x00000005, /* W2R */
241 0x00000003, /* R2P */
242 0x00000009, /* W2P */
243 0x00000006, /* RD_RCD */
244 0x00000006, /* WR_RCD */
245 0x00000003, /* RRD */
246 0x00000003, /* REXT */
247 0x00000002, /* WDV */
248 0x00000006, /* QUSE */
249 0x00000003, /* QRST */
250 0x00000009, /* QSAFE */
251 0x0000000c, /* RDV */
252 0x0000045f, /* REFRESH */
253 0x00000000, /* BURST_REFRESH_NUM */
254 0x00000004, /* PDEX2WR */
255 0x00000004, /* PDEX2RD */
256 0x00000007, /* PCHG2PDEN */
257 0x00000008, /* ACT2PDEN */
258 0x00000001, /* AR2PDEN */
259 0x0000000e, /* RW2PDEN */
260 0x0000002A, /* TXSR */
261 0x00000003, /* TCKE */
262 0x0000000F, /* TFAW */
263 0x00000008, /* TRPAB */
264 0x00000005, /* TCLKSTABLE */
265 0x00000002, /* TCLKSTOP */
266 0x000004E1, /* TREFBW */
267 0x00000005, /* QUSE_EXTRA */
268 0x00000002, /* FBIO_CFG6 */
269 0x00000000, /* ODT_WRITE */
270 0x00000000, /* ODT_READ */
271 0x00000282, /* FBIO_CFG5 */
272 0xE03C048B, /* CFG_DIG_DLL */
273 0x007FC010, /* DLL_XFORM_DQS */
274 0x00000000, /* DLL_XFORM_QUSE */
275 0x00000000, /* ZCAL_REF_CNT */
276 0x0000001B, /* ZCAL_WAIT_CNT */
277 0x00000000, /* AUTO_CAL_INTERVAL */
278 0x00000000, /* CFG_CLKTRIM_0 */
279 0x00000000, /* CFG_CLKTRIM_1 */
280 0x00000000, /* CFG_CLKTRIM_2 */
281 }
282 }
283};
284
285static const struct tegra_emc_table whistler_emc_tables_elpida_380Mhz[] = {
286 {
287 .rate = 23750, /* SDRAM frquency */
288 .regs = {
289 0x00000002, /* RC */
290 0x00000006, /* RFC */
291 0x00000003, /* RAS */
292 0x00000003, /* RP */
293 0x00000006, /* R2W */
294 0x00000004, /* W2R */
295 0x00000002, /* R2P */
296 0x0000000b, /* W2P */
297 0x00000003, /* RD_RCD */
298 0x00000003, /* WR_RCD */
299 0x00000002, /* RRD */
300 0x00000002, /* REXT */
301 0x00000003, /* WDV */
302 0x00000005, /* QUSE */
303 0x00000004, /* QRST */
304 0x00000008, /* QSAFE */
305 0x0000000c, /* RDV */
306 0x00000047, /* REFRESH */
307 0x00000000, /* BURST_REFRESH_NUM */
308 0x00000003, /* PDEX2WR */
309 0x00000003, /* PDEX2RD */
310 0x00000003, /* PCHG2PDEN */
311 0x00000008, /* ACT2PDEN */
312 0x00000001, /* AR2PDEN */
313 0x0000000b, /* RW2PDEN */
314 0x00000004, /* TXSR */
315 0x00000003, /* TCKE */
316 0x00000008, /* TFAW */
317 0x00000004, /* TRPAB */
318 0x00000008, /* TCLKSTABLE */
319 0x00000002, /* TCLKSTOP */
320 0x00000060, /* TREFBW */
321 0x00000000, /* QUSE_EXTRA */
322 0x00000003, /* FBIO_CFG6 */
323 0x00000000, /* ODT_WRITE */
324 0x00000000, /* ODT_READ */
325 0x00000282, /* FBIO_CFG5 */
326 0xa0ae04ae, /* CFG_DIG_DLL */
327 0x0001f800, /* DLL_XFORM_DQS */
328 0x00000000, /* DLL_XFORM_QUSE */
329 0x00000000, /* ZCAL_REF_CNT */
330 0x00000003, /* ZCAL_WAIT_CNT */
331 0x00000000, /* AUTO_CAL_INTERVAL */
332 0x00000000, /* CFG_CLKTRIM_0 */
333 0x00000000, /* CFG_CLKTRIM_1 */
334 0x00000000, /* CFG_CLKTRIM_2 */
335 }
336 },
337 {
338 .rate = 63334, /* SDRAM frquency */
339 .regs = {
340 0x00000004, /* RC */
341 0x00000009, /* RFC */
342 0x00000003, /* RAS */
343 0x00000003, /* RP */
344 0x00000006, /* R2W */
345 0x00000004, /* W2R */
346 0x00000002, /* R2P */
347 0x0000000b, /* W2P */
348 0x00000003, /* RD_RCD */
349 0x00000003, /* WR_RCD */
350 0x00000002, /* RRD */
351 0x00000002, /* REXT */
352 0x00000003, /* WDV */
353 0x00000006, /* QUSE */
354 0x00000004, /* QRST */
355 0x00000008, /* QSAFE */
356 0x0000000c, /* RDV */
357 0x000000c4, /* REFRESH */
358 0x00000000, /* BURST_REFRESH_NUM */
359 0x00000003, /* PDEX2WR */
360 0x00000003, /* PDEX2RD */
361 0x00000003, /* PCHG2PDEN */
362 0x00000008, /* ACT2PDEN */
363 0x00000001, /* AR2PDEN */
364 0x0000000b, /* RW2PDEN */
365 0x00000009, /* TXSR */
366 0x00000003, /* TCKE */
367 0x00000008, /* TFAW */
368 0x00000004, /* TRPAB */
369 0x00000008, /* TCLKSTABLE */
370 0x00000002, /* TCLKSTOP */
371 0x00000107, /* TREFBW */
372 0x00000000, /* QUSE_EXTRA */
373 0x00000000, /* FBIO_CFG6 */
374 0x00000000, /* ODT_WRITE */
375 0x00000000, /* ODT_READ */
376 0x00000282, /* FBIO_CFG5 */
377 0xa0ae04ae, /* CFG_DIG_DLL */
378 0x0001f800, /* DLL_XFORM_DQS */
379 0x00000000, /* DLL_XFORM_QUSE */
380 0x00000000, /* ZCAL_REF_CNT */
381 0x00000006, /* ZCAL_WAIT_CNT */
382 0x00000000, /* AUTO_CAL_INTERVAL */
383 0x00000000, /* CFG_CLKTRIM_0 */
384 0x00000000, /* CFG_CLKTRIM_1 */
385 0x00000000, /* CFG_CLKTRIM_2 */
386 }
387 },
388 {
389 .rate = 95000, /* SDRAM frquency */
390 .regs = {
391 0x00000006, /* RC */
392 0x0000000d, /* RFC */
393 0x00000004, /* RAS */
394 0x00000003, /* RP */
395 0x00000006, /* R2W */
396 0x00000004, /* W2R */
397 0x00000002, /* R2P */
398 0x0000000b, /* W2P */
399 0x00000003, /* RD_RCD */
400 0x00000003, /* WR_RCD */
401 0x00000002, /* RRD */
402 0x00000002, /* REXT */
403 0x00000003, /* WDV */
404 0x00000006, /* QUSE */
405 0x00000004, /* QRST */
406 0x00000008, /* QSAFE */
407 0x0000000c, /* RDV */
408 0x0000013f, /* REFRESH */
409 0x00000000, /* BURST_REFRESH_NUM */
410 0x00000003, /* PDEX2WR */
411 0x00000003, /* PDEX2RD */
412 0x00000003, /* PCHG2PDEN */
413 0x00000008, /* ACT2PDEN */
414 0x00000001, /* AR2PDEN */
415 0x0000000b, /* RW2PDEN */
416 0x0000000e, /* TXSR */
417 0x00000003, /* TCKE */
418 0x00000008, /* TFAW */
419 0x00000004, /* TRPAB */
420 0x00000008, /* TCLKSTABLE */
421 0x00000002, /* TCLKSTOP */
422 0x0000018c, /* TREFBW */
423 0x00000000, /* QUSE_EXTRA */
424 0x00000001, /* FBIO_CFG6 */
425 0x00000000, /* ODT_WRITE */
426 0x00000000, /* ODT_READ */
427 0x00000282, /* FBIO_CFG5 */
428 0xa0ae04ae, /* CFG_DIG_DLL */
429 0x0001f000, /* DLL_XFORM_DQS */
430 0x00000000, /* DLL_XFORM_QUSE */
431 0x00000000, /* ZCAL_REF_CNT */
432 0x00000009, /* ZCAL_WAIT_CNT */
433 0x00000000, /* AUTO_CAL_INTERVAL */
434 0x00000000, /* CFG_CLKTRIM_0 */
435 0x00000000, /* CFG_CLKTRIM_1 */
436 0x00000000, /* CFG_CLKTRIM_2 */
437 }
438 },
439 {
440 .rate = 190000, /* SDRAM frquency */
441 .regs = {
442 0x0000000c, /* RC */
443 0x00000019, /* RFC */
444 0x00000008, /* RAS */
445 0x00000004, /* RP */
446 0x00000007, /* R2W */
447 0x00000004, /* W2R */
448 0x00000002, /* R2P */
449 0x0000000b, /* W2P */
450 0x00000004, /* RD_RCD */
451 0x00000004, /* WR_RCD */
452 0x00000002, /* RRD */
453 0x00000003, /* REXT */
454 0x00000003, /* WDV */
455 0x00000006, /* QUSE */
456 0x00000004, /* QRST */
457 0x00000009, /* QSAFE */
458 0x0000000d, /* RDV */
459 0x000002bf, /* REFRESH */
460 0x00000000, /* BURST_REFRESH_NUM */
461 0x00000003, /* PDEX2WR */
462 0x00000003, /* PDEX2RD */
463 0x00000004, /* PCHG2PDEN */
464 0x00000008, /* ACT2PDEN */
465 0x00000001, /* AR2PDEN */
466 0x0000000c, /* RW2PDEN */
467 0x0000001b, /* TXSR */
468 0x00000003, /* TCKE */
469 0x0000000a, /* TFAW */
470 0x00000004, /* TRPAB */
471 0x00000008, /* TCLKSTABLE */
472 0x00000002, /* TCLKSTOP */
473 0x00000317, /* TREFBW */
474 0x00000000, /* QUSE_EXTRA */
475 0x00000002, /* FBIO_CFG6 */
476 0x00000000, /* ODT_WRITE */
477 0x00000000, /* ODT_READ */
478 0x00000282, /* FBIO_CFG5 */
479 0xa06204ae, /* CFG_DIG_DLL */
480 0x007f7010, /* DLL_XFORM_DQS */
481 0x00000000, /* DLL_XFORM_QUSE */
482 0x00000000, /* ZCAL_REF_CNT */
483 0x00000012, /* ZCAL_WAIT_CNT */
484 0x00000000, /* AUTO_CAL_INTERVAL */
485 0x00000000, /* CFG_CLKTRIM_0 */
486 0x00000000, /* CFG_CLKTRIM_1 */
487 0x00000000, /* CFG_CLKTRIM_2 */
488 }
489 },
490 {
491 .rate = 300000, /* SDRAM frquency */
492 .regs = {
493 0x00000012, /* RC */
494 0x00000027, /* RFC */
495 0x0000000d, /* RAS */
496 0x00000006, /* RP */
497 0x00000007, /* R2W */
498 0x00000005, /* W2R */
499 0x00000003, /* R2P */
500 0x0000000b, /* W2P */
501 0x00000006, /* RD_RCD */
502 0x00000006, /* WR_RCD */
503 0x00000003, /* RRD */
504 0x00000003, /* REXT */
505 0x00000003, /* WDV */
506 0x00000007, /* QUSE */
507 0x00000004, /* QRST */
508 0x00000009, /* QSAFE */
509 0x0000000d, /* RDV */
510 0x0000045f, /* REFRESH */
511 0x00000000, /* BURST_REFRESH_NUM */
512 0x00000004, /* PDEX2WR */
513 0x00000004, /* PDEX2RD */
514 0x00000006, /* PCHG2PDEN */
515 0x00000008, /* ACT2PDEN */
516 0x00000001, /* AR2PDEN */
517 0x0000000f, /* RW2PDEN */
518 0x0000002a, /* TXSR */
519 0x00000003, /* TCKE */
520 0x0000000f, /* TFAW */
521 0x00000007, /* TRPAB */
522 0x00000007, /* TCLKSTABLE */
523 0x00000002, /* TCLKSTOP */
524 0x000004e0, /* TREFBW */
525 0x00000006, /* QUSE_EXTRA */
526 0x00000002, /* FBIO_CFG6 */
527 0x00000000, /* ODT_WRITE */
528 0x00000000, /* ODT_READ */
529 0x00000282, /* FBIO_CFG5 */
530 0xe05e048b, /* CFG_DIG_DLL */
531 0x007f2010, /* DLL_XFORM_DQS */
532 0x00000000, /* DLL_XFORM_QUSE */
533 0x00000000, /* ZCAL_REF_CNT */
534 0x0000001b, /* ZCAL_WAIT_CNT */
535 0x00000000, /* AUTO_CAL_INTERVAL */
536 0x00000000, /* CFG_CLKTRIM_0 */
537 0x00000000, /* CFG_CLKTRIM_1 */
538 0x00000000, /* CFG_CLKTRIM_2 */
539 }
540 },
541 {
542 .rate = 380000, /* SDRAM frquency */
543 .regs = {
544 0x00000017, /* RC */
545 0x00000032, /* RFC */
546 0x00000010, /* RAS */
547 0x00000007, /* RP */
548 0x00000008, /* R2W */
549 0x00000005, /* W2R */
550 0x00000003, /* R2P */
551 0x0000000b, /* W2P */
552 0x00000007, /* RD_RCD */
553 0x00000007, /* WR_RCD */
554 0x00000004, /* RRD */
555 0x00000003, /* REXT */
556 0x00000003, /* WDV */
557 0x00000007, /* QUSE */
558 0x00000004, /* QRST */
559 0x0000000a, /* QSAFE */
560 0x0000000e, /* RDV */
561 0x0000059f, /* REFRESH */
562 0x00000000, /* BURST_REFRESH_NUM */
563 0x00000004, /* PDEX2WR */
564 0x00000004, /* PDEX2RD */
565 0x00000007, /* PCHG2PDEN */
566 0x00000008, /* ACT2PDEN */
567 0x00000001, /* AR2PDEN */
568 0x00000011, /* RW2PDEN */
569 0x00000036, /* TXSR */
570 0x00000003, /* TCKE */
571 0x00000013, /* TFAW */
572 0x00000008, /* TRPAB */
573 0x00000007, /* TCLKSTABLE */
574 0x00000002, /* TCLKSTOP */
575 0x0000062d, /* TREFBW */
576 0x00000006, /* QUSE_EXTRA */
577 0x00000003, /* FBIO_CFG6 */
578 0x00000000, /* ODT_WRITE */
579 0x00000000, /* ODT_READ */
580 0x00000282, /* FBIO_CFG5 */
581 0xe044048b, /* CFG_DIG_DLL */
582 0x007fb010, /* DLL_XFORM_DQS */
583 0x00000000, /* DLL_XFORM_QUSE */
584 0x00000000, /* ZCAL_REF_CNT */
585 0x00000023, /* ZCAL_WAIT_CNT */
586 0x00000000, /* AUTO_CAL_INTERVAL */
587 0x00000000, /* CFG_CLKTRIM_0 */
588 0x00000000, /* CFG_CLKTRIM_1 */
589 0x00000000, /* CFG_CLKTRIM_2 */
590 }
591 }
592};
593
594static const struct tegra_emc_chip whistler_emc_chips[] = {
595 {
596 .description = "Elpida 300MHz",
597 .mem_manufacturer_id = 0x0303,
598 .mem_revision_id1 = -1,
599 .mem_revision_id2 = -1,
600 .mem_pid = -1,
601 .table = whistler_emc_tables_elpida_300Mhz,
602 .table_size = ARRAY_SIZE(whistler_emc_tables_elpida_300Mhz)
603 },
604};
605
606static const struct tegra_emc_chip whistler_ap25_emc_chips[] = {
607 {
608 .description = "Elpida 380MHz",
609 .mem_manufacturer_id = 0x0303,
610 .mem_revision_id1 = -1,
611 .mem_revision_id2 = -1,
612 .mem_pid = -1,
613 .table = whistler_emc_tables_elpida_380Mhz,
614 .table_size = ARRAY_SIZE(whistler_emc_tables_elpida_380Mhz)
615 },
616};
617
618#define TEGRA25_SKU 0x17
619
620int __init whistler_emc_init(void)
621{
622 int sku_id = tegra_sku_id();
623
624 if (sku_id == TEGRA25_SKU)
625 tegra_init_emc(whistler_ap25_emc_chips,
626 ARRAY_SIZE(whistler_ap25_emc_chips));
627 else
628 tegra_init_emc(whistler_emc_chips,
629 ARRAY_SIZE(whistler_emc_chips));
630
631 return 0;
632}
diff --git a/arch/arm/mach-tegra/board-whistler-panel.c b/arch/arm/mach-tegra/board-whistler-panel.c
new file mode 100644
index 00000000000..74075d4659c
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-panel.c
@@ -0,0 +1,401 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-panel.c
3 *
4 * Copyright (c) 2010-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/resource.h>
25#include <asm/mach-types.h>
26#include <linux/platform_device.h>
27#include <linux/earlysuspend.h>
28#include <linux/kernel.h>
29#include <linux/pwm_backlight.h>
30#include <linux/tegra_pwm_bl.h>
31#include <linux/nvhost.h>
32#include <mach/nvmap.h>
33#include <mach/irqs.h>
34#include <mach/iomap.h>
35#include <mach/dc.h>
36#include <mach/fb.h>
37
38#include "devices.h"
39#include "gpio-names.h"
40#include "board.h"
41
42#define whistler_hdmi_hpd TEGRA_GPIO_PN7
43
44#ifdef CONFIG_TEGRA_DC
45static struct regulator *whistler_hdmi_reg = NULL;
46static struct regulator *whistler_hdmi_pll = NULL;
47#endif
48
49/*
50 * In case which_pwm is TEGRA_PWM_PM0,
51 * gpio_conf_to_sfio should be TEGRA_GPIO_PW0: set LCD_CS1_N pin to SFIO
52 * In case which_pwm is TEGRA_PWM_PM1,
53 * gpio_conf_to_sfio should be TEGRA_GPIO_PW1: set LCD_M1 pin to SFIO
54 */
55static struct platform_tegra_pwm_backlight_data whistler_disp1_backlight_data = {
56 .which_dc = 0,
57 .which_pwm = TEGRA_PWM_PM1,
58 .max_brightness = 256,
59 .dft_brightness = 77,
60 .gpio_conf_to_sfio = TEGRA_GPIO_PW1,
61 .switch_to_sfio = &tegra_gpio_disable,
62 .period = 0x1F,
63 .clk_div = 3,
64 .clk_select = 2,
65};
66
67static struct platform_device whistler_disp1_backlight_device = {
68 .name = "tegra-pwm-bl",
69 .id = -1,
70 .dev = {
71 .platform_data = &whistler_disp1_backlight_data,
72 },
73};
74
75#ifdef CONFIG_TEGRA_DC
76static int whistler_hdmi_enable(void)
77{
78 if (!whistler_hdmi_reg) {
79 whistler_hdmi_reg = regulator_get(NULL, "avdd_hdmi"); /* LD011 */
80 if (IS_ERR_OR_NULL(whistler_hdmi_reg)) {
81 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
82 whistler_hdmi_reg = NULL;
83 return PTR_ERR(whistler_hdmi_reg);
84 }
85 }
86 regulator_enable(whistler_hdmi_reg);
87
88 if (!whistler_hdmi_pll) {
89 whistler_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll"); /* LD06 */
90 if (IS_ERR_OR_NULL(whistler_hdmi_pll)) {
91 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
92 whistler_hdmi_pll = NULL;
93 regulator_disable(whistler_hdmi_reg);
94 whistler_hdmi_reg = NULL;
95 return PTR_ERR(whistler_hdmi_pll);
96 }
97 }
98 regulator_enable(whistler_hdmi_pll);
99 return 0;
100}
101
102static int whistler_hdmi_disable(void)
103{
104 regulator_disable(whistler_hdmi_reg);
105 regulator_disable(whistler_hdmi_pll);
106 return 0;
107}
108
109static struct resource whistler_disp1_resources[] = {
110 {
111 .name = "irq",
112 .start = INT_DISPLAY_GENERAL,
113 .end = INT_DISPLAY_GENERAL,
114 .flags = IORESOURCE_IRQ,
115 },
116 {
117 .name = "regs",
118 .start = TEGRA_DISPLAY_BASE,
119 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
120 .flags = IORESOURCE_MEM,
121 },
122 {
123 .name = "fbmem",
124 .flags = IORESOURCE_MEM,
125 },
126};
127
128static struct resource whistler_disp2_resources[] = {
129 {
130 .name = "irq",
131 .start = INT_DISPLAY_B_GENERAL,
132 .end = INT_DISPLAY_B_GENERAL,
133 .flags = IORESOURCE_IRQ,
134 },
135 {
136 .name = "regs",
137 .start = TEGRA_DISPLAY2_BASE,
138 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
139 .flags = IORESOURCE_MEM,
140 },
141 {
142 .name = "fbmem",
143 .flags = IORESOURCE_MEM,
144 },
145 {
146 .name = "hdmi_regs",
147 .start = TEGRA_HDMI_BASE,
148 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
149 .flags = IORESOURCE_MEM,
150 },
151};
152
153static struct tegra_dc_mode whistler_panel_modes[] = {
154 {
155 .pclk = 27000000,
156 .h_ref_to_sync = 4,
157 .v_ref_to_sync = 2,
158 .h_sync_width = 10,
159 .v_sync_width = 3,
160 .h_back_porch = 20,
161 .v_back_porch = 3,
162 .h_active = 800,
163 .v_active = 480,
164 .h_front_porch = 70,
165 .v_front_porch = 3,
166 },
167};
168
169static struct tegra_dc_out_pin whistler_dc_out_pins[] = {
170 {
171 .name = TEGRA_DC_OUT_PIN_H_SYNC,
172 .pol = TEGRA_DC_OUT_PIN_POL_LOW,
173 },
174 {
175 .name = TEGRA_DC_OUT_PIN_V_SYNC,
176 .pol = TEGRA_DC_OUT_PIN_POL_LOW,
177 },
178 {
179 .name = TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
180 .pol = TEGRA_DC_OUT_PIN_POL_LOW,
181 },
182};
183
184static u8 whistler_dc_out_pin_sel_config[] = {
185 TEGRA_PIN_OUT_CONFIG_SEL_LM1_PM1,
186};
187
188static struct tegra_dc_out whistler_disp1_out = {
189 .type = TEGRA_DC_OUT_RGB,
190
191 .align = TEGRA_DC_ALIGN_MSB,
192 .order = TEGRA_DC_ORDER_RED_BLUE,
193
194 .height = 54, /* mm */
195 .width = 90, /* mm */
196
197 .modes = whistler_panel_modes,
198 .n_modes = ARRAY_SIZE(whistler_panel_modes),
199
200 .out_pins = whistler_dc_out_pins,
201 .n_out_pins = ARRAY_SIZE(whistler_dc_out_pins),
202
203 .out_sel_configs = whistler_dc_out_pin_sel_config,
204 .n_out_sel_configs = ARRAY_SIZE(whistler_dc_out_pin_sel_config),
205};
206
207static struct tegra_dc_out whistler_disp2_out = {
208 .type = TEGRA_DC_OUT_HDMI,
209 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
210
211 .dcc_bus = 1,
212 .hotplug_gpio = whistler_hdmi_hpd,
213
214 .max_pixclock = KHZ2PICOS(148500),
215
216 .align = TEGRA_DC_ALIGN_MSB,
217 .order = TEGRA_DC_ORDER_RED_BLUE,
218
219 .enable = whistler_hdmi_enable,
220 .disable = whistler_hdmi_disable,
221};
222
223static struct tegra_fb_data whistler_fb_data = {
224 .win = 0,
225 .xres = 800,
226 .yres = 480,
227 .bits_per_pixel = 32,
228 .flags = TEGRA_FB_FLIP_ON_PROBE,
229};
230
231static struct tegra_fb_data whistler_hdmi_fb_data = {
232 .win = 0,
233 .xres = 800,
234 .yres = 480,
235 .bits_per_pixel = 32,
236 .flags = TEGRA_FB_FLIP_ON_PROBE,
237};
238
239
240static struct tegra_dc_platform_data whistler_disp1_pdata = {
241 .flags = TEGRA_DC_FLAG_ENABLED,
242 .default_out = &whistler_disp1_out,
243 .fb = &whistler_fb_data,
244};
245
246static struct nvhost_device whistler_disp1_device = {
247 .name = "tegradc",
248 .id = 0,
249 .resource = whistler_disp1_resources,
250 .num_resources = ARRAY_SIZE(whistler_disp1_resources),
251 .dev = {
252 .platform_data = &whistler_disp1_pdata,
253 },
254};
255
256static struct tegra_dc_platform_data whistler_disp2_pdata = {
257 .flags = 0,
258 .default_out = &whistler_disp2_out,
259 .fb = &whistler_hdmi_fb_data,
260};
261
262static struct nvhost_device whistler_disp2_device = {
263 .name = "tegradc",
264 .id = 1,
265 .resource = whistler_disp2_resources,
266 .num_resources = ARRAY_SIZE(whistler_disp2_resources),
267 .dev = {
268 .platform_data = &whistler_disp2_pdata,
269 },
270};
271#endif
272
273#if defined(CONFIG_TEGRA_NVMAP)
274static struct nvmap_platform_carveout whistler_carveouts[] = {
275 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
276 [1] = {
277 .name = "generic-0",
278 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
279 .base = 0x18C00000,
280 .size = SZ_128M - 0xC00000,
281 .buddy_size = SZ_32K,
282 },
283};
284
285static struct nvmap_platform_data whistler_nvmap_data = {
286 .carveouts = whistler_carveouts,
287 .nr_carveouts = ARRAY_SIZE(whistler_carveouts),
288};
289
290static struct platform_device whistler_nvmap_device = {
291 .name = "tegra-nvmap",
292 .id = -1,
293 .dev = {
294 .platform_data = &whistler_nvmap_data,
295 },
296};
297#endif
298
299static struct platform_device *whistler_gfx_devices[] __initdata = {
300#if defined(CONFIG_TEGRA_NVMAP)
301 &whistler_nvmap_device,
302#endif
303 &whistler_disp1_backlight_device,
304};
305
306#ifdef CONFIG_HAS_EARLYSUSPEND
307/* put early_suspend/late_resume handlers here for the display in order
308 * to keep the code out of the display driver, keeping it closer to upstream
309 */
310struct early_suspend whistler_panel_early_suspender;
311
312static void whistler_panel_early_suspend(struct early_suspend *h)
313{
314 /* power down LCD, add use a blank screen for HDMI */
315 if (num_registered_fb > 0)
316 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
317 if (num_registered_fb > 1)
318 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
319
320#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
321 cpufreq_save_default_governor();
322 cpufreq_set_conservative_governor();
323 cpufreq_set_conservative_governor_param("up_threshold",
324 SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
325
326 cpufreq_set_conservative_governor_param("down_threshold",
327 SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
328
329 cpufreq_set_conservative_governor_param("freq_step",
330 SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
331#endif
332}
333
334static void whistler_panel_late_resume(struct early_suspend *h)
335{
336 unsigned i;
337#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
338 cpufreq_restore_default_governor();
339#endif
340 for (i = 0; i < num_registered_fb; i++)
341 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
342}
343#endif
344
345int __init whistler_panel_init(void)
346{
347 int err;
348 struct resource __maybe_unused *res;
349
350 tegra_gpio_enable(whistler_hdmi_hpd);
351 gpio_request(whistler_hdmi_hpd, "hdmi_hpd");
352 gpio_direction_input(whistler_hdmi_hpd);
353
354#ifdef CONFIG_HAS_EARLYSUSPEND
355 whistler_panel_early_suspender.suspend = whistler_panel_early_suspend;
356 whistler_panel_early_suspender.resume = whistler_panel_late_resume;
357 whistler_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
358 register_early_suspend(&whistler_panel_early_suspender);
359#endif
360
361#if defined(CONFIG_TEGRA_NVMAP)
362 whistler_carveouts[1].base = tegra_carveout_start;
363 whistler_carveouts[1].size = tegra_carveout_size;
364#endif
365
366#ifdef CONFIG_TEGRA_GRHOST
367 err = nvhost_device_register(&tegra_grhost_device);
368 if (err)
369 return err;
370#endif
371
372 err = platform_add_devices(whistler_gfx_devices,
373 ARRAY_SIZE(whistler_gfx_devices));
374
375#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
376 res = nvhost_get_resource_byname(&whistler_disp1_device,
377 IORESOURCE_MEM, "fbmem");
378 res->start = tegra_fb_start;
379 res->end = tegra_fb_start + tegra_fb_size - 1;
380#endif
381
382 /* Copy the bootloader fb to the fb. */
383 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
384 min(tegra_fb_size, tegra_bootloader_fb_size));
385
386#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
387 res = nvhost_get_resource_byname(&whistler_disp2_device,
388 IORESOURCE_MEM, "fbmem");
389 res->start = tegra_fb2_start;
390 res->end = tegra_fb2_start + tegra_fb2_size - 1;
391
392 if (!err)
393 err = nvhost_device_register(&whistler_disp1_device);
394
395 if (!err)
396 err = nvhost_device_register(&whistler_disp2_device);
397#endif
398
399 return err;
400}
401
diff --git a/arch/arm/mach-tegra/board-whistler-pinmux.c b/arch/arm/mach-tegra/board-whistler-pinmux.c
new file mode 100644
index 00000000000..22c2f984c66
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-pinmux.c
@@ -0,0 +1,207 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-pinmux.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation
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/gpio.h>
20#include <mach/pinmux.h>
21
22#include "board-whistler.h"
23#include "gpio-names.h"
24
25/* Setting the drive strength of pins
26 * hsm: Enable High speed mode (ENABLE/DISABLE)
27 * Schimit: Enable/disable schimit (ENABLE/DISABLE)
28 * drive: low power mode (DIV_1, DIV_2, DIV_4, DIV_8)
29 * pulldn_drive - drive down (falling edge) - Driver Output Pull-Down drive
30 * strength code. Value from 0 to 31.
31 * pullup_drive - drive up (rising edge) - Driver Output Pull-Up drive
32 * strength code. Value from 0 to 31.
33 * pulldn_slew - Driver Output Pull-Up slew control code - 2bit code
34 * code 11 is least slewing of signal. code 00 is highest
35 * slewing of the signal.
36 * Value - FASTEST, FAST, SLOW, SLOWEST
37 * pullup_slew - Driver Output Pull-Down slew control code -
38 * code 11 is least slewing of signal. code 00 is highest
39 * slewing of the signal.
40 * Value - FASTEST, FAST, SLOW, SLOWEST
41 */
42#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
43 { \
44 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
45 .hsm = TEGRA_HSM_##_hsm, \
46 .schmitt = TEGRA_SCHMITT_##_schmitt, \
47 .drive = TEGRA_DRIVE_##_drive, \
48 .pull_down = TEGRA_PULL_##_pulldn_drive, \
49 .pull_up = TEGRA_PULL_##_pullup_drive, \
50 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
51 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
52 }
53
54#define DEFAULT_DRIVE(_name) \
55 { \
56 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
57 .hsm = TEGRA_HSM_DISABLE, \
58 .schmitt = TEGRA_SCHMITT_ENABLE, \
59 .drive = TEGRA_DRIVE_DIV_1, \
60 .pull_down = TEGRA_PULL_31, \
61 .pull_up = TEGRA_PULL_31, \
62 .slew_rising = TEGRA_SLEW_SLOWEST, \
63 .slew_falling = TEGRA_SLEW_SLOWEST, \
64 }
65
66static __initdata struct tegra_drive_pingroup_config whistler_drive_pinmux[] = {
67 DEFAULT_DRIVE(DBG),
68 DEFAULT_DRIVE(DDC),
69 DEFAULT_DRIVE(VI1),
70 DEFAULT_DRIVE(VI2),
71 DEFAULT_DRIVE(SDIO1),
72 SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 46, 46, SLOWEST, SLOWEST),
73 SET_DRIVE(DAP3, DISABLE, ENABLE, DIV_1, 46, 46, SLOWEST, SLOWEST),
74};
75
76static __initdata struct tegra_pingroup_config whistler_pinmux[] = {
77 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_ATB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_ATC, TEGRA_MUX_SDIO4, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_ATD, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_OSC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
84 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
92 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_GMA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
99 {TEGRA_PINGROUP_GMC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_GME, TEGRA_MUX_DAP5, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
102 {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
106 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
108 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
113 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
114 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
118 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
121 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
122 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
125 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
129 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
130 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
131 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
135 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
141 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
142 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
143 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
144 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
145 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
146 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
147 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
148 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
149 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
150 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
151 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
152 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
153 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
154 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
155 {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
156 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
157 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
158 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
159 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
160 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
161 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
162 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
163 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
164 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
165 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
166 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
167 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
168 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
169 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
170 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
171 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
172 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
173 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
174 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
175 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
176 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
177 {TEGRA_PINGROUP_UAA, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
178 {TEGRA_PINGROUP_UAB, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
179 {TEGRA_PINGROUP_UAC, TEGRA_MUX_OWR, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
180 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
181 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
182 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
183 {TEGRA_PINGROUP_UDA, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
184 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
185 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
186 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
187 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
188 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
189 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
190 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
191 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
192 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
193};
194
195static struct tegra_gpio_table gpio_table[] = {
196 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
197};
198
199int __init whistler_pinmux_init(void)
200{
201 tegra_pinmux_config_table(whistler_pinmux, ARRAY_SIZE(whistler_pinmux));
202 tegra_drive_pinmux_config_table(whistler_drive_pinmux,
203 ARRAY_SIZE(whistler_drive_pinmux));
204
205 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
206 return 0;
207}
diff --git a/arch/arm/mach-tegra/board-whistler-power.c b/arch/arm/mach-tegra/board-whistler-power.c
new file mode 100644
index 00000000000..72389f18177
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-power.c
@@ -0,0 +1,291 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/pda_power.h>
20#include <linux/platform_device.h>
21#include <linux/resource.h>
22#include <linux/regulator/machine.h>
23#include <linux/mfd/max8907c.h>
24#include <linux/regulator/max8907c-regulator.h>
25#include <linux/gpio.h>
26#include <linux/io.h>
27
28#include <mach/iomap.h>
29#include <mach/irqs.h>
30
31#include "gpio-names.h"
32#include "fuse.h"
33#include "pm.h"
34#include "wakeups-t2.h"
35#include "board.h"
36
37#define PMC_CTRL 0x0
38#define PMC_CTRL_INTR_LOW (1 << 17)
39
40static struct regulator_consumer_supply max8907c_SD1_supply[] = {
41 REGULATOR_SUPPLY("vdd_cpu", NULL),
42};
43
44static struct regulator_consumer_supply max8907c_SD2_supply[] = {
45 REGULATOR_SUPPLY("vdd_core", NULL),
46 REGULATOR_SUPPLY("vdd_aon", NULL),
47};
48
49static struct regulator_consumer_supply max8907c_SD3_supply[] = {
50 REGULATOR_SUPPLY("vddio_sys", NULL),
51};
52
53static struct regulator_consumer_supply max8907c_LDO1_supply[] = {
54 REGULATOR_SUPPLY("vddio_rx_ddr", NULL),
55};
56
57static struct regulator_consumer_supply max8907c_LDO2_supply[] = {
58 REGULATOR_SUPPLY("avdd_plla", NULL),
59};
60
61static struct regulator_consumer_supply max8907c_LDO3_supply[] = {
62 REGULATOR_SUPPLY("vdd_vcom_1v8b", NULL),
63};
64
65static struct regulator_consumer_supply max8907c_LDO4_supply[] = {
66 REGULATOR_SUPPLY("avdd_usb", NULL),
67 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
68};
69
70static struct regulator_consumer_supply max8907c_LDO5_supply[] = {
71};
72
73static struct regulator_consumer_supply max8907c_LDO6_supply[] = {
74 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
75};
76
77static struct regulator_consumer_supply max8907c_LDO7_supply[] = {
78 REGULATOR_SUPPLY("avddio_audio", NULL),
79};
80
81static struct regulator_consumer_supply max8907c_LDO8_supply[] = {
82 REGULATOR_SUPPLY("vdd_vcom_3v0", NULL),
83};
84
85static struct regulator_consumer_supply max8907c_LDO9_supply[] = {
86 REGULATOR_SUPPLY("vdd_cam1", NULL),
87};
88
89static struct regulator_consumer_supply max8907c_LDO10_supply[] = {
90 REGULATOR_SUPPLY("avdd_usb_ic", NULL),
91};
92
93static struct regulator_consumer_supply max8907c_LDO11_supply[] = {
94 REGULATOR_SUPPLY("vddio_pex_clk", NULL),
95 REGULATOR_SUPPLY("avdd_hdmi", NULL),
96};
97
98static struct regulator_consumer_supply max8907c_LDO12_supply[] = {
99 REGULATOR_SUPPLY("vddio_sdio", NULL),
100};
101
102static struct regulator_consumer_supply max8907c_LDO13_supply[] = {
103 REGULATOR_SUPPLY("vdd_vcore_phtn", NULL),
104 REGULATOR_SUPPLY("vdd_vcore_af", NULL),
105};
106
107static struct regulator_consumer_supply max8907c_LDO14_supply[] = {
108 REGULATOR_SUPPLY("avdd_vdac", NULL),
109};
110
111static struct regulator_consumer_supply max8907c_LDO15_supply[] = {
112 REGULATOR_SUPPLY("vdd_vcore_temp", NULL),
113 REGULATOR_SUPPLY("vdd_vcore_hdcp", NULL),
114};
115
116static struct regulator_consumer_supply max8907c_LDO16_supply[] = {
117 REGULATOR_SUPPLY("vdd_vbrtr", NULL),
118};
119
120static struct regulator_consumer_supply max8907c_LDO17_supply[] = {
121 REGULATOR_SUPPLY("vddio_mipi", NULL),
122};
123
124static struct regulator_consumer_supply max8907c_LDO18_supply[] = {
125 REGULATOR_SUPPLY("vddio_vi", NULL),
126 REGULATOR_SUPPLY("vcsi", "tegra_camera"),
127};
128
129static struct regulator_consumer_supply max8907c_LDO19_supply[] = {
130 REGULATOR_SUPPLY("vddio_lx", NULL),
131};
132
133static struct regulator_consumer_supply max8907c_LDO20_supply[] = {
134 REGULATOR_SUPPLY("vddio_ddr_1v2", NULL),
135 REGULATOR_SUPPLY("vddio_hsic", NULL),
136};
137
138#define MAX8907C_REGULATOR_DEVICE(_id, _minmv, _maxmv) \
139static struct regulator_init_data max8907c_##_id##_data = { \
140 .constraints = { \
141 .min_uV = (_minmv), \
142 .max_uV = (_maxmv), \
143 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
144 REGULATOR_MODE_STANDBY), \
145 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
146 REGULATOR_CHANGE_STATUS | \
147 REGULATOR_CHANGE_VOLTAGE), \
148 }, \
149 .num_consumer_supplies = ARRAY_SIZE(max8907c_##_id##_supply), \
150 .consumer_supplies = max8907c_##_id##_supply, \
151}; \
152static struct platform_device max8907c_##_id##_device = { \
153 .name = "max8907c-regulator", \
154 .id = MAX8907C_##_id, \
155 .dev = { \
156 .platform_data = &max8907c_##_id##_data, \
157 }, \
158}
159
160MAX8907C_REGULATOR_DEVICE(SD1, 637500, 1425000);
161MAX8907C_REGULATOR_DEVICE(SD2, 637500, 1425000);
162MAX8907C_REGULATOR_DEVICE(SD3, 750000, 3900000);
163MAX8907C_REGULATOR_DEVICE(LDO1, 750000, 3900000);
164MAX8907C_REGULATOR_DEVICE(LDO2, 650000, 2225000);
165MAX8907C_REGULATOR_DEVICE(LDO3, 650000, 2225000);
166MAX8907C_REGULATOR_DEVICE(LDO4, 750000, 3900000);
167MAX8907C_REGULATOR_DEVICE(LDO5, 750000, 3900000);
168MAX8907C_REGULATOR_DEVICE(LDO6, 750000, 3900000);
169MAX8907C_REGULATOR_DEVICE(LDO7, 750000, 3900000);
170MAX8907C_REGULATOR_DEVICE(LDO8, 750000, 3900000);
171MAX8907C_REGULATOR_DEVICE(LDO9, 750000, 3900000);
172MAX8907C_REGULATOR_DEVICE(LDO10, 750000, 3900000);
173MAX8907C_REGULATOR_DEVICE(LDO11, 750000, 3900000);
174MAX8907C_REGULATOR_DEVICE(LDO12, 750000, 3900000);
175MAX8907C_REGULATOR_DEVICE(LDO13, 750000, 3900000);
176MAX8907C_REGULATOR_DEVICE(LDO14, 750000, 3900000);
177MAX8907C_REGULATOR_DEVICE(LDO15, 750000, 3900000);
178MAX8907C_REGULATOR_DEVICE(LDO16, 750000, 3900000);
179MAX8907C_REGULATOR_DEVICE(LDO17, 650000, 2225000);
180MAX8907C_REGULATOR_DEVICE(LDO18, 650000, 2225000);
181MAX8907C_REGULATOR_DEVICE(LDO19, 750000, 3900000);
182MAX8907C_REGULATOR_DEVICE(LDO20, 750000, 3900000);
183
184static struct platform_device *whistler_max8907c_power_devices[] = {
185 &max8907c_SD1_device,
186 &max8907c_SD2_device,
187 &max8907c_SD3_device,
188 &max8907c_LDO1_device,
189 &max8907c_LDO2_device,
190 &max8907c_LDO3_device,
191 &max8907c_LDO4_device,
192 &max8907c_LDO5_device,
193 &max8907c_LDO6_device,
194 &max8907c_LDO7_device,
195 &max8907c_LDO8_device,
196 &max8907c_LDO9_device,
197 &max8907c_LDO10_device,
198 &max8907c_LDO11_device,
199 &max8907c_LDO12_device,
200 &max8907c_LDO13_device,
201 &max8907c_LDO14_device,
202 &max8907c_LDO15_device,
203 &max8907c_LDO16_device,
204 &max8907c_LDO17_device,
205 &max8907c_LDO18_device,
206 &max8907c_LDO19_device,
207 &max8907c_LDO20_device,
208};
209
210static int whistler_max8907c_setup(void)
211{
212 int ret;
213
214 /*
215 * Configure PWREN, and attach CPU V1 rail to it.
216 * TODO: h/w events (power cycle, reset, battery low) auto-disables PWREN.
217 * Only soft reset (not supported) requires s/w to disable PWREN explicitly
218 */
219 ret = max8907c_pwr_en_config();
220 if (ret != 0)
221 return ret;
222
223 return max8907c_pwr_en_attach();
224}
225
226static struct max8907c_platform_data max8907c_pdata = {
227 .num_subdevs = ARRAY_SIZE(whistler_max8907c_power_devices),
228 .subdevs = whistler_max8907c_power_devices,
229 .irq_base = TEGRA_NR_IRQS,
230 .max8907c_setup = whistler_max8907c_setup,
231 .use_power_off = true,
232};
233
234static struct i2c_board_info __initdata whistler_regulators[] = {
235 {
236 I2C_BOARD_INFO("max8907c", 0x3C),
237 .irq = INT_EXTERNAL_PMU,
238 .platform_data = &max8907c_pdata,
239 },
240};
241
242static void whistler_board_suspend(int lp_state, enum suspend_stage stg)
243{
244 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
245 tegra_console_uart_suspend();
246}
247
248static void whistler_board_resume(int lp_state, enum resume_stage stg)
249{
250 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
251 tegra_console_uart_resume();
252}
253
254static struct tegra_suspend_platform_data whistler_suspend_data = {
255 .cpu_timer = 2000,
256 .cpu_off_timer = 1000,
257 .suspend_mode = TEGRA_SUSPEND_LP0,
258 .core_timer = 0x7e,
259 .core_off_timer = 0xc00,
260 .corereq_high = true,
261 .sysclkreq_high = true,
262 .combined_req = true,
263 .board_suspend = whistler_board_suspend,
264 .board_resume = whistler_board_resume,
265};
266
267int __init whistler_regulator_init(void)
268{
269 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
270 void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
271 u32 pmc_ctrl;
272 u32 minor;
273
274 minor = (readl(chip_id) >> 16) & 0xf;
275 /* A03 (but not A03p) chips do not support LP0 */
276 if (minor == 3 && !(tegra_spare_fuse(18) || tegra_spare_fuse(19)))
277 whistler_suspend_data.suspend_mode = TEGRA_SUSPEND_LP1;
278
279 /* configure the power management controller to trigger PMU
280 * interrupts when low */
281 pmc_ctrl = readl(pmc + PMC_CTRL);
282 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
283
284 i2c_register_board_info(4, whistler_regulators, 1);
285
286 tegra_deep_sleep = max8907c_deep_sleep;
287
288 tegra_init_suspend(&whistler_suspend_data);
289
290 return 0;
291}
diff --git a/arch/arm/mach-tegra/board-whistler-sdhci.c b/arch/arm/mach-tegra/board-whistler-sdhci.c
new file mode 100644
index 00000000000..08ebe33ae8b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-sdhci.c
@@ -0,0 +1,248 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-sdhci.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
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/resource.h>
19#include <linux/platform_device.h>
20#include <linux/wlan_plat.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/mmc/host.h>
26
27#include <asm/mach-types.h>
28#include <mach/irqs.h>
29#include <mach/iomap.h>
30#include <mach/sdhci.h>
31
32#include "gpio-names.h"
33#include "board.h"
34
35#define WHISTLER_WLAN_PWR TEGRA_GPIO_PK5
36#define WHISTLER_WLAN_RST TEGRA_GPIO_PK6
37#define WHISTLER_WLAN_WOW TEGRA_GPIO_PU5
38
39#define WHISTLER_EXT_SDCARD_DETECT TEGRA_GPIO_PI5
40
41static void (*wifi_status_cb)(int card_present, void *dev_id);
42static void *wifi_status_cb_devid;
43
44static int whistler_wifi_status_register(
45 void (*sdhcicallback)(int card_present, void *dev_id),
46 void *dev_id)
47{
48 if (wifi_status_cb)
49 return -EAGAIN;
50 wifi_status_cb = sdhcicallback;
51 wifi_status_cb_devid = dev_id;
52 return 0;
53}
54
55static int whistler_wifi_set_carddetect(int val)
56{
57 pr_debug("%s: %d\n", __func__, val);
58 if (wifi_status_cb)
59 wifi_status_cb(val, wifi_status_cb_devid);
60 else
61 pr_warning("%s: Nobody to notify\n", __func__);
62 return 0;
63}
64
65static int whistler_wifi_power(int on)
66{
67 gpio_set_value(WHISTLER_WLAN_PWR, on);
68 mdelay(100);
69 gpio_set_value(WHISTLER_WLAN_RST, on);
70 mdelay(200);
71
72 return 0;
73}
74
75static int whistler_wifi_reset(int on)
76{
77 pr_debug("%s: do nothing\n", __func__);
78 return 0;
79}
80
81
82static struct wifi_platform_data whistler_wifi_control = {
83 .set_power = whistler_wifi_power,
84 .set_reset = whistler_wifi_reset,
85 .set_carddetect = whistler_wifi_set_carddetect,
86};
87
88static struct resource wifi_resource[] = {
89 [0] = {
90 .name = "bcm4329_wlan_irq",
91 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5),
92 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5),
93 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
94 },
95};
96
97static struct platform_device whistler_wifi_device = {
98 .name = "bcm4329_wlan",
99 .id = 1,
100 .num_resources = 1,
101 .resource = wifi_resource,
102 .dev = {
103 .platform_data = &whistler_wifi_control,
104 },
105};
106
107static struct resource sdhci_resource1[] = {
108 [0] = {
109 .start = INT_SDMMC2,
110 .end = INT_SDMMC2,
111 .flags = IORESOURCE_IRQ,
112 },
113 [1] = {
114 .start = TEGRA_SDMMC2_BASE,
115 .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1,
116 .flags = IORESOURCE_MEM,
117 },
118};
119
120
121static struct resource sdhci_resource2[] = {
122 [0] = {
123 .start = INT_SDMMC3,
124 .end = INT_SDMMC3,
125 .flags = IORESOURCE_IRQ,
126 },
127 [1] = {
128 .start = TEGRA_SDMMC3_BASE,
129 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
130 .flags = IORESOURCE_MEM,
131 },
132};
133
134static struct resource sdhci_resource3[] = {
135 [0] = {
136 .start = INT_SDMMC4,
137 .end = INT_SDMMC4,
138 .flags = IORESOURCE_IRQ,
139 },
140 [1] = {
141 .start = TEGRA_SDMMC4_BASE,
142 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
143 .flags = IORESOURCE_MEM,
144 },
145};
146
147static struct embedded_sdio_data embedded_sdio_data1 = {
148 .cccr = {
149 .sdio_vsn = 2,
150 .multi_block = 1,
151 .low_speed = 0,
152 .wide_bus = 0,
153 .high_power = 1,
154 .high_speed = 1,
155 },
156 .cis = {
157 .vendor = 0x02d0,
158 .device = 0x4329,
159 },
160};
161
162static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = {
163 .mmc_data = {
164 .register_status_notify = whistler_wifi_status_register,
165 .embedded_sdio = &embedded_sdio_data1,
166 .built_in = 1,
167 },
168 .cd_gpio = -1,
169 .wp_gpio = -1,
170 .power_gpio = -1,
171 .max_clk_limit = 25000000,
172};
173
174static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
175 .cd_gpio = WHISTLER_EXT_SDCARD_DETECT,
176 .wp_gpio = -1,
177 .power_gpio = -1,
178};
179
180static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
181 .cd_gpio = -1,
182 .wp_gpio = -1,
183 .power_gpio = -1,
184 .mmc_data = {
185 .built_in = 1,
186 }
187};
188
189static struct platform_device tegra_sdhci_device1 = {
190 .name = "sdhci-tegra",
191 .id = 1,
192 .resource = sdhci_resource1,
193 .num_resources = ARRAY_SIZE(sdhci_resource1),
194 .dev = {
195 .platform_data = &tegra_sdhci_platform_data1,
196 },
197};
198
199static struct platform_device tegra_sdhci_device2 = {
200 .name = "sdhci-tegra",
201 .id = 2,
202 .resource = sdhci_resource2,
203 .num_resources = ARRAY_SIZE(sdhci_resource2),
204 .dev = {
205 .platform_data = &tegra_sdhci_platform_data2,
206 },
207};
208
209static struct platform_device tegra_sdhci_device3 = {
210 .name = "sdhci-tegra",
211 .id = 3,
212 .resource = sdhci_resource3,
213 .num_resources = ARRAY_SIZE(sdhci_resource3),
214 .dev = {
215 .platform_data = &tegra_sdhci_platform_data3,
216 },
217};
218
219static int __init whistler_wifi_init(void)
220{
221 gpio_request(WHISTLER_WLAN_PWR, "wlan_power");
222 gpio_request(WHISTLER_WLAN_RST, "wlan_rst");
223 gpio_request(WHISTLER_WLAN_WOW, "bcmsdh_sdmmc");
224
225 tegra_gpio_enable(WHISTLER_WLAN_PWR);
226 tegra_gpio_enable(WHISTLER_WLAN_RST);
227 tegra_gpio_enable(WHISTLER_WLAN_WOW);
228
229 gpio_direction_output(WHISTLER_WLAN_PWR, 0);
230 gpio_direction_output(WHISTLER_WLAN_RST, 0);
231 gpio_direction_input(WHISTLER_WLAN_WOW);
232
233 platform_device_register(&whistler_wifi_device);
234 return 0;
235}
236int __init whistler_sdhci_init(void)
237{
238 int ret;
239
240 tegra_gpio_enable(WHISTLER_EXT_SDCARD_DETECT);
241
242 platform_device_register(&tegra_sdhci_device3);
243 platform_device_register(&tegra_sdhci_device2);
244 platform_device_register(&tegra_sdhci_device1);
245
246 whistler_wifi_init();
247 return 0;
248}
diff --git a/arch/arm/mach-tegra/board-whistler-sensors.c b/arch/arm/mach-tegra/board-whistler-sensors.c
new file mode 100644
index 00000000000..95bb2f1dd40
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-sensors.c
@@ -0,0 +1,405 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-sensors.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/delay.h>
35#include <linux/i2c.h>
36#include <mach/gpio.h>
37#include <media/ov5650.h>
38#include <media/soc380.h>
39#include <linux/regulator/consumer.h>
40#include <linux/err.h>
41#include <linux/adt7461.h>
42#include <generated/mach-types.h>
43#include <linux/gpio.h>
44#include <linux/i2c/pca953x.h>
45
46#include <mach/tegra_odm_fuses.h>
47
48#include "gpio-names.h"
49#include "cpu-tegra.h"
50#include "board-whistler.h"
51
52#define CAMERA1_PWDN_GPIO TEGRA_GPIO_PT2
53#define CAMERA1_RESET_GPIO TEGRA_GPIO_PD2
54#define CAMERA2_PWDN_GPIO TEGRA_GPIO_PBB5
55#define CAMERA2_RESET_GPIO TEGRA_GPIO_PBB1
56#define CAMERA_AF_PD_GPIO TEGRA_GPIO_PT3
57#define CAMERA_FLASH_EN1_GPIO TEGRA_GPIO_PBB4
58#define CAMERA_FLASH_EN2_GPIO TEGRA_GPIO_PA0
59
60#define FUSE_POWER_EN_GPIO (TCA6416_GPIO_BASE + 2)
61
62#define ADXL34X_IRQ_GPIO TEGRA_GPIO_PAA1
63#define ISL29018_IRQ_GPIO TEGRA_GPIO_PK2
64#define ADT7461_IRQ_GPIO TEGRA_GPIO_PI2
65
66static struct regulator *reg_avdd_cam1; /* LDO9 */
67static struct regulator *reg_vdd_af; /* LDO13 */
68static struct regulator *reg_vdd_mipi; /* LDO17 */
69static struct regulator *reg_vddio_vi; /* LDO18 */
70
71static int whistler_camera_init(void)
72{
73 tegra_gpio_enable(CAMERA1_PWDN_GPIO);
74 gpio_request(CAMERA1_PWDN_GPIO, "camera1_powerdown");
75 gpio_direction_output(CAMERA1_PWDN_GPIO, 0);
76 gpio_export(CAMERA1_PWDN_GPIO, false);
77
78 tegra_gpio_enable(CAMERA1_RESET_GPIO);
79 gpio_request(CAMERA1_RESET_GPIO, "camera1_reset");
80 gpio_direction_output(CAMERA1_RESET_GPIO, 0);
81 gpio_export(CAMERA1_RESET_GPIO, false);
82
83 tegra_gpio_enable(CAMERA2_PWDN_GPIO);
84 gpio_request(CAMERA2_PWDN_GPIO, "camera2_powerdown");
85 gpio_direction_output(CAMERA2_PWDN_GPIO, 0);
86 gpio_export(CAMERA2_PWDN_GPIO, false);
87
88 tegra_gpio_enable(CAMERA2_RESET_GPIO);
89 gpio_request(CAMERA2_RESET_GPIO, "camera2_reset");
90 gpio_direction_output(CAMERA2_RESET_GPIO, 0);
91 gpio_export(CAMERA2_RESET_GPIO, false);
92
93 tegra_gpio_enable(CAMERA_AF_PD_GPIO);
94 gpio_request(CAMERA_AF_PD_GPIO, "camera_autofocus");
95 gpio_direction_output(CAMERA_AF_PD_GPIO, 0);
96 gpio_export(CAMERA_AF_PD_GPIO, false);
97
98 tegra_gpio_enable(CAMERA_FLASH_EN1_GPIO);
99 gpio_request(CAMERA_FLASH_EN1_GPIO, "camera_flash_en1");
100 gpio_direction_output(CAMERA_FLASH_EN1_GPIO, 0);
101 gpio_export(CAMERA_FLASH_EN1_GPIO, false);
102
103 tegra_gpio_enable(CAMERA_FLASH_EN2_GPIO);
104 gpio_request(CAMERA_FLASH_EN2_GPIO, "camera_flash_en2");
105 gpio_direction_output(CAMERA_FLASH_EN2_GPIO, 0);
106 gpio_export(CAMERA_FLASH_EN2_GPIO, false);
107
108 gpio_set_value(CAMERA1_PWDN_GPIO, 1);
109 mdelay(5);
110
111 return 0;
112}
113
114static int whistler_ov5650_power_on(void)
115{
116 gpio_set_value(CAMERA1_PWDN_GPIO, 0);
117
118 if (!reg_avdd_cam1) {
119 reg_avdd_cam1 = regulator_get(NULL, "vdd_cam1");
120 if (IS_ERR_OR_NULL(reg_avdd_cam1)) {
121 pr_err("whistler_ov5650_power_on: vdd_cam1 failed\n");
122 reg_avdd_cam1 = NULL;
123 return PTR_ERR(reg_avdd_cam1);
124 }
125 regulator_enable(reg_avdd_cam1);
126 }
127 mdelay(5);
128
129 if (!reg_vdd_mipi) {
130 reg_vdd_mipi = regulator_get(NULL, "vddio_mipi");
131 if (IS_ERR_OR_NULL(reg_vdd_mipi)) {
132 pr_err("whistler_ov5650_power_on: vddio_mipi failed\n");
133 reg_vdd_mipi = NULL;
134 return PTR_ERR(reg_vdd_mipi);
135 }
136 regulator_enable(reg_vdd_mipi);
137 }
138 mdelay(5);
139
140 if (!reg_vdd_af) {
141 reg_vdd_af = regulator_get(NULL, "vdd_vcore_af");
142 if (IS_ERR_OR_NULL(reg_vdd_af)) {
143 pr_err("whistler_ov5650_power_on: vdd_vcore_af failed\n");
144 reg_vdd_af = NULL;
145 return PTR_ERR(reg_vdd_af);
146 }
147 regulator_enable(reg_vdd_af);
148 }
149 mdelay(5);
150
151 gpio_set_value(CAMERA1_RESET_GPIO, 1);
152 mdelay(10);
153 gpio_set_value(CAMERA1_RESET_GPIO, 0);
154 mdelay(5);
155 gpio_set_value(CAMERA1_RESET_GPIO, 1);
156 mdelay(20);
157 gpio_set_value(CAMERA_AF_PD_GPIO, 1);
158
159 return 0;
160}
161
162static int whistler_ov5650_power_off(void)
163{
164 gpio_set_value(CAMERA_AF_PD_GPIO, 0);
165 gpio_set_value(CAMERA1_PWDN_GPIO, 1);
166 gpio_set_value(CAMERA1_RESET_GPIO, 0);
167
168 if (reg_avdd_cam1) {
169 regulator_disable(reg_avdd_cam1);
170 regulator_put(reg_avdd_cam1);
171 reg_avdd_cam1 = NULL;
172 }
173
174 if (reg_vdd_mipi) {
175 regulator_disable(reg_vdd_mipi);
176 regulator_put(reg_vdd_mipi);
177 reg_vdd_mipi = NULL;
178 }
179
180 if (reg_vdd_af) {
181 regulator_disable(reg_vdd_af);
182 regulator_put(reg_vdd_af);
183 reg_vdd_af = NULL;
184 }
185
186 return 0;
187}
188
189static int whistler_soc380_power_on(void)
190{
191 gpio_set_value(CAMERA2_PWDN_GPIO, 0);
192
193 if (!reg_vddio_vi) {
194 reg_vddio_vi = regulator_get(NULL, "vddio_vi");
195 if (IS_ERR_OR_NULL(reg_vddio_vi)) {
196 pr_err("whistler_soc380_power_on: vddio_vi failed\n");
197 reg_vddio_vi = NULL;
198 return PTR_ERR(reg_vddio_vi);
199 }
200 regulator_set_voltage(reg_vddio_vi, 1800*1000, 1800*1000);
201 mdelay(5);
202 regulator_enable(reg_vddio_vi);
203 }
204
205 if (!reg_avdd_cam1) {
206 reg_avdd_cam1 = regulator_get(NULL, "vdd_cam1");
207 if (IS_ERR_OR_NULL(reg_avdd_cam1)) {
208 pr_err("whistler_soc380_power_on: vdd_cam1 failed\n");
209 reg_avdd_cam1 = NULL;
210 return PTR_ERR(reg_avdd_cam1);
211 }
212 regulator_enable(reg_avdd_cam1);
213 }
214 mdelay(5);
215
216 gpio_set_value(CAMERA2_RESET_GPIO, 1);
217 mdelay(10);
218 gpio_set_value(CAMERA2_RESET_GPIO, 0);
219 mdelay(5);
220 gpio_set_value(CAMERA2_RESET_GPIO, 1);
221 mdelay(20);
222
223 return 0;
224
225}
226
227static int whistler_soc380_power_off(void)
228{
229 gpio_set_value(CAMERA2_PWDN_GPIO, 1);
230 gpio_set_value(CAMERA2_RESET_GPIO, 0);
231
232 if (reg_avdd_cam1) {
233 regulator_disable(reg_avdd_cam1);
234 regulator_put(reg_avdd_cam1);
235 reg_avdd_cam1 = NULL;
236 }
237 if (reg_vddio_vi) {
238 regulator_disable(reg_vddio_vi);
239 regulator_put(reg_vddio_vi);
240 reg_vddio_vi = NULL;
241 }
242
243 return 0;
244}
245
246struct ov5650_platform_data whistler_ov5650_data = {
247 .power_on = whistler_ov5650_power_on,
248 .power_off = whistler_ov5650_power_off,
249};
250
251struct soc380_platform_data whistler_soc380_data = {
252 .power_on = whistler_soc380_power_on,
253 .power_off = whistler_soc380_power_off,
254};
255
256static int whistler_fuse_power_en(int enb)
257{
258 int ret;
259
260 ret = gpio_request(FUSE_POWER_EN_GPIO, "fuse_power_en");
261 if (ret) {
262 pr_err("%s: gpio_request fail (%d)\n", __func__, ret);
263 return ret;
264 }
265
266 ret = gpio_direction_output(FUSE_POWER_EN_GPIO, enb);
267 if (ret) {
268 pr_err("%s: gpio_direction_output fail (%d)\n", __func__, ret);
269 return ret;
270 }
271
272 gpio_free(FUSE_POWER_EN_GPIO);
273 return 0;
274}
275
276static struct pca953x_platform_data whistler_tca6416_data = {
277 .gpio_base = TCA6416_GPIO_BASE,
278};
279
280static struct i2c_board_info whistler_i2c3_board_info[] = {
281 {
282 I2C_BOARD_INFO("ov5650", 0x36),
283 .platform_data = &whistler_ov5650_data,
284 },
285 {
286 I2C_BOARD_INFO("ad5820", 0x0c),
287 },
288 {
289 I2C_BOARD_INFO("soc380", 0x3C),
290 .platform_data = &whistler_soc380_data,
291 },
292};
293
294static void whistler_adxl34x_init(void)
295{
296 tegra_gpio_enable(ADXL34X_IRQ_GPIO);
297 gpio_request(ADXL34X_IRQ_GPIO, "adxl34x");
298 gpio_direction_input(ADXL34X_IRQ_GPIO);
299}
300
301static void whistler_isl29018_init(void)
302{
303 tegra_gpio_enable(ISL29018_IRQ_GPIO);
304 gpio_request(ISL29018_IRQ_GPIO, "isl29018");
305 gpio_direction_input(ISL29018_IRQ_GPIO);
306}
307
308static struct i2c_board_info whistler_i2c1_board_info[] = {
309 {
310 I2C_BOARD_INFO("adxl34x", 0x1D),
311 .irq = TEGRA_GPIO_TO_IRQ(ADXL34X_IRQ_GPIO),
312 },
313 {
314 I2C_BOARD_INFO("isl29018", 0x44),
315 .irq = TEGRA_GPIO_TO_IRQ(ISL29018_IRQ_GPIO),
316 },
317};
318
319static void whistler_adt7461_init(void)
320{
321 tegra_gpio_enable(ADT7461_IRQ_GPIO);
322}
323
324static struct adt7461_platform_data whistler_adt7461_pdata = {
325 .supported_hwrev = true,
326 .ext_range = false,
327 .therm2 = true,
328 .conv_rate = 0x05,
329 .offset = 0,
330 .hysteresis = 0,
331 .shutdown_ext_limit = 115,
332 .shutdown_local_limit = 120,
333 .throttling_ext_limit = 90,
334 .alarm_fn = tegra_throttling_enable,
335 .irq_gpio = ADT7461_IRQ_GPIO,
336};
337
338static struct i2c_board_info whistler_i2c4_board_info[] = {
339 {
340 I2C_BOARD_INFO("adt7461", 0x4C),
341 .irq = TEGRA_GPIO_TO_IRQ(ADT7461_IRQ_GPIO),
342 .platform_data = &whistler_adt7461_pdata,
343 },
344 {
345 I2C_BOARD_INFO("tca6416", 0x20),
346 .platform_data = &whistler_tca6416_data,
347 },
348};
349
350int __init whistler_sensors_init(void)
351{
352 whistler_camera_init();
353
354 whistler_adxl34x_init();
355
356 whistler_isl29018_init();
357
358 whistler_adt7461_init();
359
360 i2c_register_board_info(0, whistler_i2c1_board_info,
361 ARRAY_SIZE(whistler_i2c1_board_info));
362
363 i2c_register_board_info(4, whistler_i2c4_board_info,
364 ARRAY_SIZE(whistler_i2c4_board_info));
365
366 i2c_register_board_info(3, whistler_i2c3_board_info,
367 ARRAY_SIZE(whistler_i2c3_board_info));
368
369 tegra_fuse_regulator_en = whistler_fuse_power_en;
370
371 return 0;
372}
373
374int __init whistler_sensor_late_init(void)
375{
376 int ret;
377
378 if (!machine_is_whistler())
379 return 0;
380
381 reg_vddio_vi = regulator_get(NULL, "vddio_vi");
382 if (IS_ERR_OR_NULL(reg_vddio_vi)) {
383 pr_err("%s: Couldn't get regulator vddio_vi\n", __func__);
384 return PTR_ERR(reg_vddio_vi);
385 }
386
387 /* set vddio_vi voltage to 1.8v */
388 ret = regulator_set_voltage(reg_vddio_vi, 1800*1000, 1800*1000);
389 if (ret) {
390 pr_err("%s: Failed to set vddio_vi to 1.8v\n", __func__);
391 goto fail_put_regulator;
392 }
393
394 regulator_put(reg_vddio_vi);
395 reg_vddio_vi = NULL;
396 return 0;
397
398fail_put_regulator:
399 regulator_put(reg_vddio_vi);
400 reg_vddio_vi = NULL;
401 return ret;
402}
403
404late_initcall(whistler_sensor_late_init);
405
diff --git a/arch/arm/mach-tegra/board-whistler.c b/arch/arm/mach-tegra/board-whistler.c
new file mode 100644
index 00000000000..2ff6e55e162
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler.c
@@ -0,0 +1,560 @@
1/*
2 * arch/arm/mach-tegra/board-whistler.c
3 *
4 * Copyright (c) 2010 - 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/serial_8250.h>
28#include <linux/i2c.h>
29#include <linux/synaptics_i2c_rmi.h>
30#include <linux/dma-mapping.h>
31#include <linux/delay.h>
32#include <linux/i2c-tegra.h>
33#include <linux/gpio.h>
34#include <linux/gpio_scrollwheel.h>
35#include <linux/input.h>
36#include <linux/platform_data/tegra_usb.h>
37#include <linux/mfd/max8907c.h>
38#include <linux/memblock.h>
39#include <linux/tegra_uart.h>
40
41#include <mach/clk.h>
42#include <mach/iomap.h>
43#include <mach/irqs.h>
44#include <mach/pinmux.h>
45#include <mach/iomap.h>
46#include <mach/io.h>
47#include <mach/i2s.h>
48#include <mach/tegra_wm8753_pdata.h>
49#include <sound/tlv320aic326x.h>
50
51#include <asm/mach-types.h>
52#include <asm/mach/arch.h>
53#include <mach/usb_phy.h>
54
55#include "board.h"
56#include "clock.h"
57#include "board-whistler.h"
58#include "devices.h"
59#include "gpio-names.h"
60#include "fuse.h"
61#include "pm.h"
62#include "board-whistler-baseband.h"
63
64#define SZ_3M (SZ_1M + SZ_2M)
65#define SZ_152M (SZ_128M + SZ_16M + SZ_8M)
66#define USB1_VBUS_GPIO TCA6416_GPIO_BASE
67
68static struct platform_device *whistler_uart_devices[] __initdata = {
69 &tegra_uarta_device,
70 &tegra_uartb_device,
71 &tegra_uartc_device,
72};
73
74struct uart_clk_parent uart_parent_clk[] = {
75 [0] = {.name = "pll_p"},
76 [1] = {.name = "pll_m"},
77 [2] = {.name = "clk_m"},
78};
79
80static struct tegra_uart_platform_data whistler_uart_pdata;
81
82static void __init uart_debug_init(void)
83{
84 unsigned long rate;
85 struct clk *debug_uart_clk;
86 struct clk *c;
87 int modem_id = tegra_get_modem_id();
88
89 if (modem_id == 0x1) {
90 /* UARTB is the debug port. */
91 pr_info("Selecting UARTB as the debug console\n");
92 whistler_uart_devices[1] = &debug_uartb_device;
93 debug_uart_port_base = ((struct plat_serial8250_port *)(
94 debug_uartb_device.dev.platform_data))->mapbase;
95 debug_uart_clk = clk_get_sys("serial8250.0", "uartb");
96
97 /* Clock enable for the debug channel */
98 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
99 rate = ((struct plat_serial8250_port *)(
100 debug_uartb_device.dev.platform_data))->uartclk;
101 pr_info("The debug console clock name is %s\n",
102 debug_uart_clk->name);
103 c = tegra_get_clock_by_name("pll_p");
104 if (IS_ERR_OR_NULL(c))
105 pr_err("Not getting the parent clock pll_p\n");
106 else
107 clk_set_parent(debug_uart_clk, c);
108
109 clk_enable(debug_uart_clk);
110 clk_set_rate(debug_uart_clk, rate);
111 } else {
112 pr_err("Not getting the clock %s for debug console\n",
113 debug_uart_clk->name);
114 }
115 } else {
116 /* UARTA is the debug port. */
117 pr_info("Selecting UARTA as the debug console\n");
118 whistler_uart_devices[0] = &debug_uarta_device;
119 debug_uart_port_base = ((struct plat_serial8250_port *)(
120 debug_uarta_device.dev.platform_data))->mapbase;
121 debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
122
123 /* Clock enable for the debug channel */
124 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
125 rate = ((struct plat_serial8250_port *)(
126 debug_uarta_device.dev.platform_data))->uartclk;
127 pr_info("The debug console clock name is %s\n",
128 debug_uart_clk->name);
129 c = tegra_get_clock_by_name("pll_p");
130 if (IS_ERR_OR_NULL(c))
131 pr_err("Not getting the parent clock pll_p\n");
132 else
133 clk_set_parent(debug_uart_clk, c);
134
135 clk_enable(debug_uart_clk);
136 clk_set_rate(debug_uart_clk, rate);
137 } else {
138 pr_err("Not getting the clock %s for debug console\n",
139 debug_uart_clk->name);
140 }
141 }
142}
143
144static void __init whistler_uart_init(void)
145{
146 int i;
147 struct clk *c;
148
149 for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
150 c = tegra_get_clock_by_name(uart_parent_clk[i].name);
151 if (IS_ERR_OR_NULL(c)) {
152 pr_err("Not able to get the clock for %s\n",
153 uart_parent_clk[i].name);
154 continue;
155 }
156 uart_parent_clk[i].parent_clk = c;
157 uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
158 }
159 whistler_uart_pdata.parent_clk_list = uart_parent_clk;
160 whistler_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
161
162 tegra_uarta_device.dev.platform_data = &whistler_uart_pdata;
163 tegra_uartb_device.dev.platform_data = &whistler_uart_pdata;
164 tegra_uartc_device.dev.platform_data = &whistler_uart_pdata;
165
166 if (!is_tegra_debug_uartport_hs())
167 uart_debug_init();
168
169 platform_add_devices(whistler_uart_devices,
170 ARRAY_SIZE(whistler_uart_devices));
171}
172
173static struct resource whistler_bcm4329_rfkill_resources[] = {
174 {
175 .name = "bcm4329_nshutdown_gpio",
176 .start = TEGRA_GPIO_PU0,
177 .end = TEGRA_GPIO_PU0,
178 .flags = IORESOURCE_IO,
179 },
180};
181
182static struct platform_device whistler_bcm4329_rfkill_device = {
183 .name = "bcm4329_rfkill",
184 .id = -1,
185 .num_resources = ARRAY_SIZE(whistler_bcm4329_rfkill_resources),
186 .resource = whistler_bcm4329_rfkill_resources,
187};
188
189static struct resource whistler_bluesleep_resources[] = {
190 [0] = {
191 .name = "gpio_host_wake",
192 .start = TEGRA_GPIO_PU6,
193 .end = TEGRA_GPIO_PU6,
194 .flags = IORESOURCE_IO,
195 },
196 [1] = {
197 .name = "gpio_ext_wake",
198 .start = TEGRA_GPIO_PU1,
199 .end = TEGRA_GPIO_PU1,
200 .flags = IORESOURCE_IO,
201 },
202 [2] = {
203 .name = "host_wake",
204 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
205 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
206 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
207 },
208};
209
210static struct platform_device whistler_bluesleep_device = {
211 .name = "bluesleep",
212 .id = -1,
213 .num_resources = ARRAY_SIZE(whistler_bluesleep_resources),
214 .resource = whistler_bluesleep_resources,
215};
216
217static void __init whistler_setup_bluesleep(void)
218{
219 platform_device_register(&whistler_bluesleep_device);
220 tegra_gpio_enable(TEGRA_GPIO_PU6);
221 tegra_gpio_enable(TEGRA_GPIO_PU1);
222 return;
223}
224
225static struct tegra_utmip_config utmi_phy_config[] = {
226 [0] = {
227 .hssync_start_delay = 9,
228 .idle_wait_delay = 17,
229 .elastic_limit = 16,
230 .term_range_adj = 6,
231 .xcvr_setup = 15,
232 .xcvr_lsfslew = 2,
233 .xcvr_lsrslew = 2,
234 },
235 [1] = {
236 .hssync_start_delay = 9,
237 .idle_wait_delay = 17,
238 .elastic_limit = 16,
239 .term_range_adj = 6,
240 .xcvr_setup = 8,
241 .xcvr_lsfslew = 2,
242 .xcvr_lsrslew = 2,
243 },
244};
245
246static struct tegra_ulpi_config ulpi_phy_config = {
247 .reset_gpio = TEGRA_GPIO_PG2,
248 .clk = "cdev2",
249};
250
251static __initdata struct tegra_clk_init_table whistler_clk_init_table[] = {
252 /* name parent rate enabled */
253 { "pwm", "clk_32k", 32768, false},
254 { "kbc", "clk_32k", 32768, true},
255 { "sdmmc2", "pll_p", 25000000, false},
256 { "i2s1", "pll_a_out0", 0, false},
257 { "i2s2", "pll_a_out0", 0, false},
258 { "spdif_out", "pll_a_out0", 0, false},
259 { NULL, NULL, 0, 0},
260};
261
262static struct tegra_i2c_platform_data whistler_i2c1_platform_data = {
263 .adapter_nr = 0,
264 .bus_count = 1,
265 .bus_clk_rate = { 400000, 0 },
266 .scl_gpio = {TEGRA_GPIO_PC4, 0},
267 .sda_gpio = {TEGRA_GPIO_PC5, 0},
268 .arb_recovery = arb_lost_recovery,
269};
270
271static const struct tegra_pingroup_config i2c2_ddc = {
272 .pingroup = TEGRA_PINGROUP_DDC,
273 .func = TEGRA_MUX_I2C2,
274};
275
276static const struct tegra_pingroup_config i2c2_gen2 = {
277 .pingroup = TEGRA_PINGROUP_PTA,
278 .func = TEGRA_MUX_I2C2,
279};
280
281static struct tegra_i2c_platform_data whistler_i2c2_platform_data = {
282 .adapter_nr = 1,
283 .bus_count = 2,
284 .bus_clk_rate = { 100000, 100000 },
285 .bus_mux = { &i2c2_ddc, &i2c2_gen2 },
286 .bus_mux_len = { 1, 1 },
287 .scl_gpio = {0, TEGRA_GPIO_PT5},
288 .sda_gpio = {0, TEGRA_GPIO_PT6},
289 .arb_recovery = arb_lost_recovery,
290};
291
292static struct tegra_i2c_platform_data whistler_i2c3_platform_data = {
293 .adapter_nr = 3,
294 .bus_count = 1,
295 .bus_clk_rate = { 400000, 0 },
296 .scl_gpio = {TEGRA_GPIO_PBB2, 0},
297 .sda_gpio = {TEGRA_GPIO_PBB3, 0},
298 .arb_recovery = arb_lost_recovery,
299};
300
301static struct tegra_i2c_platform_data whistler_dvc_platform_data = {
302 .adapter_nr = 4,
303 .bus_count = 1,
304 .bus_clk_rate = { 400000, 0 },
305 .is_dvc = true,
306 .scl_gpio = {TEGRA_GPIO_PZ6, 0},
307 .sda_gpio = {TEGRA_GPIO_PZ7, 0},
308 .arb_recovery = arb_lost_recovery,
309};
310
311static struct aic326x_pdata whistler_aic3262_pdata = {
312 /* debounce time */
313 .debounce_time_ms = 512,
314};
315
316static struct i2c_board_info __initdata wm8753_board_info[] = {
317 {
318 I2C_BOARD_INFO("wm8753", 0x1a),
319 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_HP_DET),
320 },
321 {
322 I2C_BOARD_INFO("aic3262-codec", 0x18),
323 .platform_data = &whistler_aic3262_pdata,
324 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_HP_DET),
325 },
326};
327
328static void whistler_i2c_init(void)
329{
330 tegra_i2c_device1.dev.platform_data = &whistler_i2c1_platform_data;
331 tegra_i2c_device2.dev.platform_data = &whistler_i2c2_platform_data;
332 tegra_i2c_device3.dev.platform_data = &whistler_i2c3_platform_data;
333 tegra_i2c_device4.dev.platform_data = &whistler_dvc_platform_data;
334
335 platform_device_register(&tegra_i2c_device4);
336 platform_device_register(&tegra_i2c_device3);
337 platform_device_register(&tegra_i2c_device2);
338 platform_device_register(&tegra_i2c_device1);
339
340 i2c_register_board_info(4, wm8753_board_info,
341 ARRAY_SIZE(wm8753_board_info));
342}
343
344#define GPIO_SCROLL(_pinaction, _gpio, _desc) \
345{ \
346 .pinaction = GPIO_SCROLLWHEEL_PIN_##_pinaction, \
347 .gpio = TEGRA_GPIO_##_gpio, \
348 .desc = _desc, \
349 .active_low = 1, \
350 .debounce_interval = 2, \
351}
352
353static struct gpio_scrollwheel_button scroll_keys[] = {
354 [0] = GPIO_SCROLL(ONOFF, PR3, "sw_onoff"),
355 [1] = GPIO_SCROLL(PRESS, PQ5, "sw_press"),
356 [2] = GPIO_SCROLL(ROT1, PQ3, "sw_rot1"),
357 [3] = GPIO_SCROLL(ROT2, PQ4, "sw_rot2"),
358};
359
360static struct gpio_scrollwheel_platform_data whistler_scroll_platform_data = {
361 .buttons = scroll_keys,
362 .nbuttons = ARRAY_SIZE(scroll_keys),
363};
364
365static struct platform_device whistler_scroll_device = {
366 .name = "alps-gpio-scrollwheel",
367 .id = 0,
368 .dev = {
369 .platform_data = &whistler_scroll_platform_data,
370 },
371};
372
373static struct platform_device tegra_camera = {
374 .name = "tegra_camera",
375 .id = -1,
376};
377
378static struct tegra_wm8753_platform_data whistler_audio_pdata = {
379 .gpio_spkr_en = -1,
380 .gpio_hp_det = TEGRA_GPIO_HP_DET,
381 .gpio_hp_mute = -1,
382 .gpio_int_mic_en = -1,
383 .gpio_ext_mic_en = -1,
384 .debounce_time_hp = 200,
385};
386
387static struct platform_device whistler_audio_device1 = {
388 .name = "tegra-snd-aic326x",
389 .id = 0,
390 .dev = {
391 .platform_data = &whistler_audio_pdata,
392 },
393};
394
395static struct platform_device whistler_audio_device2 = {
396 .name = "tegra-snd-wm8753",
397 .id = 0,
398 .dev = {
399 .platform_data = &whistler_audio_pdata,
400 },
401};
402
403static struct platform_device *whistler_devices[] __initdata = {
404 &tegra_pmu_device,
405 &tegra_udc_device,
406 &tegra_gart_device,
407 &tegra_aes_device,
408 &tegra_wdt_device,
409 &tegra_avp_device,
410 &whistler_scroll_device,
411 &tegra_camera,
412 &tegra_i2s_device1,
413 &tegra_i2s_device2,
414 &tegra_spdif_device,
415 &tegra_das_device,
416 &spdif_dit_device,
417 &bluetooth_dit_device,
418 &baseband_dit_device,
419 &whistler_bcm4329_rfkill_device,
420 &tegra_pcm_device,
421 &whistler_audio_device1,
422 &whistler_audio_device2,
423};
424
425static struct synaptics_i2c_rmi_platform_data synaptics_pdata = {
426 .flags = SYNAPTICS_FLIP_X | SYNAPTICS_FLIP_Y | SYNAPTICS_SWAP_XY,
427 .irqflags = IRQF_TRIGGER_LOW,
428};
429
430static const struct i2c_board_info whistler_i2c_touch_info[] = {
431 {
432 I2C_BOARD_INFO("synaptics-rmi-ts", 0x20),
433 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC6),
434 .platform_data = &synaptics_pdata,
435 },
436};
437
438static int __init whistler_touch_init(void)
439{
440 tegra_gpio_enable(TEGRA_GPIO_PC6);
441 i2c_register_board_info(0, whistler_i2c_touch_info, 1);
442
443 return 0;
444}
445
446static int __init whistler_scroll_init(void)
447{
448 int i;
449 for (i = 0; i < ARRAY_SIZE(scroll_keys); i++)
450 tegra_gpio_enable(scroll_keys[i].gpio);
451
452 return 0;
453}
454
455static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
456 [0] = {
457 .instance = 0,
458 .vbus_irq = MAX8907C_INT_BASE + MAX8907C_IRQ_VCHG_DC_R,
459 .vbus_gpio = USB1_VBUS_GPIO,
460 },
461 [1] = {
462 .instance = 1,
463 .vbus_gpio = -1,
464 },
465 [2] = {
466 .instance = 2,
467 .vbus_gpio = -1,
468 },
469};
470
471static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
472 [0] = {
473 .phy_config = &utmi_phy_config[0],
474 .operating_mode = TEGRA_USB_HOST,
475 .power_down_on_bus_suspend = 1,
476 .default_enable = false,
477 },
478 [1] = {
479 .phy_config = &ulpi_phy_config,
480 .operating_mode = TEGRA_USB_HOST,
481 .power_down_on_bus_suspend = 1,
482 .default_enable = false,
483 },
484 [2] = {
485 .phy_config = &utmi_phy_config[1],
486 .operating_mode = TEGRA_USB_HOST,
487 .power_down_on_bus_suspend = 1,
488 .default_enable = false,
489 },
490};
491
492static struct tegra_otg_platform_data tegra_otg_pdata = {
493 .ehci_device = &tegra_ehci1_device,
494 .ehci_pdata = &tegra_ehci_pdata[0],
495};
496
497static int __init whistler_gps_init(void)
498{
499 tegra_gpio_enable(TEGRA_GPIO_PU4);
500 return 0;
501}
502
503static void whistler_usb_init(void)
504{
505 tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata));
506
507 tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
508 platform_device_register(&tegra_otg_device);
509
510}
511
512static void __init tegra_whistler_init(void)
513{
514 int modem_id = tegra_get_modem_id();
515 tegra_clk_init_from_table(whistler_clk_init_table);
516 whistler_pinmux_init();
517 whistler_i2c_init();
518 whistler_uart_init();
519 platform_add_devices(whistler_devices, ARRAY_SIZE(whistler_devices));
520 tegra_ram_console_debug_init();
521 whistler_sdhci_init();
522 whistler_regulator_init();
523 whistler_panel_init();
524 whistler_sensors_init();
525 whistler_touch_init();
526 whistler_kbc_init();
527 whistler_gps_init();
528 whistler_usb_init();
529 whistler_scroll_init();
530 whistler_emc_init();
531 if (modem_id == 0x1)
532 whistler_baseband_init();
533 whistler_setup_bluesleep();
534 tegra_release_bootloader_fb();
535}
536
537int __init tegra_whistler_protected_aperture_init(void)
538{
539 tegra_protected_aperture_init(tegra_grhost_aperture);
540 return 0;
541}
542
543void __init tegra_whistler_reserve(void)
544{
545 if (memblock_reserve(0x0, 4096) < 0)
546 pr_warn("Cannot reserve first 4K of memory for safety\n");
547
548 tegra_reserve(SZ_152M, SZ_3M, SZ_1M);
549 tegra_ram_console_debug_reserve(SZ_1M);
550}
551
552MACHINE_START(WHISTLER, "whistler")
553 .boot_params = 0x00000100,
554 .map_io = tegra_map_common_io,
555 .reserve = tegra_whistler_reserve,
556 .init_early = tegra_init_early,
557 .init_irq = tegra_init_irq,
558 .timer = &tegra_timer,
559 .init_machine = tegra_whistler_init,
560MACHINE_END
diff --git a/arch/arm/mach-tegra/board-whistler.h b/arch/arm/mach-tegra/board-whistler.h
new file mode 100644
index 00000000000..a31be96e915
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler.h
@@ -0,0 +1,39 @@
1/*
2 * arch/arm/mach-tegra/board-whistler.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_WHISTLER_H
18#define _MACH_TEGRA_BOARD_WHISTLER_H
19
20int whistler_regulator_init(void);
21int whistler_sdhci_init(void);
22int whistler_pinmux_init(void);
23int whistler_panel_init(void);
24int whistler_kbc_init(void);
25int whistler_sensors_init(void);
26int whistler_baseband_init(void);
27int whistler_emc_init(void);
28
29/* Interrupt numbers from external peripherals */
30#define MAX8907C_INT_BASE TEGRA_NR_IRQS
31#define MAX8907C_INT_END (MAX8907C_INT_BASE + 31)
32
33/* Audio-related GPIOs */
34#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW3
35
36/* TCA6416 GPIO expander */
37#define TCA6416_GPIO_BASE (TEGRA_NR_GPIOS)
38
39#endif
diff --git a/arch/arm/mach-tegra/clock-common.c b/arch/arm/mach-tegra/clock-common.c
new file mode 100644
index 00000000000..67c5d51378a
--- /dev/null
+++ b/arch/arm/mach-tegra/clock-common.c
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 2010-2012 NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/clk.h>
17#include <linux/clkdev.h>
18#include <linux/io.h>
19
20#include <mach/clk.h>
21#include <mach/iomap.h>
22
23#include "clock.h"
24
25#define clk_writel(value, reg) \
26 __raw_writel(value, (u32)reg_clk_base + (reg))
27#define clk_readl(reg) \
28 __raw_readl((u32)reg_clk_base + (reg))
29
30#define OSC_FREQ_DET 0x58
31#define OSC_FREQ_DET_TRIG (1<<31)
32
33#define OSC_FREQ_DET_STATUS 0x5C
34#define OSC_FREQ_DET_BUSY (1<<31)
35#define OSC_FREQ_DET_CNT_MASK 0xFFFF
36
37static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
38static unsigned long osc_input_freq;
39
40unsigned long tegra_clk_measure_input_freq(void)
41{
42 u32 clock_autodetect;
43
44 if (osc_input_freq)
45 return osc_input_freq;
46
47 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
48 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
49 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
50
51 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3)
52 osc_input_freq = 12000000;
53 else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3)
54 osc_input_freq = 13000000;
55 else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3)
56 osc_input_freq = 19200000;
57 else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3)
58 osc_input_freq = 26000000;
59#ifndef CONFIG_ARCH_TEGRA_2x_SOC
60 else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3)
61 osc_input_freq = 16800000;
62 else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3)
63 osc_input_freq = 38400000;
64 else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3)
65 osc_input_freq = 48000000;
66#endif
67 else {
68 pr_err("%s: Unexpected clock autodetect value %d", __func__,
69 clock_autodetect);
70 BUG();
71 }
72 return osc_input_freq;
73}
diff --git a/arch/arm/mach-tegra/common-t2.c b/arch/arm/mach-tegra/common-t2.c
new file mode 100644
index 00000000000..6f9b177892c
--- /dev/null
+++ b/arch/arm/mach-tegra/common-t2.c
@@ -0,0 +1,192 @@
1/*
2 * arch/arm/mach-tegra/common-t2.c
3 *
4 * Tegra 2 SoC-specific initialization (memory controller, etc.)
5 *
6 * Copyright (c) 2009-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/io.h>
25#include <linux/interrupt.h>
26#include <linux/spinlock.h>
27
28#include <mach/iomap.h>
29#include <mach/irqs.h>
30
31#define MC_INT_STATUS 0x0
32#define MC_INT_MASK 0x4
33#define MC_INT_DECERR_EMEM_OTHERS (1<<6)
34#define MC_INT_INVALID_GART_PAGE (1<<7)
35#define MC_INT_SECURITY_VIOLATION (1<<8)
36
37#define MC_GART_ERROR_STATUS 0x30
38#define MC_GART_ERROR_ADDRESS 0x34
39
40#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
41#define MC_DECERR_EMEM_OTHERS_ADDRESS 0x5c
42
43#define MC_SECURITY_VIOLATION_STATUS 0x74
44#define MC_SECURITY_VIOLATION_ADDRESS 0x78
45
46struct mc_client {
47 bool write;
48 const char *name;
49};
50
51#define client(_name,_write) \
52 { \
53 .write = _write, \
54 .name = _name, \
55 }
56
57static const struct mc_client mc_clients[] = {
58 client("display0_wina", false), client("display1_wina", false),
59 client("display0_winb", false), client("display1_winb", false),
60 client("display0_winc", false), client("display1_winc", false),
61 client("display0_winb_vfilter", false),
62 client("display1_winb_vfilter", false),
63 client("epp", false), client("gr2d_pat", false),
64 client("gr2d_src", false), client("mpe_unified", false),
65 client("vi_chroma_filter", false), client("cop", false),
66 client("display0_cursor", false), client("display1_cursor", false),
67 client("gr3d_fdc", false), client("gr2d_dst", false),
68 client("host1x_dma", false), client("host1x_generic", false),
69 client("gr3d_idx", false), client("cpu_uncached", false),
70 client("mpe_intrapred", false), client("mpe_mpea", false),
71 client("mpe_mpec", false), client("ahb_dma", false),
72 client("ahb_slave", false), client("gr3d_tex", false),
73 client("vde_bsev", false), client("vde_mbe", false),
74 client("vde_mce", false), client("vde_tpe", false),
75 client("epp_u", true), client("epp_v", true),
76 client("epp_y", true), client("mpe_unified", true),
77 client("vi_sb", true), client("vi_u", true),
78 client("vi_v", true), client("vi_y", true),
79 client("gr2d_dst", true), client("gr3d_fdc", true),
80 client("host1x", true), client("isp", true),
81 client("cpu_uncached", true), client("mpe_mpec", true),
82 client("ahb_dma", true), client("ahb_slave", true),
83 client("avp_bsev", true), client("avp_mbe", true),
84 client("avp_tpm", true),
85};
86
87static DEFINE_SPINLOCK(mc_lock);
88static unsigned long error_count = 0;
89#define MAX_PRINTS 5
90
91static void unthrottle_prints(struct work_struct *work)
92{
93 unsigned long flags;
94
95 spin_lock_irqsave(&mc_lock, flags);
96 error_count = 0;
97 spin_unlock_irqrestore(&mc_lock, flags);
98}
99
100static DECLARE_DELAYED_WORK(unthrottle_prints_work, unthrottle_prints);
101
102static irqreturn_t tegra_mc_error_isr(int irq, void *data)
103{
104 void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
105 unsigned long count;
106 u32 stat;
107
108 stat = readl(mc + MC_INT_STATUS);
109 stat &= (MC_INT_SECURITY_VIOLATION |
110 MC_INT_INVALID_GART_PAGE |
111 MC_INT_DECERR_EMEM_OTHERS);
112
113 __cancel_delayed_work(&unthrottle_prints_work);
114
115 spin_lock(&mc_lock);
116 count = ++error_count;
117 spin_unlock(&mc_lock);
118
119 if (count >= MAX_PRINTS) {
120 if (count == MAX_PRINTS)
121 pr_err("Too many MC errors; throttling prints\n");
122 schedule_delayed_work(&unthrottle_prints_work, HZ/2);
123 goto out;
124 }
125
126 if (stat & MC_INT_DECERR_EMEM_OTHERS) {
127 const struct mc_client *client = NULL;
128 u32 addr, req;
129
130 req = readl(mc + MC_DECERR_EMEM_OTHERS_STATUS);
131 addr = readl(mc + MC_DECERR_EMEM_OTHERS_ADDRESS);
132 req &= 0x3f;
133 if (req < ARRAY_SIZE(mc_clients))
134 client = &mc_clients[req];
135
136 pr_err("MC_DECERR: %p %s (%s)\n", (void*)addr,
137 (client) ? client->name : "unknown",
138 (client && client->write) ? "write" : "read");
139 }
140
141 if (stat & MC_INT_INVALID_GART_PAGE) {
142 const struct mc_client *client = NULL;
143 u32 addr, req;
144
145 req = readl(mc + MC_GART_ERROR_STATUS);
146 addr = readl(mc + MC_GART_ERROR_ADDRESS);
147 req = (req >> 1) & 0x3f;
148
149 if (req < ARRAY_SIZE(mc_clients))
150 client = &mc_clients[req];
151
152 pr_err("MC_GART_ERR: %p %s (%s)\n", (void*)addr,
153 (client) ? client->name : "unknown",
154 (client && client->write) ? "write" : "read");
155 }
156
157 if (stat & MC_INT_SECURITY_VIOLATION) {
158 const struct mc_client *client = NULL;
159 const char *type = NULL;
160 u32 addr, req;
161
162 req = readl(mc + MC_SECURITY_VIOLATION_STATUS);
163 addr = readl(mc + MC_SECURITY_VIOLATION_ADDRESS);
164
165 type = (req & (1<<30)) ? "carveout" : "trustzone";
166
167 req &= 0x3f;
168 if (req < ARRAY_SIZE(mc_clients))
169 client = &mc_clients[req];
170
171 pr_err("MC_SECURITY_ERR (%s): %p %s (%s)\n", type, (void*)addr,
172 (client) ? client->name : "unknown",
173 (client && client->write) ? "write" : "read");
174 }
175out:
176 writel(stat, mc + MC_INT_STATUS);
177 return IRQ_HANDLED;
178}
179
180void __init tegra_mc_init(void)
181{
182 if (request_irq(INT_MC_GENERAL, tegra_mc_error_isr, 0,
183 "mc_status", NULL)) {
184 pr_err("%s: unable to register MC error interrupt\n", __func__);
185 } else {
186 void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
187 u32 reg = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
188 MC_INT_DECERR_EMEM_OTHERS;
189 writel(reg, mc + MC_INT_MASK);
190 }
191}
192arch_initcall(tegra_mc_init);
diff --git a/arch/arm/mach-tegra/common-t3.c b/arch/arm/mach-tegra/common-t3.c
new file mode 100644
index 00000000000..1a9bd755e28
--- /dev/null
+++ b/arch/arm/mach-tegra/common-t3.c
@@ -0,0 +1,268 @@
1/*
2 * arch/arm/mach-tegra/common-t3.c
3 *
4 * Tegra 3 SoC-specific initialization (memory controller, etc.)
5 *
6 * Copyright (c) 2010-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/io.h>
25#include <linux/interrupt.h>
26#include <linux/spinlock.h>
27
28#include <mach/iomap.h>
29#include <mach/irqs.h>
30
31#include "tegra3_emc.h"
32
33#define MC_INT_STATUS 0x0
34#define MC_INT_MASK 0x4
35#define MC_INT_DECERR_EMEM (1<<6)
36#define MC_INT_SECURITY_VIOLATION (1<<8)
37#define MC_INT_ARBITRATION_EMEM (1<<9)
38#define MC_INT_INVALID_SMMU_PAGE (1<<10)
39
40#define MC_ERROR_STATUS 0x8
41#define MC_ERROR_ADDRESS 0xC
42
43#define MC_TIMING_REG_NUM1 \
44 ((MC_EMEM_ARB_TIMING_W2R - MC_EMEM_ARB_CFG) / 4 + 1)
45#define MC_TIMING_REG_NUM2 \
46 ((MC_EMEM_ARB_MISC1 - MC_EMEM_ARB_DA_TURNS) / 4 + 1)
47
48struct mc_client {
49 const char *name;
50};
51
52#define client(_name) \
53 { \
54 .name = _name, \
55 }
56
57
58static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
59
60
61#ifdef CONFIG_PM_SLEEP
62static u32 mc_boot_timing[MC_TIMING_REG_NUM1 + MC_TIMING_REG_NUM2 + 4];
63
64static void tegra_mc_timing_save(void)
65{
66 u32 off;
67 u32 *ctx = mc_boot_timing;
68
69 for (off = MC_EMEM_ARB_CFG; off <= MC_EMEM_ARB_TIMING_W2R; off += 4)
70 *ctx++ = readl((u32)mc + off);
71
72 for (off = MC_EMEM_ARB_DA_TURNS; off <= MC_EMEM_ARB_MISC1; off += 4)
73 *ctx++ = readl((u32)mc + off);
74
75 *ctx++ = readl((u32)mc + MC_EMEM_ARB_RING3_THROTTLE);
76 *ctx++ = readl((u32)mc + MC_EMEM_ARB_OVERRIDE);
77 *ctx++ = readl((u32)mc + MC_RESERVED_RSV);
78
79 *ctx++ = readl((u32)mc + MC_INT_MASK);
80}
81
82void tegra_mc_timing_restore(void)
83{
84 u32 off;
85 u32 *ctx = mc_boot_timing;
86
87 for (off = MC_EMEM_ARB_CFG; off <= MC_EMEM_ARB_TIMING_W2R; off += 4)
88 __raw_writel(*ctx++, (u32)mc + off);
89
90 for (off = MC_EMEM_ARB_DA_TURNS; off <= MC_EMEM_ARB_MISC1; off += 4)
91 __raw_writel(*ctx++, (u32)mc + off);
92
93 __raw_writel(*ctx++, (u32)mc + MC_EMEM_ARB_RING3_THROTTLE);
94 __raw_writel(*ctx++, (u32)mc + MC_EMEM_ARB_OVERRIDE);
95 __raw_writel(*ctx++, (u32)mc + MC_RESERVED_RSV);
96
97 writel(*ctx++, (u32)mc + MC_INT_MASK);
98 off = readl((u32)mc + MC_INT_MASK);
99
100 writel(0x1, (u32)mc + MC_TIMING_CONTROL);
101 off = readl((u32)mc + MC_TIMING_CONTROL);
102}
103#else
104#define tegra_mc_timing_save()
105#endif
106
107
108static const struct mc_client mc_clients[] = {
109 client("ptc"),
110 client("display0_wina"), client("display1_wina"),
111 client("display0_winb"), client("display1_winb"),
112 client("display0_winc"), client("display1_winc"),
113 client("display0_winb_vfilter"),
114 client("display1_winb_vfilter"),
115 client("epp"), client("gr2d_pat"),
116 client("gr2d_src"), client("mpe_unified"),
117 client("vi_chroma_filter"), client("pcie"),
118 client("avp"),
119 client("display0_cursor"), client("display1_cursor"),
120 client("gr3d0_fdc"), client("gr3d1_fdc"),
121 client("gr2d_dst"), client("hda"),
122 client("host1x_dma"), client("host1x_generic"),
123 client("gr3d0_idx"), client("gr3d1_idx"),
124 client("mpe_intrapred"), client("mpe_mpea"),
125 client("mpe_mpec"), client("ahb_dma"),
126 client("ahb_slave"), client("sata"),
127 client("gr3d0_tex"), client("gr3d1_tex"),
128 client("vde_bsev"), client("vde_mbe"),
129 client("vde_mce"), client("vde_tpe"),
130 client("cpu_lp"), client("cpu"),
131 client("epp_u"), client("epp_v"),
132 client("epp_y"), client("mpe_unified"),
133 client("vi_sb"), client("vi_u"),
134 client("vi_v"), client("vi_y"),
135 client("gr2d_dst"), client("pcie"),
136 client("avp"), client("gr3d0_fdc"),
137 client("gr3d1_fdc"), client("hda"),
138 client("host1x"), client("isp"),
139 client("cpu_lp"), client("cpu"),
140 client("mpe_mpec"), client("ahb_dma"),
141 client("ahb_slave"), client("sata"),
142 client("vde_bsev"), client("vde_dbg"),
143 client("vde_mbe"), client("vde_tpm"),
144};
145
146static const char *smmu_page_attrib[] = {
147 "SMMU: nr-nw-s",
148 "SMMU: nr-nw-ns",
149 "SMMU: nr-wr-s",
150 "SMMU: nr-wr-ns",
151 "SMMU: rd-nw-s",
152 "SMMU: rd-nw-ns",
153 "SMMU: rd-wr-s",
154 "SMMU: rd-wr-ns"
155};
156
157static DEFINE_SPINLOCK(mc_lock);
158static unsigned long error_count = 0;
159#define MAX_PRINTS 5
160
161static void unthrottle_prints(struct work_struct *work)
162{
163 unsigned long flags;
164
165 spin_lock_irqsave(&mc_lock, flags);
166 error_count = 0;
167 spin_unlock_irqrestore(&mc_lock, flags);
168}
169
170static DECLARE_DELAYED_WORK(unthrottle_prints_work, unthrottle_prints);
171
172static irqreturn_t tegra_mc_error_isr(int irq, void *data)
173{
174 const struct mc_client *client = NULL;
175 const char *mc_err;
176 const char *mc_err_info;
177 unsigned long count;
178 u32 stat;
179 u32 addr;
180 u32 err;
181 u32 type;
182 u32 is_write;
183 u32 is_secure;
184 u32 client_id;
185
186 stat = readl(mc + MC_INT_STATUS);
187 stat &= (MC_INT_DECERR_EMEM |
188 MC_INT_SECURITY_VIOLATION |
189 MC_INT_INVALID_SMMU_PAGE);
190
191 __cancel_delayed_work(&unthrottle_prints_work);
192
193 spin_lock(&mc_lock);
194 count = ++error_count;
195 spin_unlock(&mc_lock);
196
197 if (count >= MAX_PRINTS) {
198 if (count == MAX_PRINTS)
199 pr_err("Too many MC errors; throttling prints\n");
200 schedule_delayed_work(&unthrottle_prints_work, HZ/2);
201 goto out;
202 }
203
204 err = readl(mc + MC_ERROR_STATUS);
205 addr = readl(mc + MC_ERROR_ADDRESS);
206 is_write = err & (1<<16);
207 is_secure = err & (1<<17);
208 type = (err >> 28) & 7;
209 client_id = err & 0x7f;
210 if (client_id < ARRAY_SIZE(mc_clients))
211 client = &mc_clients[client_id];
212
213 if (stat & MC_INT_DECERR_EMEM)
214 mc_err = "MC_DECERR";
215 else if (stat & MC_INT_SECURITY_VIOLATION)
216 mc_err = "MC_SECURITY_ERR";
217 else if (stat & MC_INT_INVALID_SMMU_PAGE)
218 mc_err = "MC_SMMU_ERR";
219 else
220 mc_err = "unknown";
221
222 mc_err_info = "";
223 if (type == 3) {
224 mc_err_info = "SECURITY_TRUSTZONE";
225 } else if (type == 4) {
226 mc_err_info = "SECURITY_CARVEOUT";
227 } else if (type == 6) {
228 u32 attrib = (err >> 25) & 7;
229 mc_err_info = smmu_page_attrib[attrib];
230 }
231
232 pr_err("%s (0x%08X): %p %s (%s %s %s)\n", mc_err, err, (void*)addr,
233 (client) ? client->name : "unknown",
234 (is_secure)? "secure" : "non-secure",
235 (is_write) ? "write" : "read",
236 mc_err_info);
237
238out:
239 writel(stat, mc + MC_INT_STATUS);
240 return IRQ_HANDLED;
241}
242
243int __init tegra_mc_init(void)
244{
245 u32 reg;
246 int ret = 0;
247
248 reg = 0x0F7F1010;
249 writel(reg, mc + MC_RESERVED_RSV);
250
251 reg = readl(mc + MC_EMEM_ARB_OVERRIDE);
252 reg |= 3;
253 writel(reg, mc + MC_EMEM_ARB_OVERRIDE);
254
255 if (request_irq(INT_MC_GENERAL, tegra_mc_error_isr, 0,
256 "mc_status", NULL)) {
257 pr_err("%s: unable to register MC error interrupt\n", __func__);
258 ret = -ENXIO;
259 } else {
260 reg = MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION |
261 MC_INT_INVALID_SMMU_PAGE;
262 writel(reg, mc + MC_INT_MASK);
263 }
264 tegra_mc_timing_save();
265
266 return ret;
267}
268arch_initcall(tegra_mc_init);
diff --git a/arch/arm/mach-tegra/cpu-tegra.h b/arch/arm/mach-tegra/cpu-tegra.h
new file mode 100644
index 00000000000..2bba460514f
--- /dev/null
+++ b/arch/arm/mach-tegra/cpu-tegra.h
@@ -0,0 +1,86 @@
1/*
2 * arch/arm/mach-tegra/cpu-tegra.h
3 *
4 * Copyright (c) 2011-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_TEGRA_CPU_TEGRA_H
22#define __MACH_TEGRA_CPU_TEGRA_H
23
24unsigned int tegra_getspeed(unsigned int cpu);
25int tegra_cpu_set_speed_cap(unsigned int *speed_cap);
26unsigned int tegra_count_slow_cpus(unsigned long speed_limit);
27unsigned int tegra_get_slowest_cpu_n(void);
28unsigned long tegra_cpu_lowest_speed(void);
29unsigned long tegra_cpu_highest_speed(void);
30
31#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
32int tegra_throttle_init(struct mutex *cpu_lock);
33void tegra_throttle_exit(void);
34bool tegra_is_throttling(void);
35unsigned int tegra_throttle_governor_speed(unsigned int requested_speed);
36int tegra_throttle_debug_init(struct dentry *cpu_tegra_debugfs_root);
37void tegra_throttling_enable(bool enable);
38#else
39static inline int tegra_throttle_init(struct mutex *cpu_lock)
40{ return 0; }
41static inline void tegra_throttle_exit(void)
42{}
43static inline bool tegra_is_throttling(void)
44{ return false; }
45static inline unsigned int tegra_throttle_governor_speed(
46 unsigned int requested_speed)
47{ return requested_speed; }
48static inline int tegra_throttle_debug_init(
49 struct dentry *cpu_tegra_debugfs_root)
50{ return 0; }
51static inline void tegra_throttling_enable(bool enable)
52{}
53#endif /* CONFIG_TEGRA_THERMAL_THROTTLE */
54
55#if defined(CONFIG_TEGRA_AUTO_HOTPLUG) && !defined(CONFIG_ARCH_TEGRA_2x_SOC)
56int tegra_auto_hotplug_init(struct mutex *cpu_lock);
57void tegra_auto_hotplug_exit(void);
58void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend);
59#else
60static inline int tegra_auto_hotplug_init(struct mutex *cpu_lock)
61{ return 0; }
62static inline void tegra_auto_hotplug_exit(void)
63{ }
64static inline void tegra_auto_hotplug_governor(unsigned int cpu_freq,
65 bool suspend)
66{ }
67#endif
68
69#ifdef CONFIG_TEGRA_EDP_LIMITS
70bool tegra_cpu_edp_favor_up(unsigned int n, int mp_overhead);
71bool tegra_cpu_edp_favor_down(unsigned int n, int mp_overhead);
72#else
73static inline bool tegra_cpu_edp_favor_up(unsigned int n, int mp_overhead)
74{ return true; }
75static inline bool tegra_cpu_edp_favor_down(unsigned int n, int mp_overhead)
76{ return false; }
77#endif
78
79#ifdef CONFIG_CPU_FREQ
80int tegra_suspended_target(unsigned int target_freq);
81#else
82static inline int tegra_suspended_target(unsigned int target_freq)
83{ return -ENOSYS; }
84#endif
85
86#endif /* __MACH_TEGRA_CPU_TEGRA_H */
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
new file mode 100644
index 00000000000..76ff94435a1
--- /dev/null
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -0,0 +1,555 @@
1/*
2 * arch/arm/mach-tegra/cpu-tegra3.c
3 *
4 * CPU auto-hotplug for Tegra3 CPUs
5 *
6 * Copyright (c) 2011-2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/sched.h>
27#include <linux/cpufreq.h>
28#include <linux/delay.h>
29#include <linux/err.h>
30#include <linux/io.h>
31#include <linux/cpu.h>
32#include <linux/clk.h>
33#include <linux/debugfs.h>
34#include <linux/seq_file.h>
35#include <linux/pm_qos_params.h>
36
37#include "pm.h"
38#include "cpu-tegra.h"
39#include "clock.h"
40
41#define INITIAL_STATE TEGRA_HP_DISABLED
42#define UP2G0_DELAY_MS 70
43#define UP2Gn_DELAY_MS 100
44#define DOWN_DELAY_MS 2000
45
46static struct mutex *tegra3_cpu_lock;
47
48static struct workqueue_struct *hotplug_wq;
49static struct delayed_work hotplug_work;
50
51static bool no_lp;
52module_param(no_lp, bool, 0644);
53
54static unsigned long up2gn_delay;
55static unsigned long up2g0_delay;
56static unsigned long down_delay;
57module_param(up2gn_delay, ulong, 0644);
58module_param(up2g0_delay, ulong, 0644);
59module_param(down_delay, ulong, 0644);
60
61static unsigned int idle_top_freq;
62static unsigned int idle_bottom_freq;
63module_param(idle_top_freq, uint, 0644);
64module_param(idle_bottom_freq, uint, 0644);
65
66static int mp_overhead = 10;
67module_param(mp_overhead, int, 0644);
68
69static int balance_level = 75;
70module_param(balance_level, int, 0644);
71
72static struct clk *cpu_clk;
73static struct clk *cpu_g_clk;
74static struct clk *cpu_lp_clk;
75
76static struct {
77 cputime64_t time_up_total;
78 u64 last_update;
79 unsigned int up_down_count;
80} hp_stats[CONFIG_NR_CPUS + 1]; /* Append LP CPU entry at the end */
81
82static void hp_init_stats(void)
83{
84 int i;
85 u64 cur_jiffies = get_jiffies_64();
86
87 for (i = 0; i <= CONFIG_NR_CPUS; i++) {
88 hp_stats[i].time_up_total = 0;
89 hp_stats[i].last_update = cur_jiffies;
90
91 hp_stats[i].up_down_count = 0;
92 if (is_lp_cluster()) {
93 if (i == CONFIG_NR_CPUS)
94 hp_stats[i].up_down_count = 1;
95 } else {
96 if ((i < nr_cpu_ids) && cpu_online(i))
97 hp_stats[i].up_down_count = 1;
98 }
99 }
100
101}
102
103static void hp_stats_update(unsigned int cpu, bool up)
104{
105 u64 cur_jiffies = get_jiffies_64();
106 bool was_up = hp_stats[cpu].up_down_count & 0x1;
107
108 if (was_up)
109 hp_stats[cpu].time_up_total = cputime64_add(
110 hp_stats[cpu].time_up_total, cputime64_sub(
111 cur_jiffies, hp_stats[cpu].last_update));
112
113 if (was_up != up) {
114 hp_stats[cpu].up_down_count++;
115 if ((hp_stats[cpu].up_down_count & 0x1) != up) {
116 /* FIXME: sysfs user space CPU control breaks stats */
117 pr_err("tegra hotplug stats out of sync with %s CPU%d",
118 (cpu < CONFIG_NR_CPUS) ? "G" : "LP",
119 (cpu < CONFIG_NR_CPUS) ? cpu : 0);
120 hp_stats[cpu].up_down_count ^= 0x1;
121 }
122 }
123 hp_stats[cpu].last_update = cur_jiffies;
124}
125
126
127enum {
128 TEGRA_HP_DISABLED = 0,
129 TEGRA_HP_IDLE,
130 TEGRA_HP_DOWN,
131 TEGRA_HP_UP,
132};
133static int hp_state;
134
135static int hp_state_set(const char *arg, const struct kernel_param *kp)
136{
137 int ret = 0;
138 int old_state;
139
140 if (!tegra3_cpu_lock)
141 return ret;
142
143 mutex_lock(tegra3_cpu_lock);
144
145 old_state = hp_state;
146 ret = param_set_bool(arg, kp); /* set idle or disabled only */
147
148 if (ret == 0) {
149 if ((hp_state == TEGRA_HP_DISABLED) &&
150 (old_state != TEGRA_HP_DISABLED))
151 pr_info("Tegra auto-hotplug disabled\n");
152 else if (hp_state != TEGRA_HP_DISABLED) {
153 if (old_state == TEGRA_HP_DISABLED) {
154 pr_info("Tegra auto-hotplug enabled\n");
155 hp_init_stats();
156 }
157 /* catch-up with governor target speed */
158 tegra_cpu_set_speed_cap(NULL);
159 }
160 } else
161 pr_warn("%s: unable to set tegra hotplug state %s\n",
162 __func__, arg);
163
164 mutex_unlock(tegra3_cpu_lock);
165 return ret;
166}
167
168static int hp_state_get(char *buffer, const struct kernel_param *kp)
169{
170 return param_get_int(buffer, kp);
171}
172
173static struct kernel_param_ops tegra_hp_state_ops = {
174 .set = hp_state_set,
175 .get = hp_state_get,
176};
177module_param_cb(auto_hotplug, &tegra_hp_state_ops, &hp_state, 0644);
178
179
180enum {
181 TEGRA_CPU_SPEED_BALANCED,
182 TEGRA_CPU_SPEED_BIASED,
183 TEGRA_CPU_SPEED_SKEWED,
184};
185
186static noinline int tegra_cpu_speed_balance(void)
187{
188 unsigned long highest_speed = tegra_cpu_highest_speed();
189 unsigned long balanced_speed = highest_speed * balance_level / 100;
190 unsigned long skewed_speed = balanced_speed / 2;
191 unsigned int nr_cpus = num_online_cpus();
192 unsigned int max_cpus = pm_qos_request(PM_QOS_MAX_ONLINE_CPUS) ? : 4;
193 unsigned int min_cpus = pm_qos_request(PM_QOS_MIN_ONLINE_CPUS);
194
195 /* balanced: freq targets for all CPUs are above 50% of highest speed
196 biased: freq target for at least one CPU is below 50% threshold
197 skewed: freq targets for at least 2 CPUs are below 25% threshold */
198 if (((tegra_count_slow_cpus(skewed_speed) >= 2) ||
199 tegra_cpu_edp_favor_down(nr_cpus, mp_overhead) ||
200 (highest_speed <= idle_bottom_freq) || (nr_cpus > max_cpus)) &&
201 (nr_cpus > min_cpus))
202 return TEGRA_CPU_SPEED_SKEWED;
203
204 if (((tegra_count_slow_cpus(balanced_speed) >= 1) ||
205 (!tegra_cpu_edp_favor_up(nr_cpus, mp_overhead)) ||
206 (highest_speed <= idle_bottom_freq) || (nr_cpus == max_cpus)) &&
207 (nr_cpus >= min_cpus))
208 return TEGRA_CPU_SPEED_BIASED;
209
210 return TEGRA_CPU_SPEED_BALANCED;
211}
212
213static void tegra_auto_hotplug_work_func(struct work_struct *work)
214{
215 bool up = false;
216 unsigned int cpu = nr_cpu_ids;
217
218 mutex_lock(tegra3_cpu_lock);
219
220 switch (hp_state) {
221 case TEGRA_HP_DISABLED:
222 case TEGRA_HP_IDLE:
223 break;
224 case TEGRA_HP_DOWN:
225 cpu = tegra_get_slowest_cpu_n();
226 if (cpu < nr_cpu_ids) {
227 up = false;
228 queue_delayed_work(
229 hotplug_wq, &hotplug_work, down_delay);
230 hp_stats_update(cpu, false);
231 } else if (!is_lp_cluster() && !no_lp) {
232 if(!clk_set_parent(cpu_clk, cpu_lp_clk)) {
233 hp_stats_update(CONFIG_NR_CPUS, true);
234 hp_stats_update(0, false);
235 /* catch-up with governor target speed */
236 tegra_cpu_set_speed_cap(NULL);
237 } else
238 queue_delayed_work(
239 hotplug_wq, &hotplug_work, down_delay);
240 }
241 break;
242 case TEGRA_HP_UP:
243 if (is_lp_cluster() && !no_lp) {
244 if(!clk_set_parent(cpu_clk, cpu_g_clk)) {
245 hp_stats_update(CONFIG_NR_CPUS, false);
246 hp_stats_update(0, true);
247 /* catch-up with governor target speed */
248 tegra_cpu_set_speed_cap(NULL);
249 }
250 } else {
251 switch (tegra_cpu_speed_balance()) {
252 /* cpu speed is up and balanced - one more on-line */
253 case TEGRA_CPU_SPEED_BALANCED:
254 cpu = cpumask_next_zero(0, cpu_online_mask);
255 if (cpu < nr_cpu_ids) {
256 up = true;
257 hp_stats_update(cpu, true);
258 }
259 break;
260 /* cpu speed is up, but skewed - remove one core */
261 case TEGRA_CPU_SPEED_SKEWED:
262 cpu = tegra_get_slowest_cpu_n();
263 if (cpu < nr_cpu_ids) {
264 up = false;
265 hp_stats_update(cpu, false);
266 }
267 break;
268 /* cpu speed is up, but under-utilized - do nothing */
269 case TEGRA_CPU_SPEED_BIASED:
270 default:
271 break;
272 }
273 }
274 queue_delayed_work(
275 hotplug_wq, &hotplug_work, up2gn_delay);
276 break;
277 default:
278 pr_err("%s: invalid tegra hotplug state %d\n",
279 __func__, hp_state);
280 }
281 mutex_unlock(tegra3_cpu_lock);
282
283 if (cpu < nr_cpu_ids) {
284 if (up)
285 cpu_up(cpu);
286 else
287 cpu_down(cpu);
288 }
289}
290
291static int min_cpus_notify(struct notifier_block *nb, unsigned long n, void *p)
292{
293 mutex_lock(tegra3_cpu_lock);
294
295 if ((n >= 2) && is_lp_cluster()) {
296 if (!clk_set_parent(cpu_clk, cpu_g_clk)) {
297 hp_stats_update(CONFIG_NR_CPUS, false);
298 hp_stats_update(0, true);
299 }
300 }
301 /* update governor state machine */
302 tegra_cpu_set_speed_cap(NULL);
303 mutex_unlock(tegra3_cpu_lock);
304 return NOTIFY_OK;
305}
306
307static struct notifier_block min_cpus_notifier = {
308 .notifier_call = min_cpus_notify,
309};
310
311void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
312{
313 unsigned long up_delay, top_freq, bottom_freq;
314
315 if (!is_g_cluster_present())
316 return;
317
318 if (suspend && (hp_state != TEGRA_HP_DISABLED)) {
319 hp_state = TEGRA_HP_IDLE;
320
321 /* Switch to G-mode if suspend rate is high enough */
322 if (is_lp_cluster() && (cpu_freq >= idle_bottom_freq)) {
323 if (!clk_set_parent(cpu_clk, cpu_g_clk)) {
324 hp_stats_update(CONFIG_NR_CPUS, false);
325 hp_stats_update(0, true);
326 }
327 }
328 return;
329 }
330
331 if (is_lp_cluster()) {
332 up_delay = up2g0_delay;
333 top_freq = idle_top_freq;
334 bottom_freq = 0;
335 } else {
336 up_delay = up2gn_delay;
337 top_freq = idle_bottom_freq;
338 bottom_freq = idle_bottom_freq;
339 }
340
341 if (pm_qos_request(PM_QOS_MIN_ONLINE_CPUS) >= 2) {
342 if (hp_state != TEGRA_HP_UP) {
343 hp_state = TEGRA_HP_UP;
344 queue_delayed_work(
345 hotplug_wq, &hotplug_work, up_delay);
346 }
347 return;
348 }
349
350 switch (hp_state) {
351 case TEGRA_HP_DISABLED:
352 break;
353 case TEGRA_HP_IDLE:
354 if (cpu_freq > top_freq) {
355 hp_state = TEGRA_HP_UP;
356 queue_delayed_work(
357 hotplug_wq, &hotplug_work, up_delay);
358 } else if (cpu_freq <= bottom_freq) {
359 hp_state = TEGRA_HP_DOWN;
360 queue_delayed_work(
361 hotplug_wq, &hotplug_work, down_delay);
362 }
363 break;
364 case TEGRA_HP_DOWN:
365 if (cpu_freq > top_freq) {
366 hp_state = TEGRA_HP_UP;
367 queue_delayed_work(
368 hotplug_wq, &hotplug_work, up_delay);
369 } else if (cpu_freq > bottom_freq) {
370 hp_state = TEGRA_HP_IDLE;
371 }
372 break;
373 case TEGRA_HP_UP:
374 if (cpu_freq <= bottom_freq) {
375 hp_state = TEGRA_HP_DOWN;
376 queue_delayed_work(
377 hotplug_wq, &hotplug_work, down_delay);
378 } else if (cpu_freq <= top_freq) {
379 hp_state = TEGRA_HP_IDLE;
380 }
381 break;
382 default:
383 pr_err("%s: invalid tegra hotplug state %d\n",
384 __func__, hp_state);
385 BUG();
386 }
387}
388
389int tegra_auto_hotplug_init(struct mutex *cpu_lock)
390{
391 /*
392 * Not bound to the issuer CPU (=> high-priority), has rescue worker
393 * task, single-threaded, freezable.
394 */
395 hotplug_wq = alloc_workqueue(
396 "cpu-tegra3", WQ_UNBOUND | WQ_RESCUER | WQ_FREEZABLE, 1);
397 if (!hotplug_wq)
398 return -ENOMEM;
399 INIT_DELAYED_WORK(&hotplug_work, tegra_auto_hotplug_work_func);
400
401 cpu_clk = clk_get_sys(NULL, "cpu");
402 cpu_g_clk = clk_get_sys(NULL, "cpu_g");
403 cpu_lp_clk = clk_get_sys(NULL, "cpu_lp");
404 if (IS_ERR(cpu_clk) || IS_ERR(cpu_g_clk) || IS_ERR(cpu_lp_clk))
405 return -ENOENT;
406
407 idle_top_freq = clk_get_max_rate(cpu_lp_clk) / 1000;
408 idle_bottom_freq = clk_get_min_rate(cpu_g_clk) / 1000;
409
410 up2g0_delay = msecs_to_jiffies(UP2G0_DELAY_MS);
411 up2gn_delay = msecs_to_jiffies(UP2Gn_DELAY_MS);
412 down_delay = msecs_to_jiffies(DOWN_DELAY_MS);
413
414 tegra3_cpu_lock = cpu_lock;
415 hp_state = INITIAL_STATE;
416 hp_init_stats();
417 pr_info("Tegra auto-hotplug initialized: %s\n",
418 (hp_state == TEGRA_HP_DISABLED) ? "disabled" : "enabled");
419
420 if (pm_qos_add_notifier(PM_QOS_MIN_ONLINE_CPUS, &min_cpus_notifier))
421 pr_err("%s: Failed to register min cpus PM QoS notifier\n",
422 __func__);
423
424 return 0;
425}
426
427#ifdef CONFIG_DEBUG_FS
428
429static struct dentry *hp_debugfs_root;
430
431struct pm_qos_request_list min_cpu_req;
432struct pm_qos_request_list max_cpu_req;
433
434static int hp_stats_show(struct seq_file *s, void *data)
435{
436 int i;
437 u64 cur_jiffies = get_jiffies_64();
438
439 mutex_lock(tegra3_cpu_lock);
440 if (hp_state != TEGRA_HP_DISABLED) {
441 for (i = 0; i <= CONFIG_NR_CPUS; i++) {
442 bool was_up = (hp_stats[i].up_down_count & 0x1);
443 hp_stats_update(i, was_up);
444 }
445 }
446 mutex_unlock(tegra3_cpu_lock);
447
448 seq_printf(s, "%-15s ", "cpu:");
449 for (i = 0; i < CONFIG_NR_CPUS; i++) {
450 seq_printf(s, "G%-9d ", i);
451 }
452 seq_printf(s, "LP\n");
453
454 seq_printf(s, "%-15s ", "transitions:");
455 for (i = 0; i <= CONFIG_NR_CPUS; i++) {
456 seq_printf(s, "%-10u ", hp_stats[i].up_down_count);
457 }
458 seq_printf(s, "\n");
459
460 seq_printf(s, "%-15s ", "time plugged:");
461 for (i = 0; i <= CONFIG_NR_CPUS; i++) {
462 seq_printf(s, "%-10llu ",
463 cputime64_to_clock_t(hp_stats[i].time_up_total));
464 }
465 seq_printf(s, "\n");
466
467 seq_printf(s, "%-15s %llu\n", "time-stamp:",
468 cputime64_to_clock_t(cur_jiffies));
469
470 return 0;
471}
472
473static int hp_stats_open(struct inode *inode, struct file *file)
474{
475 return single_open(file, hp_stats_show, inode->i_private);
476}
477
478static const struct file_operations hp_stats_fops = {
479 .open = hp_stats_open,
480 .read = seq_read,
481 .llseek = seq_lseek,
482 .release = single_release,
483};
484
485static int min_cpus_get(void *data, u64 *val)
486{
487 *val = pm_qos_request(PM_QOS_MIN_ONLINE_CPUS);
488 return 0;
489}
490static int min_cpus_set(void *data, u64 val)
491{
492 pm_qos_update_request(&min_cpu_req, (s32)val);
493 return 0;
494}
495DEFINE_SIMPLE_ATTRIBUTE(min_cpus_fops, min_cpus_get, min_cpus_set, "%llu\n");
496
497static int max_cpus_get(void *data, u64 *val)
498{
499 *val = pm_qos_request(PM_QOS_MAX_ONLINE_CPUS);
500 return 0;
501}
502static int max_cpus_set(void *data, u64 val)
503{
504 pm_qos_update_request(&max_cpu_req, (s32)val);
505 return 0;
506}
507DEFINE_SIMPLE_ATTRIBUTE(max_cpus_fops, max_cpus_get, max_cpus_set, "%llu\n");
508
509static int __init tegra_auto_hotplug_debug_init(void)
510{
511 if (!tegra3_cpu_lock)
512 return -ENOENT;
513
514 hp_debugfs_root = debugfs_create_dir("tegra_hotplug", NULL);
515 if (!hp_debugfs_root)
516 return -ENOMEM;
517
518 pm_qos_add_request(&min_cpu_req, PM_QOS_MIN_ONLINE_CPUS,
519 PM_QOS_DEFAULT_VALUE);
520 pm_qos_add_request(&max_cpu_req, PM_QOS_MAX_ONLINE_CPUS,
521 PM_QOS_DEFAULT_VALUE);
522
523 if (!debugfs_create_file(
524 "min_cpus", S_IRUGO, hp_debugfs_root, NULL, &min_cpus_fops))
525 goto err_out;
526
527 if (!debugfs_create_file(
528 "max_cpus", S_IRUGO, hp_debugfs_root, NULL, &max_cpus_fops))
529 goto err_out;
530
531 if (!debugfs_create_file(
532 "stats", S_IRUGO, hp_debugfs_root, NULL, &hp_stats_fops))
533 goto err_out;
534
535 return 0;
536
537err_out:
538 debugfs_remove_recursive(hp_debugfs_root);
539 pm_qos_remove_request(&min_cpu_req);
540 pm_qos_remove_request(&max_cpu_req);
541 return -ENOMEM;
542}
543
544late_initcall(tegra_auto_hotplug_debug_init);
545#endif
546
547void tegra_auto_hotplug_exit(void)
548{
549 destroy_workqueue(hotplug_wq);
550#ifdef CONFIG_DEBUG_FS
551 debugfs_remove_recursive(hp_debugfs_root);
552 pm_qos_remove_request(&min_cpu_req);
553 pm_qos_remove_request(&max_cpu_req);
554#endif
555}
diff --git a/arch/arm/mach-tegra/cpuidle-t2.c b/arch/arm/mach-tegra/cpuidle-t2.c
new file mode 100644
index 00000000000..e5ff7c61f24
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-t2.c
@@ -0,0 +1,413 @@
1/*
2 * arch/arm/mach-tegra/cpuidle-t2.c
3 *
4 * CPU idle driver for Tegra2 CPUs
5 *
6 * Copyright (c) 2010-2011, NVIDIA Corporation.
7 * Copyright (c) 2011 Google, Inc.
8 * Author: Colin Cross <ccross@android.com>
9 * Gary King <gking@nvidia.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/cpu.h>
28#include <linux/cpuidle.h>
29#include <linux/debugfs.h>
30#include <linux/delay.h>
31#include <linux/init.h>
32#include <linux/interrupt.h>
33#include <linux/irq.h>
34#include <linux/io.h>
35#include <linux/sched.h>
36#include <linux/seq_file.h>
37#include <linux/slab.h>
38#include <linux/smp.h>
39#include <linux/suspend.h>
40#include <linux/tick.h>
41
42#include <asm/cpu_pm.h>
43
44#include <mach/iomap.h>
45#include <mach/irqs.h>
46
47#include "cpuidle.h"
48#include "gic.h"
49#include "pm.h"
50#include "sleep.h"
51#include "timer.h"
52
53static struct {
54 unsigned int cpu_ready_count[2];
55 unsigned long long cpu_wants_lp2_time[2];
56 unsigned long long in_lp2_time;
57 unsigned int both_idle_count;
58 unsigned int tear_down_count;
59 unsigned int lp2_count;
60 unsigned int lp2_completed_count;
61 unsigned int lp2_count_bin[32];
62 unsigned int lp2_completed_count_bin[32];
63 unsigned int lp2_int_count[NR_IRQS];
64 unsigned int last_lp2_int_count[NR_IRQS];
65} idle_stats;
66
67static inline unsigned int time_to_bin(unsigned int time)
68{
69 return fls(time);
70}
71
72#ifdef CONFIG_SMP
73
74#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4C
75#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
76
77static void __iomem *clk_rst = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
78static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
79static s64 tegra_cpu1_wake_by_time = LLONG_MAX;
80
81static int tegra2_reset_sleeping_cpu(int cpu)
82{
83 int ret = 0;
84
85 BUG_ON(cpu == 0);
86 BUG_ON(cpu == smp_processor_id());
87 tegra_pen_lock();
88
89 if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE)
90 tegra2_cpu_reset(cpu);
91 else
92 ret = -EINVAL;
93
94 tegra_pen_unlock();
95
96 return ret;
97}
98
99static void tegra2_wake_reset_cpu(int cpu)
100{
101 u32 reg;
102
103 BUG_ON(cpu == 0);
104 BUG_ON(cpu == smp_processor_id());
105
106 tegra_pen_lock();
107
108 tegra2_cpu_clear_resettable();
109
110 /* enable cpu clock on cpu */
111 reg = readl(clk_rst + 0x4c);
112 writel(reg & ~(1 << (8 + cpu)),
113 clk_rst + CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
114
115 /* take the CPU out of reset */
116 reg = 0x1111 << cpu;
117 writel(reg, clk_rst +
118 CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
119
120 /* unhalt the cpu */
121 flowctrl_writel(0, FLOW_CTRL_HALT_CPU(1));
122
123 tegra_pen_unlock();
124}
125
126static int tegra2_reset_other_cpus(int cpu)
127{
128 int i;
129 int ret = 0;
130
131 BUG_ON(cpu != 0);
132
133 for_each_online_cpu(i) {
134 if (i != cpu) {
135 if (tegra2_reset_sleeping_cpu(i)) {
136 ret = -EBUSY;
137 break;
138 }
139 }
140 }
141
142 if (ret) {
143 for_each_online_cpu(i) {
144 if (i != cpu)
145 tegra2_wake_reset_cpu(i);
146 }
147 return ret;
148 }
149
150 return 0;
151}
152#else
153static void tegra2_wake_reset_cpu(int cpu)
154{
155}
156
157static int tegra2_reset_other_cpus(int cpu)
158{
159 return 0;
160}
161#endif
162
163bool tegra2_lp2_is_allowed(struct cpuidle_device *dev,
164 struct cpuidle_state *state)
165{
166 s64 request = ktime_to_us(tick_nohz_get_sleep_length());
167
168 if (request < state->target_residency) {
169 /* Not enough time left to enter LP2 */
170 return false;
171 }
172
173 return true;
174}
175
176static inline void tegra2_lp3_fall_back(struct cpuidle_device *dev)
177{
178 /* Not enough time left to enter LP2 */
179 tegra_cpu_wfi();
180
181 /* fall back here from LP2 path - tell cpuidle governor */
182 dev->last_state = &dev->states[0];
183}
184
185static int tegra2_idle_lp2_cpu_0(struct cpuidle_device *dev,
186 struct cpuidle_state *state, s64 request)
187{
188 ktime_t entry_time;
189 ktime_t exit_time;
190 s64 wake_time;
191 bool sleep_completed = false;
192 int bin;
193 int i;
194
195 while (tegra2_cpu_is_resettable_soon())
196 cpu_relax();
197
198 if (tegra2_reset_other_cpus(dev->cpu))
199 return 0;
200
201 idle_stats.both_idle_count++;
202
203 if (request < state->target_residency) {
204 tegra2_lp3_fall_back(dev);
205 return -EBUSY;
206 }
207
208 /* LP2 entry time */
209 entry_time = ktime_get();
210
211 /* LP2 initial targeted wake time */
212 wake_time = ktime_to_us(entry_time) + request;
213
214 /* CPU0 must wake up before CPU1. */
215 smp_rmb();
216 wake_time = min_t(s64, wake_time, tegra_cpu1_wake_by_time);
217
218 /* LP2 actual targeted wake time */
219 request = wake_time - ktime_to_us(entry_time);
220 BUG_ON(wake_time < 0LL);
221
222 idle_stats.tear_down_count++;
223 entry_time = ktime_get();
224
225 if (request > state->target_residency) {
226 s64 sleep_time = request - tegra_lp2_exit_latency;
227
228 bin = time_to_bin((u32)request / 1000);
229 idle_stats.lp2_count++;
230 idle_stats.lp2_count_bin[bin]++;
231
232 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
233
234 if (tegra_idle_lp2_last(sleep_time, 0) == 0)
235 sleep_completed = true;
236 else {
237 int irq = tegra_gic_pending_interrupt();
238 idle_stats.lp2_int_count[irq]++;
239 }
240
241 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
242 }
243
244 for_each_online_cpu(i) {
245 if (i != dev->cpu)
246 tegra2_wake_reset_cpu(i);
247 }
248
249 exit_time = ktime_get();
250 if (sleep_completed) {
251 /*
252 * Stayed in LP2 for the full time until the next tick,
253 * adjust the exit latency based on measurement
254 */
255 s64 actual_time = ktime_to_us(ktime_sub(exit_time, entry_time));
256 long offset = (long)(actual_time - request);
257 int latency = tegra_lp2_exit_latency + offset / 16;
258 latency = clamp(latency, 0, 10000);
259 tegra_lp2_exit_latency = latency;
260 smp_wmb();
261
262 idle_stats.lp2_completed_count++;
263 idle_stats.lp2_completed_count_bin[bin]++;
264 idle_stats.in_lp2_time += actual_time;
265
266 pr_debug("%lld %lld %ld %d\n", request, actual_time,
267 offset, bin);
268 }
269
270 return 0;
271}
272
273static void tegra2_idle_lp2_cpu_1(struct cpuidle_device *dev,
274 struct cpuidle_state *state, s64 request)
275{
276#ifdef CONFIG_SMP
277 struct tegra_twd_context twd_context;
278
279 if (request < tegra_lp2_exit_latency) {
280 tegra2_cpu_clear_resettable();
281 tegra2_lp3_fall_back(dev);
282 return;
283 }
284
285 /* Save time this CPU must be awakened by. */
286 tegra_cpu1_wake_by_time = ktime_to_us(ktime_get()) + request;
287 smp_wmb();
288
289 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
290
291 tegra_twd_suspend(&twd_context);
292
293 tegra2_sleep_wfi(PLAT_PHYS_OFFSET - PAGE_OFFSET);
294
295 tegra2_cpu_clear_resettable();
296
297 tegra_cpu1_wake_by_time = LLONG_MAX;
298
299 tegra_twd_resume(&twd_context);
300
301 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
302#endif
303}
304
305void tegra2_idle_lp2(struct cpuidle_device *dev,
306 struct cpuidle_state *state)
307{
308 s64 request = ktime_to_us(tick_nohz_get_sleep_length());
309 bool last_cpu = tegra_set_cpu_in_lp2(dev->cpu);
310
311 cpu_pm_enter();
312
313 if (dev->cpu == 0) {
314 if (last_cpu) {
315 if (tegra2_idle_lp2_cpu_0(dev, state, request) < 0) {
316 int i;
317 for_each_online_cpu(i) {
318 if (i != dev->cpu)
319 tegra2_wake_reset_cpu(i);
320 }
321 }
322 } else {
323 tegra2_lp3_fall_back(dev);
324 }
325 } else {
326 BUG_ON(last_cpu);
327 tegra2_idle_lp2_cpu_1(dev, state, request);
328 }
329
330 cpu_pm_exit();
331 tegra_clear_cpu_in_lp2(dev->cpu);
332}
333
334void tegra2_cpu_idle_stats_lp2_ready(unsigned int cpu)
335{
336 idle_stats.cpu_ready_count[cpu]++;
337}
338
339void tegra2_cpu_idle_stats_lp2_time(unsigned int cpu, s64 us)
340{
341 idle_stats.cpu_wants_lp2_time[cpu] += us;
342}
343
344#ifdef CONFIG_DEBUG_FS
345int tegra2_lp2_debug_show(struct seq_file *s, void *data)
346{
347 int bin;
348 int i;
349 seq_printf(s, " cpu0 cpu1\n");
350 seq_printf(s, "-------------------------------------------------\n");
351 seq_printf(s, "cpu ready: %8u %8u\n",
352 idle_stats.cpu_ready_count[0],
353 idle_stats.cpu_ready_count[1]);
354 seq_printf(s, "both idle: %8u %7u%% %7u%%\n",
355 idle_stats.both_idle_count,
356 idle_stats.both_idle_count * 100 /
357 (idle_stats.cpu_ready_count[0] ?: 1),
358 idle_stats.both_idle_count * 100 /
359 (idle_stats.cpu_ready_count[1] ?: 1));
360 seq_printf(s, "tear down: %8u %7u%%\n", idle_stats.tear_down_count,
361 idle_stats.tear_down_count * 100 /
362 (idle_stats.both_idle_count ?: 1));
363 seq_printf(s, "lp2: %8u %7u%%\n", idle_stats.lp2_count,
364 idle_stats.lp2_count * 100 /
365 (idle_stats.both_idle_count ?: 1));
366 seq_printf(s, "lp2 completed: %8u %7u%%\n",
367 idle_stats.lp2_completed_count,
368 idle_stats.lp2_completed_count * 100 /
369 (idle_stats.lp2_count ?: 1));
370
371 seq_printf(s, "\n");
372 seq_printf(s, "cpu ready time: %8llu %8llu ms\n",
373 div64_u64(idle_stats.cpu_wants_lp2_time[0], 1000),
374 div64_u64(idle_stats.cpu_wants_lp2_time[1], 1000));
375 seq_printf(s, "lp2 time: %8llu ms %7d%% %7d%%\n",
376 div64_u64(idle_stats.in_lp2_time, 1000),
377 (int)div64_u64(idle_stats.in_lp2_time * 100,
378 idle_stats.cpu_wants_lp2_time[0] ?: 1),
379 (int)div64_u64(idle_stats.in_lp2_time * 100,
380 idle_stats.cpu_wants_lp2_time[1] ?: 1));
381
382 seq_printf(s, "\n");
383 seq_printf(s, "%19s %8s %8s %8s\n", "", "lp2", "comp", "%");
384 seq_printf(s, "-------------------------------------------------\n");
385 for (bin = 0; bin < 32; bin++) {
386 if (idle_stats.lp2_count_bin[bin] == 0)
387 continue;
388 seq_printf(s, "%6u - %6u ms: %8u %8u %7u%%\n",
389 1 << (bin - 1), 1 << bin,
390 idle_stats.lp2_count_bin[bin],
391 idle_stats.lp2_completed_count_bin[bin],
392 idle_stats.lp2_completed_count_bin[bin] * 100 /
393 idle_stats.lp2_count_bin[bin]);
394 }
395
396 seq_printf(s, "\n");
397 seq_printf(s, "%3s %20s %6s %10s\n",
398 "int", "name", "count", "last count");
399 seq_printf(s, "--------------------------------------------\n");
400 for (i = 0; i < NR_IRQS; i++) {
401 if (idle_stats.lp2_int_count[i] == 0)
402 continue;
403 seq_printf(s, "%3d %20s %6d %10d\n",
404 i, irq_to_desc(i)->action ?
405 irq_to_desc(i)->action->name ?: "???" : "???",
406 idle_stats.lp2_int_count[i],
407 idle_stats.lp2_int_count[i] -
408 idle_stats.last_lp2_int_count[i]);
409 idle_stats.last_lp2_int_count[i] = idle_stats.lp2_int_count[i];
410 };
411 return 0;
412}
413#endif
diff --git a/arch/arm/mach-tegra/cpuidle-t3.c b/arch/arm/mach-tegra/cpuidle-t3.c
new file mode 100644
index 00000000000..c6a50a542d8
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-t3.c
@@ -0,0 +1,532 @@
1/*
2 * arch/arm/mach-tegra/cpuidle-t3.c
3 *
4 * CPU idle driver for Tegra3 CPUs
5 *
6 * Copyright (c) 2010-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/cpu.h>
25#include <linux/cpuidle.h>
26#include <linux/debugfs.h>
27#include <linux/delay.h>
28#include <linux/hrtimer.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/irq.h>
32#include <linux/io.h>
33#include <linux/ratelimit.h>
34#include <linux/sched.h>
35#include <linux/seq_file.h>
36#include <linux/slab.h>
37#include <linux/smp.h>
38#include <linux/suspend.h>
39#include <linux/tick.h>
40#include <linux/clk.h>
41
42#include <asm/cacheflush.h>
43#include <asm/cpu_pm.h>
44#include <asm/hardware/gic.h>
45#include <asm/localtimer.h>
46
47#include <mach/iomap.h>
48#include <mach/irqs.h>
49
50#include <trace/events/power.h>
51
52#include "clock.h"
53#include "cpuidle.h"
54#include "dvfs.h"
55#include "fuse.h"
56#include "gic.h"
57#include "pm.h"
58#include "reset.h"
59#include "sleep.h"
60#include "timer.h"
61
62#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS \
63 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x470)
64#define PMC_POWERGATE_STATUS \
65 (IO_ADDRESS(TEGRA_PMC_BASE) + 0x038)
66
67#ifdef CONFIG_SMP
68static s64 tegra_cpu_wake_by_time[4] = {
69 LLONG_MAX, LLONG_MAX, LLONG_MAX, LLONG_MAX };
70#endif
71
72static bool lp2_0_in_idle = true;
73module_param(lp2_0_in_idle, bool, 0644);
74
75static bool lp2_n_in_idle = true;
76module_param(lp2_n_in_idle, bool, 0644);
77
78static struct clk *cpu_clk_for_dvfs;
79static struct clk *twd_clk;
80
81static int lp2_exit_latencies[5];
82
83static struct {
84 unsigned int cpu_ready_count[5];
85 unsigned int tear_down_count[5];
86 unsigned long long cpu_wants_lp2_time[5];
87 unsigned long long in_lp2_time[5];
88 unsigned int lp2_count;
89 unsigned int lp2_completed_count;
90 unsigned int lp2_count_bin[32];
91 unsigned int lp2_completed_count_bin[32];
92 unsigned int lp2_int_count[NR_IRQS];
93 unsigned int last_lp2_int_count[NR_IRQS];
94} idle_stats;
95
96static inline unsigned int time_to_bin(unsigned int time)
97{
98 return fls(time);
99}
100
101static inline void tegra_irq_unmask(int irq)
102{
103 struct irq_data *data = irq_get_irq_data(irq);
104 data->chip->irq_unmask(data);
105}
106
107static inline unsigned int cpu_number(unsigned int n)
108{
109 return is_lp_cluster() ? 4 : n;
110}
111
112void tegra3_cpu_idle_stats_lp2_ready(unsigned int cpu)
113{
114 idle_stats.cpu_ready_count[cpu_number(cpu)]++;
115}
116
117void tegra3_cpu_idle_stats_lp2_time(unsigned int cpu, s64 us)
118{
119 idle_stats.cpu_wants_lp2_time[cpu_number(cpu)] += us;
120}
121
122/* Allow rail off only if all secondary CPUs are power gated, and no
123 rail update is in progress */
124static bool tegra3_rail_off_is_allowed(void)
125{
126 u32 rst = readl(CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
127 u32 pg = readl(PMC_POWERGATE_STATUS) >> 8;
128
129 if (((rst & 0xE) != 0xE) || ((pg & 0xE) != 0))
130 return false;
131
132 if (tegra_dvfs_rail_updating(cpu_clk_for_dvfs))
133 return false;
134
135 return true;
136}
137
138bool tegra3_lp2_is_allowed(struct cpuidle_device *dev,
139 struct cpuidle_state *state)
140{
141 s64 request;
142
143 if (!tegra_all_cpus_booted)
144 return false;
145
146 if ((!lp2_0_in_idle && !dev->cpu) || (!lp2_n_in_idle && dev->cpu))
147 return false;
148
149 /* On A01, LP2 on slave CPU's cause ranhdom CPU hangs.
150 * Refer to Bug 804085.
151 */
152 if ((tegra_get_revision() == TEGRA_REVISION_A01) &&
153 num_online_cpus() > 1)
154 return false;
155
156#ifndef CONFIG_TEGRA_RAIL_OFF_MULTIPLE_CPUS
157 /* FIXME: All CPU's entering LP2 is not working.
158 * Don't let CPU0 enter LP2 when any secondary CPU is online.
159 */
160 if ((dev->cpu == 0) && (num_online_cpus() > 1))
161 return false;
162#endif
163 if ((dev->cpu == 0) && (!tegra3_rail_off_is_allowed()))
164 return false;
165
166 request = ktime_to_us(tick_nohz_get_sleep_length());
167 if (state->exit_latency != lp2_exit_latencies[cpu_number(dev->cpu)]) {
168 /* possible on the 1st entry after cluster switch*/
169 state->exit_latency = lp2_exit_latencies[cpu_number(dev->cpu)];
170 tegra_lp2_update_target_residency(state);
171 }
172 if (request < state->target_residency) {
173 /* Not enough time left to enter LP2 */
174 return false;
175 }
176
177 return true;
178}
179
180static inline void tegra3_lp3_fall_back(struct cpuidle_device *dev)
181{
182 tegra_cpu_wfi();
183 /* fall back here from LP2 path - tell cpuidle governor */
184 dev->last_state = &dev->states[0];
185}
186
187static inline void tegra3_lp2_restore_affinity(void)
188{
189#ifdef CONFIG_SMP
190 /* Disable the distributor. */
191 tegra_gic_dist_disable();
192
193 /* Restore the other CPU's interrupt affinity. */
194 tegra_gic_restore_affinity();
195
196 /* Re-enable the distributor. */
197 tegra_gic_dist_enable();
198#endif
199}
200
201static void tegra3_idle_enter_lp2_cpu_0(struct cpuidle_device *dev,
202 struct cpuidle_state *state, s64 request)
203{
204 ktime_t entry_time;
205 ktime_t exit_time;
206 bool sleep_completed = false;
207 bool multi_cpu_entry = false;
208 int bin;
209 s64 sleep_time;
210
211 /* LP2 entry time */
212 entry_time = ktime_get();
213
214 if (request < state->target_residency) {
215 /* Not enough time left to enter LP2 */
216 tegra3_lp3_fall_back(dev);
217 return;
218 }
219
220#ifdef CONFIG_SMP
221 multi_cpu_entry = !is_lp_cluster() && (num_online_cpus() > 1);
222 if (multi_cpu_entry) {
223 s64 wake_time;
224 unsigned int i;
225
226 /* Disable the distributor -- this is the only way to
227 prevent the other CPUs from responding to interrupts
228 and potentially fiddling with the distributor
229 registers while we're fiddling with them. */
230 tegra_gic_dist_disable();
231
232 /* Did an interrupt come in for another CPU before we
233 could disable the distributor? */
234 if (!tegra3_rail_off_is_allowed()) {
235 /* Yes, re-enable the distributor and LP3. */
236 tegra_gic_dist_enable();
237 tegra3_lp3_fall_back(dev);
238 return;
239 }
240
241 /* LP2 initial targeted wake time */
242 wake_time = ktime_to_us(entry_time) + request;
243
244 /* CPU0 must wake up before any of the other CPUs. */
245 smp_rmb();
246 for (i = 1; i < CONFIG_NR_CPUS; i++)
247 wake_time = min_t(s64, wake_time,
248 tegra_cpu_wake_by_time[i]);
249
250 /* LP2 actual targeted wake time */
251 request = wake_time - ktime_to_us(entry_time);
252 BUG_ON(wake_time < 0LL);
253
254 if (request < state->target_residency) {
255 /* Not enough time left to enter LP2 */
256 tegra_gic_dist_enable();
257 tegra3_lp3_fall_back(dev);
258 return;
259 }
260
261 /* Cancel LP2 wake timers for all secondary CPUs */
262 tegra_lp2_timer_cancel_secondary();
263
264 /* Save and disable the affinity setting for the other
265 CPUs and route all interrupts to CPU0. */
266 tegra_gic_disable_affinity();
267
268 /* Re-enable the distributor. */
269 tegra_gic_dist_enable();
270 }
271#endif
272
273 sleep_time = request -
274 lp2_exit_latencies[cpu_number(dev->cpu)];
275
276 bin = time_to_bin((u32)request / 1000);
277 idle_stats.tear_down_count[cpu_number(dev->cpu)]++;
278 idle_stats.lp2_count++;
279 idle_stats.lp2_count_bin[bin]++;
280
281 trace_power_start(POWER_CSTATE, 2, dev->cpu);
282 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
283 if (!is_lp_cluster())
284 tegra_dvfs_rail_off(tegra_cpu_rail, entry_time);
285
286 if (tegra_idle_lp2_last(sleep_time, 0) == 0)
287 sleep_completed = true;
288 else {
289 int irq = tegra_gic_pending_interrupt();
290 idle_stats.lp2_int_count[irq]++;
291 }
292
293 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
294 exit_time = ktime_get();
295 if (!is_lp_cluster())
296 tegra_dvfs_rail_on(tegra_cpu_rail, exit_time);
297 idle_stats.in_lp2_time[cpu_number(dev->cpu)] +=
298 ktime_to_us(ktime_sub(exit_time, entry_time));
299
300 if (multi_cpu_entry)
301 tegra3_lp2_restore_affinity();
302
303 if (sleep_completed) {
304 /*
305 * Stayed in LP2 for the full time until the next tick,
306 * adjust the exit latency based on measurement
307 */
308 int offset = ktime_to_us(ktime_sub(exit_time, entry_time))
309 - request;
310 int latency = lp2_exit_latencies[cpu_number(dev->cpu)] +
311 offset / 16;
312 latency = clamp(latency, 0, 10000);
313 lp2_exit_latencies[cpu_number(dev->cpu)] = latency;
314 state->exit_latency = latency; /* for idle governor */
315 smp_wmb();
316
317 idle_stats.lp2_completed_count++;
318 idle_stats.lp2_completed_count_bin[bin]++;
319
320 pr_debug("%lld %lld %d %d\n", request,
321 ktime_to_us(ktime_sub(exit_time, entry_time)),
322 offset, bin);
323 }
324}
325
326static void tegra3_idle_enter_lp2_cpu_n(struct cpuidle_device *dev,
327 struct cpuidle_state *state, s64 request)
328{
329#ifdef CONFIG_SMP
330 s64 sleep_time;
331 ktime_t entry_time;
332 struct tegra_twd_context twd_context;
333 bool sleep_completed = false;
334 struct tick_sched *ts = tick_get_tick_sched(dev->cpu);
335
336 if (!tegra_twd_get_state(&twd_context)) {
337 unsigned long twd_rate = clk_get_rate(twd_clk);
338
339 if ((twd_context.twd_ctrl & TWD_TIMER_CONTROL_ENABLE) &&
340 (twd_context.twd_ctrl & TWD_TIMER_CONTROL_IT_ENABLE)) {
341 request = div_u64((u64)twd_context.twd_cnt * 1000000,
342 twd_rate);
343#ifdef CONFIG_TEGRA_LP2_ARM_TWD
344 if (request >= state->target_residency) {
345 twd_context.twd_cnt -= state->exit_latency *
346 (twd_rate / 1000000);
347 writel(twd_context.twd_cnt,
348 twd_base + TWD_TIMER_COUNTER);
349 }
350#endif
351 }
352 }
353
354 if (!tegra_is_lp2_timer_ready(dev->cpu) ||
355 (request < state->target_residency) ||
356 (!ts) || (ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
357 /*
358 * Not enough time left to enter LP2, or wake timer not ready
359 */
360 tegra3_lp3_fall_back(dev);
361 return;
362 }
363
364#ifndef CONFIG_TEGRA_LP2_ARM_TWD
365 sleep_time = request - state->exit_latency;
366 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
367 tegra_twd_suspend(&twd_context);
368 tegra_lp2_set_trigger(sleep_time);
369#endif
370 idle_stats.tear_down_count[cpu_number(dev->cpu)]++;
371
372 trace_power_start(POWER_CSTATE, 2, dev->cpu);
373
374 entry_time = ktime_get();
375
376 /* Save time this CPU must be awakened by. */
377 tegra_cpu_wake_by_time[dev->cpu] = ktime_to_us(entry_time) + request;
378 smp_wmb();
379
380 tegra3_sleep_cpu_secondary(PLAT_PHYS_OFFSET - PAGE_OFFSET);
381
382 tegra_cpu_wake_by_time[dev->cpu] = LLONG_MAX;
383
384#ifdef CONFIG_TEGRA_LP2_ARM_TWD
385 if (!tegra_twd_get_state(&twd_context))
386 sleep_completed = (twd_context.twd_cnt == 0);
387#else
388 sleep_completed = !tegra_lp2_timer_remain();
389 tegra_lp2_set_trigger(0);
390 tegra_twd_resume(&twd_context);
391 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
392#endif
393 sleep_time = ktime_to_us(ktime_sub(ktime_get(), entry_time));
394 idle_stats.in_lp2_time[cpu_number(dev->cpu)] += sleep_time;
395 if (sleep_completed) {
396 /*
397 * Stayed in LP2 for the full time until timer expires,
398 * adjust the exit latency based on measurement
399 */
400 int offset = sleep_time - request;
401 int latency = lp2_exit_latencies[cpu_number(dev->cpu)] +
402 offset / 16;
403 latency = clamp(latency, 0, 10000);
404 lp2_exit_latencies[cpu_number(dev->cpu)] = latency;
405 state->exit_latency = latency; /* for idle governor */
406 smp_wmb();
407 }
408#endif
409}
410
411void tegra3_idle_lp2(struct cpuidle_device *dev,
412 struct cpuidle_state *state)
413{
414 s64 request = ktime_to_us(tick_nohz_get_sleep_length());
415 bool last_cpu = tegra_set_cpu_in_lp2(dev->cpu);
416
417 cpu_pm_enter();
418
419 if (dev->cpu == 0) {
420 if (last_cpu)
421 tegra3_idle_enter_lp2_cpu_0(dev, state, request);
422 else
423 tegra3_lp3_fall_back(dev);
424 } else
425 tegra3_idle_enter_lp2_cpu_n(dev, state, request);
426
427 cpu_pm_exit();
428 tegra_clear_cpu_in_lp2(dev->cpu);
429}
430
431int tegra3_cpudile_init_soc(void)
432{
433 int i;
434
435 cpu_clk_for_dvfs = tegra_get_clock_by_name("cpu_g");
436 twd_clk = tegra_get_clock_by_name("twd");
437
438 for (i = 0; i < ARRAY_SIZE(lp2_exit_latencies); i++)
439 lp2_exit_latencies[i] = tegra_lp2_exit_latency;
440
441 return 0;
442}
443
444#ifdef CONFIG_DEBUG_FS
445int tegra3_lp2_debug_show(struct seq_file *s, void *data)
446{
447 int bin;
448 int i;
449 seq_printf(s, " cpu0 cpu1 cpu2 cpu3 cpulp\n");
450 seq_printf(s, "-----------------------------------------------------------------------------\n");
451 seq_printf(s, "cpu ready: %8u %8u %8u %8u %8u\n",
452 idle_stats.cpu_ready_count[0],
453 idle_stats.cpu_ready_count[1],
454 idle_stats.cpu_ready_count[2],
455 idle_stats.cpu_ready_count[3],
456 idle_stats.cpu_ready_count[4]);
457 seq_printf(s, "tear down: %8u %8u %8u %8u %8u\n",
458 idle_stats.tear_down_count[0],
459 idle_stats.tear_down_count[1],
460 idle_stats.tear_down_count[2],
461 idle_stats.tear_down_count[3],
462 idle_stats.tear_down_count[4]);
463 seq_printf(s, "lp2: %8u\n", idle_stats.lp2_count);
464 seq_printf(s, "lp2 completed: %8u %7u%%\n",
465 idle_stats.lp2_completed_count,
466 idle_stats.lp2_completed_count * 100 /
467 (idle_stats.lp2_count ?: 1));
468
469 seq_printf(s, "\n");
470 seq_printf(s, "cpu ready time: %8llu %8llu %8llu %8llu %8llu ms\n",
471 div64_u64(idle_stats.cpu_wants_lp2_time[0], 1000),
472 div64_u64(idle_stats.cpu_wants_lp2_time[1], 1000),
473 div64_u64(idle_stats.cpu_wants_lp2_time[2], 1000),
474 div64_u64(idle_stats.cpu_wants_lp2_time[3], 1000),
475 div64_u64(idle_stats.cpu_wants_lp2_time[4], 1000));
476
477 seq_printf(s, "lp2 time: %8llu %8llu %8llu %8llu %8llu ms\n",
478 div64_u64(idle_stats.in_lp2_time[0], 1000),
479 div64_u64(idle_stats.in_lp2_time[1], 1000),
480 div64_u64(idle_stats.in_lp2_time[2], 1000),
481 div64_u64(idle_stats.in_lp2_time[3], 1000),
482 div64_u64(idle_stats.in_lp2_time[4], 1000));
483
484 seq_printf(s, "lp2 %%: %7d%% %7d%% %7d%% %7d%% %7d%%\n",
485 (int)(idle_stats.cpu_wants_lp2_time[0] ?
486 div64_u64(idle_stats.in_lp2_time[0] * 100,
487 idle_stats.cpu_wants_lp2_time[0]) : 0),
488 (int)(idle_stats.cpu_wants_lp2_time[1] ?
489 div64_u64(idle_stats.in_lp2_time[1] * 100,
490 idle_stats.cpu_wants_lp2_time[1]) : 0),
491 (int)(idle_stats.cpu_wants_lp2_time[2] ?
492 div64_u64(idle_stats.in_lp2_time[2] * 100,
493 idle_stats.cpu_wants_lp2_time[2]) : 0),
494 (int)(idle_stats.cpu_wants_lp2_time[3] ?
495 div64_u64(idle_stats.in_lp2_time[3] * 100,
496 idle_stats.cpu_wants_lp2_time[3]) : 0),
497 (int)(idle_stats.cpu_wants_lp2_time[4] ?
498 div64_u64(idle_stats.in_lp2_time[4] * 100,
499 idle_stats.cpu_wants_lp2_time[4]) : 0));
500 seq_printf(s, "\n");
501
502 seq_printf(s, "%19s %8s %8s %8s\n", "", "lp2", "comp", "%");
503 seq_printf(s, "-------------------------------------------------\n");
504 for (bin = 0; bin < 32; bin++) {
505 if (idle_stats.lp2_count_bin[bin] == 0)
506 continue;
507 seq_printf(s, "%6u - %6u ms: %8u %8u %7u%%\n",
508 1 << (bin - 1), 1 << bin,
509 idle_stats.lp2_count_bin[bin],
510 idle_stats.lp2_completed_count_bin[bin],
511 idle_stats.lp2_completed_count_bin[bin] * 100 /
512 idle_stats.lp2_count_bin[bin]);
513 }
514
515 seq_printf(s, "\n");
516 seq_printf(s, "%3s %20s %6s %10s\n",
517 "int", "name", "count", "last count");
518 seq_printf(s, "--------------------------------------------\n");
519 for (i = 0; i < NR_IRQS; i++) {
520 if (idle_stats.lp2_int_count[i] == 0)
521 continue;
522 seq_printf(s, "%3d %20s %6d %10d\n",
523 i, irq_to_desc(i)->action ?
524 irq_to_desc(i)->action->name ?: "???" : "???",
525 idle_stats.lp2_int_count[i],
526 idle_stats.lp2_int_count[i] -
527 idle_stats.last_lp2_int_count[i]);
528 idle_stats.last_lp2_int_count[i] = idle_stats.lp2_int_count[i];
529 };
530 return 0;
531}
532#endif
diff --git a/arch/arm/mach-tegra/csi.c b/arch/arm/mach-tegra/csi.c
new file mode 100644
index 00000000000..3b26c7ae223
--- /dev/null
+++ b/arch/arm/mach-tegra/csi.c
@@ -0,0 +1,84 @@
1/*
2 * arch/arm/mach-tegra/csi.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/string.h>
19#include <linux/err.h>
20#include <linux/clk.h>
21#include <linux/io.h>
22
23#include <mach/iomap.h>
24#include <mach/csi.h>
25
26#include "clock.h"
27
28static struct clk *vi_clk;
29static struct clk *csi_clk;
30
31int tegra_vi_csi_writel(u32 val, u32 offset)
32{
33 if (vi_clk == NULL) {
34 vi_clk = tegra_get_clock_by_name("vi");
35 if (IS_ERR_OR_NULL(vi_clk)) {
36 pr_err("vi: can't get vi clock\n");
37 return -EINVAL;
38 }
39 }
40 clk_enable(vi_clk);
41
42 if (csi_clk == NULL) {
43 csi_clk = tegra_get_clock_by_name("csi");
44 if (IS_ERR_OR_NULL(csi_clk)) {
45 pr_err("csi: can't get csi clock\n");
46 return -EINVAL;
47 }
48 }
49 clk_enable(csi_clk);
50
51 writel(val, IO_TO_VIRT(TEGRA_VI_BASE) + offset * 4);
52
53 clk_disable(csi_clk);
54 clk_disable(vi_clk);
55 return 0;
56}
57
58int tegra_vi_csi_readl(u32 offset, u32 *val)
59{
60 if (vi_clk == NULL) {
61 vi_clk = tegra_get_clock_by_name("vi");
62 if (IS_ERR_OR_NULL(vi_clk)) {
63 pr_err("vi: can't get vi clock\n");
64 return -EINVAL;
65 }
66 }
67 clk_enable(vi_clk);
68
69 if (csi_clk == NULL) {
70 csi_clk = tegra_get_clock_by_name("csi");
71 if (IS_ERR_OR_NULL(csi_clk)) {
72 pr_err("csi: can't get csi clock\n");
73 return -EINVAL;
74 }
75 }
76 clk_enable(csi_clk);
77
78 *val = readl(IO_TO_VIRT(TEGRA_VI_BASE) + offset * 4);
79
80 clk_disable(csi_clk);
81 clk_disable(vi_clk);
82
83 return 0;
84}
diff --git a/arch/arm/mach-tegra/delay.S b/arch/arm/mach-tegra/delay.S
new file mode 100644
index 00000000000..76bfafa76eb
--- /dev/null
+++ b/arch/arm/mach-tegra/delay.S
@@ -0,0 +1,52 @@
1/*
2 * arch/arm/mach-tegra/delay.S
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/linkage.h>
21#include <asm/assembler.h>
22#include <mach/iomap.h>
23#include <mach/io.h>
24
25#include "asm_macros.h"
26
27 .text
28
29ENTRY(__udelay)
30ENTRY(__const_udelay)
31 mov32 r3, (IO_PPSB_VIRT + TEGRA_TMRUS_BASE - IO_PPSB_PHYS)
32 ldr r1, [r3]
33
34/* r0 - usecs to wait
35 * r1 - initial value of the counter
36 */
37loop:
38 ldr r2, [r3]
39 sub r2, r2, r1
40 cmp r2, r0
41 bls loop
42 mov pc, lr
43ENDPROC(__const_udelay)
44ENDPROC(__udelay)
45
46
47@ Delay routine
48ENTRY(__delay)
49 subs r0, r0, #1
50 bhi __delay
51 mov pc, lr
52ENDPROC(__delay)
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
new file mode 100644
index 00000000000..202c767550e
--- /dev/null
+++ b/arch/arm/mach-tegra/devices.c
@@ -0,0 +1,1692 @@
1/*
2 * Copyright (C) 2010,2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.com>
6 * Erik Gilling <ccross@android.com>
7 *
8 * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
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
22#include <linux/resource.h>
23#include <linux/dma-mapping.h>
24#include <linux/fsl_devices.h>
25#include <linux/serial_8250.h>
26#include <linux/i2c-tegra.h>
27#include <linux/platform_data/tegra_usb.h>
28#include <linux/tegra_avp.h>
29#include <linux/nvhost.h>
30#include <linux/clk.h>
31#include <asm/pmu.h>
32#include <mach/irqs.h>
33#include <mach/iomap.h>
34#include <mach/dma.h>
35#include <mach/usb_phy.h>
36#include <mach/tegra_smmu.h>
37
38#include "gpio-names.h"
39#include "devices.h"
40
41static struct resource i2c_resource1[] = {
42 [0] = {
43 .start = INT_I2C,
44 .end = INT_I2C,
45 .flags = IORESOURCE_IRQ,
46 },
47 [1] = {
48 .start = TEGRA_I2C_BASE,
49 .end = TEGRA_I2C_BASE + TEGRA_I2C_SIZE-1,
50 .flags = IORESOURCE_MEM,
51 },
52};
53
54static struct resource i2c_resource2[] = {
55 [0] = {
56 .start = INT_I2C2,
57 .end = INT_I2C2,
58 .flags = IORESOURCE_IRQ,
59 },
60 [1] = {
61 .start = TEGRA_I2C2_BASE,
62 .end = TEGRA_I2C2_BASE + TEGRA_I2C2_SIZE-1,
63 .flags = IORESOURCE_MEM,
64 },
65};
66
67static struct resource i2c_resource3[] = {
68 [0] = {
69 .start = INT_I2C3,
70 .end = INT_I2C3,
71 .flags = IORESOURCE_IRQ,
72 },
73 [1] = {
74 .start = TEGRA_I2C3_BASE,
75 .end = TEGRA_I2C3_BASE + TEGRA_I2C3_SIZE-1,
76 .flags = IORESOURCE_MEM,
77 },
78};
79
80#ifdef CONFIG_ARCH_TEGRA_2x_SOC
81static struct resource i2c_resource4[] = {
82 [0] = {
83 .start = INT_DVC,
84 .end = INT_DVC,
85 .flags = IORESOURCE_IRQ,
86 },
87 [1] = {
88 .start = TEGRA_DVC_BASE,
89 .end = TEGRA_DVC_BASE + TEGRA_DVC_SIZE-1,
90 .flags = IORESOURCE_MEM,
91 },
92};
93
94#else
95static struct resource i2c_resource4[] = {
96 [0] = {
97 .start = INT_I2C4,
98 .end = INT_I2C4,
99 .flags = IORESOURCE_IRQ,
100 },
101 [1] = {
102 .start = TEGRA_I2C4_BASE,
103 .end = TEGRA_I2C4_BASE + TEGRA_I2C4_SIZE-1,
104 .flags = IORESOURCE_MEM,
105 },
106};
107
108static struct resource i2c_resource5[] = {
109 [0] = {
110 .start = INT_I2C5,
111 .end = INT_I2C5,
112 .flags = IORESOURCE_IRQ,
113 },
114 [1] = {
115 .start = TEGRA_I2C5_BASE,
116 .end = TEGRA_I2C5_BASE + TEGRA_I2C5_SIZE-1,
117 .flags = IORESOURCE_MEM,
118 },
119};
120#endif
121
122static struct tegra_i2c_platform_data tegra_i2c1_platform_data = {
123 .bus_clk_rate = { 400000 },
124};
125
126static struct tegra_i2c_platform_data tegra_i2c2_platform_data = {
127 .bus_clk_rate = { 400000 },
128};
129
130static struct tegra_i2c_platform_data tegra_i2c3_platform_data = {
131 .bus_clk_rate = { 400000 },
132};
133
134static struct tegra_i2c_platform_data tegra_dvc_platform_data = {
135 .bus_clk_rate = { 400000 },
136};
137
138struct platform_device tegra_i2c_device1 = {
139 .name = "tegra-i2c",
140 .id = 0,
141 .resource = i2c_resource1,
142 .num_resources = ARRAY_SIZE(i2c_resource1),
143 .dev = {
144 .platform_data = &tegra_i2c1_platform_data,
145 },
146};
147
148struct platform_device tegra_i2c_device2 = {
149 .name = "tegra-i2c",
150 .id = 1,
151 .resource = i2c_resource2,
152 .num_resources = ARRAY_SIZE(i2c_resource2),
153 .dev = {
154 .platform_data = &tegra_i2c2_platform_data,
155 },
156};
157
158struct platform_device tegra_i2c_device3 = {
159 .name = "tegra-i2c",
160 .id = 2,
161 .resource = i2c_resource3,
162 .num_resources = ARRAY_SIZE(i2c_resource3),
163 .dev = {
164 .platform_data = &tegra_i2c3_platform_data,
165 },
166};
167
168struct platform_device tegra_i2c_device4 = {
169 .name = "tegra-i2c",
170 .id = 3,
171 .resource = i2c_resource4,
172 .num_resources = ARRAY_SIZE(i2c_resource4),
173 .dev = {
174 .platform_data = &tegra_dvc_platform_data,
175 },
176};
177
178#ifndef CONFIG_ARCH_TEGRA_2x_SOC
179struct platform_device tegra_i2c_device5 = {
180 .name = "tegra-i2c",
181 .id = 4,
182 .resource = i2c_resource5,
183 .num_resources = ARRAY_SIZE(i2c_resource5),
184 .dev = {
185 .platform_data = 0,
186 },
187};
188#endif
189
190static struct resource spi_resource1[] = {
191 [0] = {
192 .start = INT_SPI_1,
193 .end = INT_SPI_1,
194 .flags = IORESOURCE_IRQ,
195 },
196 [1] = {
197 .start = TEGRA_SPI1_BASE,
198 .end = TEGRA_SPI1_BASE + TEGRA_SPI1_SIZE-1,
199 .flags = IORESOURCE_MEM,
200 },
201};
202
203static struct resource spi_resource2[] = {
204 [0] = {
205 .start = INT_SPI_2,
206 .end = INT_SPI_2,
207 .flags = IORESOURCE_IRQ,
208 },
209 [1] = {
210 .start = TEGRA_SPI2_BASE,
211 .end = TEGRA_SPI2_BASE + TEGRA_SPI2_SIZE-1,
212 .flags = IORESOURCE_MEM,
213 },
214};
215
216static struct resource spi_resource3[] = {
217 [0] = {
218 .start = INT_SPI_3,
219 .end = INT_SPI_3,
220 .flags = IORESOURCE_IRQ,
221 },
222 [1] = {
223 .start = TEGRA_SPI3_BASE,
224 .end = TEGRA_SPI3_BASE + TEGRA_SPI3_SIZE-1,
225 .flags = IORESOURCE_MEM,
226 },
227};
228
229static struct resource spi_resource4[] = {
230 [0] = {
231 .start = INT_SPI_4,
232 .end = INT_SPI_4,
233 .flags = IORESOURCE_IRQ,
234 },
235 [1] = {
236 .start = TEGRA_SPI4_BASE,
237 .end = TEGRA_SPI4_BASE + TEGRA_SPI4_SIZE-1,
238 .flags = IORESOURCE_MEM,
239 },
240};
241#ifndef CONFIG_ARCH_TEGRA_2x_SOC
242static struct resource spi_resource5[] = {
243 [0] = {
244 .start = INT_SPI_5,
245 .end = INT_SPI_5,
246 .flags = IORESOURCE_IRQ,
247 },
248 [1] = {
249 .start = TEGRA_SPI5_BASE,
250 .end = TEGRA_SPI5_BASE + TEGRA_SPI5_SIZE-1,
251 .flags = IORESOURCE_MEM,
252 },
253};
254
255static struct resource spi_resource6[] = {
256 [0] = {
257 .start = INT_SPI_6,
258 .end = INT_SPI_6,
259 .flags = IORESOURCE_IRQ,
260 },
261 [1] = {
262 .start = TEGRA_SPI6_BASE,
263 .end = TEGRA_SPI6_BASE + TEGRA_SPI6_SIZE-1,
264 .flags = IORESOURCE_MEM,
265 },
266};
267#endif
268
269#ifndef CONFIG_ARCH_TEGRA_2x_SOC
270static struct resource dtv_resource[] = {
271 [0] = {
272 .start = INT_DTV,
273 .end = INT_DTV,
274 .flags = IORESOURCE_IRQ,
275 },
276 [1] = {
277 .start = TEGRA_DTV_BASE,
278 .end = TEGRA_DTV_BASE + TEGRA_DTV_SIZE - 1,
279 .flags = IORESOURCE_MEM,
280 },
281 [2] = {
282 .start = TEGRA_DMA_REQ_SEL_DTV,
283 .end = TEGRA_DMA_REQ_SEL_DTV,
284 .flags = IORESOURCE_DMA
285 },
286};
287#endif
288
289
290struct platform_device tegra_spi_device1 = {
291 .name = "spi_tegra",
292 .id = 0,
293 .resource = spi_resource1,
294 .num_resources = ARRAY_SIZE(spi_resource1),
295 .dev = {
296 .coherent_dma_mask = 0xffffffff,
297 },
298};
299
300struct platform_device tegra_spi_device2 = {
301 .name = "spi_tegra",
302 .id = 1,
303 .resource = spi_resource2,
304 .num_resources = ARRAY_SIZE(spi_resource2),
305 .dev = {
306 .coherent_dma_mask = 0xffffffff,
307 },
308};
309
310struct platform_device tegra_spi_device3 = {
311 .name = "spi_tegra",
312 .id = 2,
313 .resource = spi_resource3,
314 .num_resources = ARRAY_SIZE(spi_resource3),
315 .dev = {
316 .coherent_dma_mask = 0xffffffff,
317 },
318};
319
320struct platform_device tegra_spi_device4 = {
321 .name = "spi_tegra",
322 .id = 3,
323 .resource = spi_resource4,
324 .num_resources = ARRAY_SIZE(spi_resource4),
325 .dev = {
326 .coherent_dma_mask = 0xffffffff,
327 },
328};
329#ifndef CONFIG_ARCH_TEGRA_2x_SOC
330struct platform_device tegra_spi_device5 = {
331 .name = "spi_tegra",
332 .id = 4,
333 .resource = spi_resource5,
334 .num_resources = ARRAY_SIZE(spi_resource5),
335 .dev = {
336 .coherent_dma_mask = 0xffffffff,
337 },
338};
339
340struct platform_device tegra_spi_device6 = {
341 .name = "spi_tegra",
342 .id = 5,
343 .resource = spi_resource6,
344 .num_resources = ARRAY_SIZE(spi_resource6),
345 .dev = {
346 .coherent_dma_mask = 0xffffffff,
347 },
348};
349#endif
350
351struct platform_device tegra_spi_slave_device1 = {
352 .name = "spi_slave_tegra",
353 .id = 0,
354 .resource = spi_resource1,
355 .num_resources = ARRAY_SIZE(spi_resource1),
356 .dev = {
357 .coherent_dma_mask = 0xffffffff,
358 },
359};
360
361struct platform_device tegra_spi_slave_device2 = {
362 .name = "spi_slave_tegra",
363 .id = 1,
364 .resource = spi_resource2,
365 .num_resources = ARRAY_SIZE(spi_resource2),
366 .dev = {
367 .coherent_dma_mask = 0xffffffff,
368 },
369};
370
371struct platform_device tegra_spi_slave_device3 = {
372 .name = "spi_slave_tegra",
373 .id = 2,
374 .resource = spi_resource3,
375 .num_resources = ARRAY_SIZE(spi_resource3),
376 .dev = {
377 .coherent_dma_mask = 0xffffffff,
378 },
379};
380
381struct platform_device tegra_spi_slave_device4 = {
382 .name = "spi_slave_tegra",
383 .id = 3,
384 .resource = spi_resource4,
385 .num_resources = ARRAY_SIZE(spi_resource4),
386 .dev = {
387 .coherent_dma_mask = 0xffffffff,
388 },
389};
390#ifndef CONFIG_ARCH_TEGRA_2x_SOC
391struct platform_device tegra_spi_slave_device5 = {
392 .name = "spi_slave_tegra",
393 .id = 4,
394 .resource = spi_resource5,
395 .num_resources = ARRAY_SIZE(spi_resource5),
396 .dev = {
397 .coherent_dma_mask = 0xffffffff,
398 },
399};
400
401struct platform_device tegra_spi_slave_device6 = {
402 .name = "spi_slave_tegra",
403 .id = 5,
404 .resource = spi_resource6,
405 .num_resources = ARRAY_SIZE(spi_resource6),
406 .dev = {
407 .coherent_dma_mask = 0xffffffff,
408 },
409};
410#endif
411
412static struct resource resources_nor[] = {
413 [0] = {
414 .start = INT_SNOR,
415 .end = INT_SNOR,
416 .flags = IORESOURCE_IRQ,
417 },
418 [1] = {
419 /* Map SNOR Controller */
420 .start = TEGRA_SNOR_BASE,
421 .end = TEGRA_SNOR_BASE + TEGRA_SNOR_SIZE - 1,
422 .flags = IORESOURCE_MEM,
423 },
424 [2] = {
425 /* Map the size of flash */
426 .start = TEGRA_NOR_FLASH_BASE,
427 .end = TEGRA_NOR_FLASH_BASE + TEGRA_NOR_FLASH_SIZE - 1,
428 .flags = IORESOURCE_MEM,
429 }
430};
431
432struct platform_device tegra_nor_device = {
433 .name = "tegra-nor",
434 .id = -1,
435 .num_resources = ARRAY_SIZE(resources_nor),
436 .resource = resources_nor,
437 .dev = {
438 .coherent_dma_mask = 0xffffffff,
439 },
440};
441
442#ifndef CONFIG_ARCH_TEGRA_2x_SOC
443struct platform_device tegra_dtv_device = {
444 .name = "tegra_dtv",
445 .id = -1,
446 .resource = dtv_resource,
447 .num_resources = ARRAY_SIZE(dtv_resource),
448 .dev = {
449 .init_name = "dtv",
450 .coherent_dma_mask = 0xffffffff,
451 },
452};
453#endif
454
455static struct resource sdhci_resource1[] = {
456 [0] = {
457 .start = INT_SDMMC1,
458 .end = INT_SDMMC1,
459 .flags = IORESOURCE_IRQ,
460 },
461 [1] = {
462 .start = TEGRA_SDMMC1_BASE,
463 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
464 .flags = IORESOURCE_MEM,
465 },
466};
467
468static struct resource sdhci_resource2[] = {
469 [0] = {
470 .start = INT_SDMMC2,
471 .end = INT_SDMMC2,
472 .flags = IORESOURCE_IRQ,
473 },
474 [1] = {
475 .start = TEGRA_SDMMC2_BASE,
476 .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1,
477 .flags = IORESOURCE_MEM,
478 },
479};
480
481static struct resource sdhci_resource3[] = {
482 [0] = {
483 .start = INT_SDMMC3,
484 .end = INT_SDMMC3,
485 .flags = IORESOURCE_IRQ,
486 },
487 [1] = {
488 .start = TEGRA_SDMMC3_BASE,
489 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
490 .flags = IORESOURCE_MEM,
491 },
492};
493
494static struct resource sdhci_resource4[] = {
495 [0] = {
496 .start = INT_SDMMC4,
497 .end = INT_SDMMC4,
498 .flags = IORESOURCE_IRQ,
499 },
500 [1] = {
501 .start = TEGRA_SDMMC4_BASE,
502 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
503 .flags = IORESOURCE_MEM,
504 },
505};
506
507struct platform_device tegra_pci_device = {
508 .name = "tegra-pcie",
509 .id = 0,
510 .resource = 0,
511 .num_resources = 0,
512 .dev = {
513 .platform_data = 0,
514 },
515};
516
517/* board files should fill in platform_data register the devices themselvs.
518 * See board-harmony.c for an example
519 */
520struct platform_device tegra_sdhci_device1 = {
521 .name = "sdhci-tegra",
522 .id = 0,
523 .resource = sdhci_resource1,
524 .num_resources = ARRAY_SIZE(sdhci_resource1),
525};
526
527struct platform_device tegra_sdhci_device2 = {
528 .name = "sdhci-tegra",
529 .id = 1,
530 .resource = sdhci_resource2,
531 .num_resources = ARRAY_SIZE(sdhci_resource2),
532};
533
534struct platform_device tegra_sdhci_device3 = {
535 .name = "sdhci-tegra",
536 .id = 2,
537 .resource = sdhci_resource3,
538 .num_resources = ARRAY_SIZE(sdhci_resource3),
539};
540
541struct platform_device tegra_sdhci_device4 = {
542 .name = "sdhci-tegra",
543 .id = 3,
544 .resource = sdhci_resource4,
545 .num_resources = ARRAY_SIZE(sdhci_resource4),
546};
547
548static struct resource tegra_usb1_resources[] = {
549 [0] = {
550 .start = TEGRA_USB_BASE,
551 .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
552 .flags = IORESOURCE_MEM,
553 },
554 [1] = {
555 .start = INT_USB,
556 .end = INT_USB,
557 .flags = IORESOURCE_IRQ,
558 },
559};
560
561static struct resource tegra_usb2_resources[] = {
562 [0] = {
563 .start = TEGRA_USB2_BASE,
564 .end = TEGRA_USB2_BASE + TEGRA_USB2_SIZE - 1,
565 .flags = IORESOURCE_MEM,
566 },
567 [1] = {
568 .start = INT_USB2,
569 .end = INT_USB2,
570 .flags = IORESOURCE_IRQ,
571 },
572};
573
574static struct resource tegra_usb3_resources[] = {
575 [0] = {
576 .start = TEGRA_USB3_BASE,
577 .end = TEGRA_USB3_BASE + TEGRA_USB3_SIZE - 1,
578 .flags = IORESOURCE_MEM,
579 },
580 [1] = {
581 .start = INT_USB3,
582 .end = INT_USB3,
583 .flags = IORESOURCE_IRQ,
584 },
585};
586
587static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
588 /* All existing boards use GPIO PV0 for phy reset */
589 .reset_gpio = TEGRA_GPIO_PV0,
590 .clk = "cdev2",
591};
592
593static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
594 .operating_mode = TEGRA_USB_OTG,
595 .power_down_on_bus_suspend = 1,
596};
597
598static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
599 .phy_config = &tegra_ehci2_ulpi_phy_config,
600 .operating_mode = TEGRA_USB_HOST,
601 .power_down_on_bus_suspend = 1,
602};
603
604static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
605 .operating_mode = TEGRA_USB_HOST,
606 .power_down_on_bus_suspend = 1,
607};
608
609static u64 tegra_ehci_dmamask = DMA_BIT_MASK(32);
610
611struct platform_device tegra_ehci1_device = {
612 .name = "tegra-ehci",
613 .id = 0,
614 .dev = {
615 .dma_mask = &tegra_ehci_dmamask,
616 .coherent_dma_mask = DMA_BIT_MASK(32),
617 .platform_data = &tegra_ehci1_pdata,
618 },
619 .resource = tegra_usb1_resources,
620 .num_resources = ARRAY_SIZE(tegra_usb1_resources),
621};
622
623struct platform_device tegra_ehci2_device = {
624 .name = "tegra-ehci",
625 .id = 1,
626 .dev = {
627 .dma_mask = &tegra_ehci_dmamask,
628 .coherent_dma_mask = DMA_BIT_MASK(32),
629 .platform_data = &tegra_ehci2_pdata,
630 },
631 .resource = tegra_usb2_resources,
632 .num_resources = ARRAY_SIZE(tegra_usb2_resources),
633};
634
635struct platform_device tegra_ehci3_device = {
636 .name = "tegra-ehci",
637 .id = 2,
638 .dev = {
639 .dma_mask = &tegra_ehci_dmamask,
640 .coherent_dma_mask = DMA_BIT_MASK(32),
641 .platform_data = &tegra_ehci3_pdata,
642 },
643 .resource = tegra_usb3_resources,
644 .num_resources = ARRAY_SIZE(tegra_usb3_resources),
645};
646
647static struct resource tegra_pmu_resources[] = {
648 [0] = {
649 .start = INT_CPU0_PMU_INTR,
650 .end = INT_CPU0_PMU_INTR,
651 .flags = IORESOURCE_IRQ,
652 },
653 [1] = {
654 .start = INT_CPU1_PMU_INTR,
655 .end = INT_CPU1_PMU_INTR,
656 .flags = IORESOURCE_IRQ,
657 },
658#ifndef CONFIG_ARCH_TEGRA_2x_SOC
659 [2] = {
660 .start = INT_CPU2_PMU_INTR,
661 .end = INT_CPU2_PMU_INTR,
662 .flags = IORESOURCE_IRQ,
663 },
664 [3] = {
665 .start = INT_CPU3_PMU_INTR,
666 .end = INT_CPU3_PMU_INTR,
667 .flags = IORESOURCE_IRQ,
668 },
669#endif
670};
671
672struct platform_device tegra_pmu_device = {
673 .name = "arm-pmu",
674 .id = ARM_PMU_DEVICE_CPU,
675 .num_resources = ARRAY_SIZE(tegra_pmu_resources),
676 .resource = tegra_pmu_resources,
677};
678
679static struct resource tegra_uarta_resources[] = {
680 [0] = {
681 .start = TEGRA_UARTA_BASE,
682 .end = TEGRA_UARTA_BASE + TEGRA_UARTA_SIZE - 1,
683 .flags = IORESOURCE_MEM,
684 },
685 [1] = {
686 .start = INT_UARTA,
687 .end = INT_UARTA,
688 .flags = IORESOURCE_IRQ,
689 },
690};
691
692static struct resource tegra_uartb_resources[] = {
693 [0] = {
694 .start = TEGRA_UARTB_BASE,
695 .end = TEGRA_UARTB_BASE + TEGRA_UARTB_SIZE - 1,
696 .flags = IORESOURCE_MEM,
697 },
698 [1] = {
699 .start = INT_UARTB,
700 .end = INT_UARTB,
701 .flags = IORESOURCE_IRQ,
702 },
703};
704
705static struct resource tegra_uartc_resources[] = {
706 [0] = {
707 .start = TEGRA_UARTC_BASE,
708 .end = TEGRA_UARTC_BASE + TEGRA_UARTC_SIZE - 1,
709 .flags = IORESOURCE_MEM,
710 },
711 [1] = {
712 .start = INT_UARTC,
713 .end = INT_UARTC,
714 .flags = IORESOURCE_IRQ,
715 },
716};
717
718static struct resource tegra_uartd_resources[] = {
719 [0] = {
720 .start = TEGRA_UARTD_BASE,
721 .end = TEGRA_UARTD_BASE + TEGRA_UARTD_SIZE - 1,
722 .flags = IORESOURCE_MEM,
723 },
724 [1] = {
725 .start = INT_UARTD,
726 .end = INT_UARTD,
727 .flags = IORESOURCE_IRQ,
728 },
729};
730
731static struct resource tegra_uarte_resources[] = {
732 [0] = {
733 .start = TEGRA_UARTE_BASE,
734 .end = TEGRA_UARTE_BASE + TEGRA_UARTE_SIZE - 1,
735 .flags = IORESOURCE_MEM,
736 },
737 [1] = {
738 .start = INT_UARTE,
739 .end = INT_UARTE,
740 .flags = IORESOURCE_IRQ,
741 },
742};
743
744struct platform_device tegra_uarta_device = {
745 .name = "tegra_uart",
746 .id = 0,
747 .num_resources = ARRAY_SIZE(tegra_uarta_resources),
748 .resource = tegra_uarta_resources,
749 .dev = {
750 .coherent_dma_mask = DMA_BIT_MASK(32),
751 },
752};
753
754struct platform_device tegra_uartb_device = {
755 .name = "tegra_uart",
756 .id = 1,
757 .num_resources = ARRAY_SIZE(tegra_uartb_resources),
758 .resource = tegra_uartb_resources,
759 .dev = {
760 .coherent_dma_mask = DMA_BIT_MASK(32),
761 },
762};
763
764struct platform_device tegra_uartc_device = {
765 .name = "tegra_uart",
766 .id = 2,
767 .num_resources = ARRAY_SIZE(tegra_uartc_resources),
768 .resource = tegra_uartc_resources,
769 .dev = {
770 .coherent_dma_mask = DMA_BIT_MASK(32),
771 },
772};
773
774struct platform_device tegra_uartd_device = {
775 .name = "tegra_uart",
776 .id = 3,
777 .num_resources = ARRAY_SIZE(tegra_uartd_resources),
778 .resource = tegra_uartd_resources,
779 .dev = {
780 .coherent_dma_mask = DMA_BIT_MASK(32),
781 },
782};
783
784struct platform_device tegra_uarte_device = {
785 .name = "tegra_uart",
786 .id = 4,
787 .num_resources = ARRAY_SIZE(tegra_uarte_resources),
788 .resource = tegra_uarte_resources,
789 .dev = {
790 .coherent_dma_mask = DMA_BIT_MASK(32),
791 },
792};
793
794static struct plat_serial8250_port debug_uarta_platform_data[] = {
795 {
796 .membase = IO_ADDRESS(TEGRA_UARTA_BASE),
797 .mapbase = TEGRA_UARTA_BASE,
798 .irq = INT_UARTA,
799 .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
800 .type = PORT_TEGRA,
801 .iotype = UPIO_MEM,
802 .regshift = 2,
803 },
804 {
805 .flags = 0,
806 },
807};
808
809static struct plat_serial8250_port debug_uartb_platform_data[] = {
810 {
811 .membase = IO_ADDRESS(TEGRA_UARTB_BASE),
812 .mapbase = TEGRA_UARTB_BASE,
813 .irq = INT_UARTB,
814 .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
815 .type = PORT_TEGRA,
816 .iotype = UPIO_MEM,
817 .regshift = 2,
818 },
819 {
820 .flags = 0,
821 },
822};
823
824static struct plat_serial8250_port debug_uartc_platform_data[] = {
825 {
826 .membase = IO_ADDRESS(TEGRA_UARTC_BASE),
827 .mapbase = TEGRA_UARTC_BASE,
828 .irq = INT_UARTC,
829 .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
830 .type = PORT_TEGRA,
831 .iotype = UPIO_MEM,
832 .regshift = 2,
833 },
834 {
835 .flags = 0,
836 },
837};
838
839static struct plat_serial8250_port debug_uartd_platform_data[] = {
840 {
841 .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
842 .mapbase = TEGRA_UARTD_BASE,
843 .irq = INT_UARTD,
844 .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
845 .type = PORT_TEGRA,
846 .iotype = UPIO_MEM,
847 .regshift = 2,
848 },
849 {
850 .flags = 0,
851 },
852};
853
854#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
855static struct plat_serial8250_port debug_uarte_platform_data[] = {
856 {
857 .membase = IO_ADDRESS(TEGRA_UARTE_BASE),
858 .mapbase = TEGRA_UARTE_BASE,
859 .irq = INT_UARTE,
860 .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
861 .type = PORT_TEGRA,
862 .iotype = UPIO_MEM,
863 .regshift = 2,
864 },
865 {
866 .flags = 0,
867 },
868};
869#endif
870
871struct platform_device debug_uarta_device = {
872 .name = "serial8250",
873 .id = PLAT8250_DEV_PLATFORM,
874 .dev = {
875 .platform_data = debug_uarta_platform_data,
876 },
877};
878
879struct platform_device debug_uartb_device = {
880 .name = "serial8250",
881 .id = PLAT8250_DEV_PLATFORM,
882 .dev = {
883 .platform_data = debug_uartb_platform_data,
884 },
885};
886
887struct platform_device debug_uartc_device = {
888 .name = "serial8250",
889 .id = PLAT8250_DEV_PLATFORM,
890 .dev = {
891 .platform_data = debug_uartc_platform_data,
892 },
893};
894
895struct platform_device debug_uartd_device = {
896 .name = "serial8250",
897 .id = PLAT8250_DEV_PLATFORM,
898 .dev = {
899 .platform_data = debug_uartd_platform_data,
900 },
901};
902
903#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
904struct platform_device debug_uarte_device = {
905 .name = "serial8250",
906 .id = PLAT8250_DEV_PLATFORM,
907 .dev = {
908 .platform_data = debug_uarte_platform_data,
909 },
910};
911#endif
912
913#ifdef CONFIG_ARCH_TEGRA_2x_SOC
914static struct resource i2s_resource1[] = {
915 [0] = {
916 .start = INT_I2S1,
917 .end = INT_I2S1,
918 .flags = IORESOURCE_IRQ
919 },
920 [1] = {
921 .start = TEGRA_DMA_REQ_SEL_I2S_1,
922 .end = TEGRA_DMA_REQ_SEL_I2S_1,
923 .flags = IORESOURCE_DMA
924 },
925 [2] = {
926 .start = TEGRA_I2S1_BASE,
927 .end = TEGRA_I2S1_BASE + TEGRA_I2S1_SIZE - 1,
928 .flags = IORESOURCE_MEM
929 }
930};
931
932struct platform_device tegra_i2s_device1 = {
933 .name = "tegra20-i2s",
934 .id = 0,
935 .resource = i2s_resource1,
936 .num_resources = ARRAY_SIZE(i2s_resource1),
937};
938
939static struct resource i2s_resource2[] = {
940 [0] = {
941 .start = INT_I2S2,
942 .end = INT_I2S2,
943 .flags = IORESOURCE_IRQ
944 },
945 [1] = {
946 .start = TEGRA_DMA_REQ_SEL_I2S2_1,
947 .end = TEGRA_DMA_REQ_SEL_I2S2_1,
948 .flags = IORESOURCE_DMA
949 },
950 [2] = {
951 .start = TEGRA_I2S2_BASE,
952 .end = TEGRA_I2S2_BASE + TEGRA_I2S2_SIZE - 1,
953 .flags = IORESOURCE_MEM
954 }
955};
956
957struct platform_device tegra_i2s_device2 = {
958 .name = "tegra20-i2s",
959 .id = 1,
960 .resource = i2s_resource2,
961 .num_resources = ARRAY_SIZE(i2s_resource2),
962};
963#else
964static struct resource i2s_resource0[] = {
965 [0] = {
966 .start = TEGRA_I2S0_BASE,
967 .end = TEGRA_I2S0_BASE + TEGRA_I2S0_SIZE - 1,
968 .flags = IORESOURCE_MEM
969 }
970};
971
972struct platform_device tegra_i2s_device0 = {
973 .name = "tegra30-i2s",
974 .id = 0,
975 .resource = i2s_resource0,
976 .num_resources = ARRAY_SIZE(i2s_resource0),
977};
978
979static struct resource i2s_resource1[] = {
980 [0] = {
981 .start = TEGRA_I2S1_BASE,
982 .end = TEGRA_I2S1_BASE + TEGRA_I2S1_SIZE - 1,
983 .flags = IORESOURCE_MEM
984 }
985};
986
987struct platform_device tegra_i2s_device1 = {
988 .name = "tegra30-i2s",
989 .id = 1,
990 .resource = i2s_resource1,
991 .num_resources = ARRAY_SIZE(i2s_resource1),
992};
993
994static struct resource i2s_resource2[] = {
995 [0] = {
996 .start = TEGRA_I2S2_BASE,
997 .end = TEGRA_I2S2_BASE + TEGRA_I2S2_SIZE - 1,
998 .flags = IORESOURCE_MEM
999 }
1000};
1001
1002struct platform_device tegra_i2s_device2 = {
1003 .name = "tegra30-i2s",
1004 .id = 2,
1005 .resource = i2s_resource2,
1006 .num_resources = ARRAY_SIZE(i2s_resource2),
1007};
1008
1009static struct resource i2s_resource3[] = {
1010 [0] = {
1011 .start = TEGRA_I2S3_BASE,
1012 .end = TEGRA_I2S3_BASE + TEGRA_I2S3_SIZE - 1,
1013 .flags = IORESOURCE_MEM
1014 }
1015};
1016
1017struct platform_device tegra_i2s_device3 = {
1018 .name = "tegra30-i2s",
1019 .id = 3,
1020 .resource = i2s_resource3,
1021 .num_resources = ARRAY_SIZE(i2s_resource3),
1022};
1023
1024static struct resource i2s_resource4[] = {
1025 [0] = {
1026 .start = TEGRA_I2S4_BASE,
1027 .end = TEGRA_I2S4_BASE + TEGRA_I2S4_SIZE - 1,
1028 .flags = IORESOURCE_MEM
1029 }
1030};
1031
1032struct platform_device tegra_i2s_device4 = {
1033 .name = "tegra30-i2s",
1034 .id = 4,
1035 .resource = i2s_resource4,
1036 .num_resources = ARRAY_SIZE(i2s_resource4),
1037};
1038#endif
1039
1040#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1041static struct resource spdif_resource[] = {
1042 [0] = {
1043 .start = INT_SPDIF,
1044 .end = INT_SPDIF,
1045 .flags = IORESOURCE_IRQ
1046 },
1047 [1] = {
1048 .start = TEGRA_DMA_REQ_SEL_SPD_I,
1049 .end = TEGRA_DMA_REQ_SEL_SPD_I,
1050 .flags = IORESOURCE_DMA
1051 },
1052 [2] = {
1053 .start = TEGRA_SPDIF_BASE,
1054 .end = TEGRA_SPDIF_BASE + TEGRA_SPDIF_SIZE - 1,
1055 .flags = IORESOURCE_MEM
1056 }
1057};
1058
1059struct platform_device tegra_spdif_device = {
1060 .name = "tegra20-spdif",
1061 .id = -1,
1062 .resource = spdif_resource,
1063 .num_resources = ARRAY_SIZE(spdif_resource),
1064};
1065#else
1066static struct resource spdif_resource[] = {
1067 [0] = {
1068 .start = TEGRA_SPDIF_BASE,
1069 .end = TEGRA_SPDIF_BASE + TEGRA_SPDIF_SIZE - 1,
1070 .flags = IORESOURCE_MEM
1071 }
1072};
1073
1074struct platform_device tegra_spdif_device = {
1075 .name = "tegra30-spdif",
1076 .id = -1,
1077 .resource = spdif_resource,
1078 .num_resources = ARRAY_SIZE(spdif_resource),
1079};
1080#endif
1081
1082#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1083static struct resource ahub_resource[] = {
1084 [0] = {
1085 .start = TEGRA_APBIF0_BASE,
1086 .end = TEGRA_APBIF3_BASE + TEGRA_APBIF3_SIZE - 1,
1087 .flags = IORESOURCE_MEM
1088 },
1089 [1] = {
1090 .start = TEGRA_AHUB_BASE,
1091 .end = TEGRA_AHUB_BASE + TEGRA_AHUB_SIZE - 1,
1092 .flags = IORESOURCE_MEM
1093 }
1094};
1095
1096struct platform_device tegra_ahub_device = {
1097 .name = "tegra30-ahub",
1098 .id = -1,
1099 .resource = ahub_resource,
1100 .num_resources = ARRAY_SIZE(ahub_resource),
1101};
1102
1103static struct resource dam_resource0[] = {
1104 [0] = {
1105 .start = TEGRA_DAM0_BASE,
1106 .end = TEGRA_DAM0_BASE + TEGRA_DAM0_SIZE - 1,
1107 .flags = IORESOURCE_MEM
1108 }
1109};
1110
1111struct platform_device tegra_dam_device0 = {
1112 .name = "tegra30-dam",
1113 .id = 0,
1114 .resource = dam_resource0,
1115 .num_resources = ARRAY_SIZE(dam_resource0),
1116};
1117
1118static struct resource dam_resource1[] = {
1119 [0] = {
1120 .start = TEGRA_DAM1_BASE,
1121 .end = TEGRA_DAM1_BASE + TEGRA_DAM1_SIZE - 1,
1122 .flags = IORESOURCE_MEM
1123 }
1124};
1125
1126struct platform_device tegra_dam_device1 = {
1127 .name = "tegra30-dam",
1128 .id = 1,
1129 .resource = dam_resource1,
1130 .num_resources = ARRAY_SIZE(dam_resource1),
1131};
1132
1133static struct resource dam_resource2[] = {
1134 [0] = {
1135 .start = TEGRA_DAM2_BASE,
1136 .end = TEGRA_DAM2_BASE + TEGRA_DAM2_SIZE - 1,
1137 .flags = IORESOURCE_MEM
1138 }
1139};
1140
1141struct platform_device tegra_dam_device2 = {
1142 .name = "tegra30-dam",
1143 .id = 2,
1144 .resource = dam_resource2,
1145 .num_resources = ARRAY_SIZE(dam_resource2),
1146};
1147
1148static u64 tegra_hda_dma_mask = DMA_BIT_MASK(32);
1149static struct resource hda_platform_resources[] = {
1150 [0] = {
1151 .start = TEGRA_HDA_BASE,
1152 .end = TEGRA_HDA_BASE + TEGRA_HDA_SIZE - 1,
1153 .flags = IORESOURCE_MEM
1154 },
1155 [1] = {
1156 .start = INT_HDA,
1157 .end = INT_HDA,
1158 .flags = IORESOURCE_IRQ
1159 },
1160};
1161
1162struct platform_device tegra_hda_device = {
1163 .name = "tegra30-hda",
1164 .id = -1,
1165 .dev = {
1166 .coherent_dma_mask = DMA_BIT_MASK(32),
1167 .dma_mask = &tegra_hda_dma_mask,
1168 },
1169 .resource = hda_platform_resources,
1170 .num_resources = ARRAY_SIZE(hda_platform_resources),
1171};
1172#endif
1173
1174struct platform_device spdif_dit_device = {
1175 .name = "spdif-dit",
1176 .id = 0,
1177};
1178
1179struct platform_device bluetooth_dit_device = {
1180 .name = "spdif-dit",
1181 .id = 1,
1182};
1183
1184struct platform_device baseband_dit_device = {
1185 .name = "spdif-dit",
1186 .id = 2,
1187};
1188
1189struct platform_device tegra_pcm_device = {
1190 .name = "tegra-pcm-audio",
1191 .id = -1,
1192};
1193
1194static struct resource w1_resources[] = {
1195 [0] = {
1196 .start = INT_OWR,
1197 .end = INT_OWR,
1198 .flags = IORESOURCE_IRQ
1199 },
1200 [1] = {
1201 .start = TEGRA_OWR_BASE,
1202 .end = TEGRA_OWR_BASE + TEGRA_OWR_SIZE - 1,
1203 .flags = IORESOURCE_MEM
1204 }
1205};
1206
1207struct platform_device tegra_w1_device = {
1208 .name = "tegra_w1",
1209 .id = -1,
1210 .resource = w1_resources,
1211 .num_resources = ARRAY_SIZE(w1_resources),
1212};
1213
1214static struct resource tegra_udc_resources[] = {
1215 [0] = {
1216 .start = TEGRA_USB_BASE,
1217 .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
1218 .flags = IORESOURCE_MEM,
1219 },
1220 [1] = {
1221 .start = INT_USB,
1222 .end = INT_USB,
1223 .flags = IORESOURCE_IRQ,
1224 },
1225};
1226
1227static u64 tegra_udc_dmamask = DMA_BIT_MASK(32);
1228
1229static struct fsl_usb2_platform_data tegra_udc_pdata = {
1230 .operating_mode = FSL_USB2_DR_DEVICE,
1231 .phy_mode = FSL_USB2_PHY_UTMI,
1232};
1233
1234struct platform_device tegra_udc_device = {
1235 .name = "fsl-tegra-udc",
1236 .id = -1,
1237 .dev = {
1238 .dma_mask = &tegra_udc_dmamask,
1239 .coherent_dma_mask = DMA_BIT_MASK(32),
1240 .platform_data = &tegra_udc_pdata,
1241 },
1242 .resource = tegra_udc_resources,
1243 .num_resources = ARRAY_SIZE(tegra_udc_resources),
1244};
1245
1246static struct resource tegra_otg_resources[] = {
1247 [0] = {
1248 .start = TEGRA_USB_BASE,
1249 .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
1250 .flags = IORESOURCE_MEM,
1251 },
1252 [1] = {
1253 .start = INT_USB,
1254 .end = INT_USB,
1255 .flags = IORESOURCE_IRQ,
1256 },
1257};
1258
1259struct platform_device tegra_otg_device = {
1260 .name = "tegra-otg",
1261 .id = -1,
1262 .resource = tegra_otg_resources,
1263 .num_resources = ARRAY_SIZE(tegra_otg_resources),
1264};
1265
1266#ifdef CONFIG_SATA_AHCI_TEGRA
1267static u64 tegra_sata_dma_mask = DMA_BIT_MASK(32);
1268
1269static struct resource tegra_sata_resources[] = {
1270 [0] = {
1271 .start = TEGRA_SATA_BAR5_BASE,
1272 .end = TEGRA_SATA_BAR5_BASE + TEGRA_SATA_BAR5_SIZE - 1,
1273 .flags = IORESOURCE_MEM,
1274 },
1275 [1] = {
1276 .start = TEGRA_SATA_CONFIG_BASE,
1277 .end = TEGRA_SATA_CONFIG_BASE + TEGRA_SATA_CONFIG_SIZE - 1,
1278 .flags = IORESOURCE_MEM,
1279 },
1280 [2] = {
1281 .start = INT_SATA_CTL,
1282 .end = INT_SATA_CTL,
1283 .flags = IORESOURCE_IRQ,
1284 },
1285};
1286
1287struct platform_device tegra_sata_device = {
1288 .name = "tegra-sata",
1289 .id = 0,
1290 .dev = {
1291 .platform_data = 0,
1292 .coherent_dma_mask = DMA_BIT_MASK(32),
1293 .dma_mask = &tegra_sata_dma_mask,
1294 },
1295 .resource = tegra_sata_resources,
1296 .num_resources = ARRAY_SIZE(tegra_sata_resources),
1297};
1298#endif
1299
1300#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1301static struct resource das_resource[] = {
1302 [0] = {
1303 .start = TEGRA_APB_MISC_DAS_BASE,
1304 .end = TEGRA_APB_MISC_DAS_BASE + TEGRA_APB_MISC_DAS_SIZE - 1,
1305 .flags = IORESOURCE_MEM
1306 }
1307};
1308
1309struct platform_device tegra_das_device = {
1310 .name = "tegra20-das",
1311 .id = -1,
1312 .resource = das_resource,
1313 .num_resources = ARRAY_SIZE(das_resource),
1314};
1315#endif
1316
1317#if defined(CONFIG_TEGRA_IOVMM_GART) || defined(CONFIG_TEGRA_IOMMU_GART)
1318static struct resource tegra_gart_resources[] = {
1319 [0] = {
1320 .name = "mc",
1321 .flags = IORESOURCE_MEM,
1322 .start = TEGRA_MC_BASE,
1323 .end = TEGRA_MC_BASE + TEGRA_MC_SIZE - 1,
1324 },
1325 [1] = {
1326 .name = "gart",
1327 .flags = IORESOURCE_MEM,
1328 .start = TEGRA_GART_BASE,
1329 .end = TEGRA_GART_BASE + TEGRA_GART_SIZE - 1,
1330 }
1331};
1332
1333struct platform_device tegra_gart_device = {
1334 .name = "tegra_gart",
1335 .id = -1,
1336 .num_resources = ARRAY_SIZE(tegra_gart_resources),
1337 .resource = tegra_gart_resources
1338};
1339#endif
1340
1341#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
1342static struct resource tegra_smmu_resources[] = {
1343 [0] = {
1344 .name = "mc",
1345 .flags = IORESOURCE_MEM,
1346 .start = TEGRA_MC_BASE,
1347 .end = TEGRA_MC_BASE + TEGRA_MC_SIZE - 1,
1348 },
1349 [1] = {
1350 .name = "ahbarb",
1351 .flags = IORESOURCE_MEM,
1352 .start = TEGRA_AHB_ARB_BASE,
1353 .end = TEGRA_AHB_ARB_BASE + TEGRA_AHB_ARB_SIZE - 1,
1354 }
1355};
1356
1357struct platform_device tegra_smmu_device = {
1358 .name = "tegra_smmu",
1359 .id = -1,
1360 .num_resources = ARRAY_SIZE(tegra_smmu_resources),
1361 .resource = tegra_smmu_resources
1362};
1363
1364
1365static struct tegra_smmu_window tegra_smmu[] = {
1366 [0] = {
1367 .start = TEGRA_SMMU_BASE,
1368 .end = TEGRA_SMMU_BASE + TEGRA_SMMU_SIZE - 1,
1369 },
1370};
1371
1372struct tegra_smmu_window *tegra_smmu_window(int wnum)
1373{
1374 return &tegra_smmu[wnum];
1375}
1376
1377int tegra_smmu_window_count(void)
1378{
1379 return ARRAY_SIZE(tegra_smmu);
1380}
1381#endif
1382
1383#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
1384#define CLK_RESET_RST_SOURCE 0x0
1385static struct resource tegra_wdt_resources[] = {
1386 [0] = {
1387 .start = TEGRA_CLK_RESET_BASE + CLK_RESET_RST_SOURCE,
1388 .end = TEGRA_CLK_RESET_BASE + CLK_RESET_RST_SOURCE + 4 - 1,
1389 .flags = IORESOURCE_MEM,
1390 },
1391 [1] = {
1392 .start = TEGRA_TMR1_BASE,
1393 .end = TEGRA_TMR1_BASE + TEGRA_TMR1_SIZE - 1,
1394 .flags = IORESOURCE_MEM,
1395 },
1396 [2] = {
1397 .start = INT_TMR1,
1398 .end = INT_TMR1,
1399 .flags = IORESOURCE_IRQ,
1400 },
1401};
1402#else
1403static struct resource tegra_wdt_resources[] = {
1404 [0] = {
1405 .start = TEGRA_WDT0_BASE,
1406 .end = TEGRA_WDT0_BASE + TEGRA_WDT0_SIZE - 1,
1407 .flags = IORESOURCE_MEM,
1408 },
1409 [1] = {
1410 .start = TEGRA_TMR10_BASE,
1411 .end = TEGRA_TMR10_BASE + TEGRA_TMR10_SIZE - 1,
1412 .flags = IORESOURCE_MEM,
1413 },
1414 [2] = {
1415 .start = INT_WDT_CPU,
1416 .end = INT_WDT_CPU,
1417 .flags = IORESOURCE_IRQ,
1418 },
1419};
1420#endif
1421
1422struct platform_device tegra_wdt_device = {
1423 .name = "tegra_wdt",
1424 .id = -1,
1425 .num_resources = ARRAY_SIZE(tegra_wdt_resources),
1426 .resource = tegra_wdt_resources,
1427};
1428
1429static struct resource tegra_pwfm0_resource = {
1430 .start = TEGRA_PWFM0_BASE,
1431 .end = TEGRA_PWFM0_BASE + TEGRA_PWFM0_SIZE - 1,
1432 .flags = IORESOURCE_MEM,
1433};
1434
1435static struct resource tegra_pwfm1_resource = {
1436 .start = TEGRA_PWFM1_BASE,
1437 .end = TEGRA_PWFM1_BASE + TEGRA_PWFM1_SIZE - 1,
1438 .flags = IORESOURCE_MEM,
1439};
1440
1441static struct resource tegra_pwfm2_resource = {
1442 .start = TEGRA_PWFM2_BASE,
1443 .end = TEGRA_PWFM2_BASE + TEGRA_PWFM2_SIZE - 1,
1444 .flags = IORESOURCE_MEM,
1445};
1446
1447static struct resource tegra_pwfm3_resource = {
1448 .start = TEGRA_PWFM3_BASE,
1449 .end = TEGRA_PWFM3_BASE + TEGRA_PWFM3_SIZE - 1,
1450 .flags = IORESOURCE_MEM,
1451};
1452
1453struct platform_device tegra_pwfm0_device = {
1454 .name = "tegra_pwm",
1455 .id = 0,
1456 .num_resources = 1,
1457 .resource = &tegra_pwfm0_resource,
1458};
1459
1460struct platform_device tegra_pwfm1_device = {
1461 .name = "tegra_pwm",
1462 .id = 1,
1463 .num_resources = 1,
1464 .resource = &tegra_pwfm1_resource,
1465};
1466
1467struct platform_device tegra_pwfm2_device = {
1468 .name = "tegra_pwm",
1469 .id = 2,
1470 .num_resources = 1,
1471 .resource = &tegra_pwfm2_resource,
1472};
1473
1474struct platform_device tegra_pwfm3_device = {
1475 .name = "tegra_pwm",
1476 .id = 3,
1477 .num_resources = 1,
1478 .resource = &tegra_pwfm3_resource,
1479};
1480
1481static struct tegra_avp_platform_data tegra_avp_pdata = {
1482#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1483 .emc_clk_rate = ULONG_MAX,
1484#else
1485 .emc_clk_rate = 200000000,
1486#endif
1487};
1488
1489struct resource tegra_nvavp_resources[] = {
1490 [0] = {
1491 .start = INT_SHR_SEM_INBOX_IBF,
1492 .end = INT_SHR_SEM_INBOX_IBF,
1493 .flags = IORESOURCE_IRQ,
1494 .name = "mbox_from_nvavp_pending",
1495 },
1496};
1497
1498struct nvhost_device nvavp_device = {
1499 .name = "nvavp",
1500 .id = -1,
1501 .resource = tegra_nvavp_resources,
1502 .num_resources = ARRAY_SIZE(tegra_nvavp_resources),
1503};
1504
1505static struct resource tegra_avp_resources[] = {
1506 [0] = {
1507 .start = INT_SHR_SEM_INBOX_IBF,
1508 .end = INT_SHR_SEM_INBOX_IBF,
1509 .flags = IORESOURCE_IRQ,
1510 .name = "mbox_from_avp_pending",
1511 },
1512};
1513
1514struct platform_device tegra_avp_device = {
1515 .name = "tegra-avp",
1516 .id = -1,
1517 .num_resources = ARRAY_SIZE(tegra_avp_resources),
1518 .resource = tegra_avp_resources,
1519 .dev = {
1520 .coherent_dma_mask = 0xffffffffULL,
1521 .platform_data = &tegra_avp_pdata,
1522 },
1523};
1524
1525static struct resource tegra_aes_resources[] = {
1526 {
1527 .start = TEGRA_VDE_BASE,
1528 .end = TEGRA_VDE_BASE + TEGRA_VDE_SIZE - 1,
1529 .flags = IORESOURCE_MEM,
1530 },
1531 {
1532 .start = TEGRA_BSEA_BASE,
1533 .end = TEGRA_BSEA_BASE + TEGRA_BSEA_SIZE - 1,
1534 .flags = IORESOURCE_MEM,
1535 },
1536};
1537
1538static u64 tegra_aes_dma_mask = DMA_BIT_MASK(32);
1539
1540struct platform_device tegra_aes_device = {
1541 .name = "tegra-aes",
1542 .id = -1,
1543 .resource = tegra_aes_resources,
1544 .num_resources = ARRAY_SIZE(tegra_aes_resources),
1545 .dev = {
1546 .dma_mask = &tegra_aes_dma_mask,
1547 .coherent_dma_mask = DMA_BIT_MASK(32),
1548 },
1549};
1550
1551static struct resource tegra_kbc_resources[] = {
1552 [0] = {
1553 .start = TEGRA_KBC_BASE,
1554 .end = TEGRA_KBC_BASE + TEGRA_KBC_SIZE - 1,
1555 .flags = IORESOURCE_MEM,
1556 },
1557 [1] = {
1558 .start = INT_KBC,
1559 .end = INT_KBC,
1560 .flags = IORESOURCE_IRQ,
1561 },
1562};
1563
1564struct platform_device tegra_kbc_device = {
1565 .name = "tegra-kbc",
1566 .id = -1,
1567 .resource = tegra_kbc_resources,
1568 .num_resources = ARRAY_SIZE(tegra_kbc_resources),
1569 .dev = {
1570 .platform_data = 0,
1571 },
1572};
1573
1574#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
1575static struct resource tegra_tsensor_resources[]= {
1576 {
1577 .start = TEGRA_TSENSOR_BASE,
1578 .end = TEGRA_TSENSOR_BASE + TEGRA_TSENSOR_SIZE - 1,
1579 .flags = IORESOURCE_MEM,
1580 },
1581 {
1582 .start = INT_TSENSOR,
1583 .end = INT_TSENSOR,
1584 .flags = IORESOURCE_IRQ,
1585 },
1586 {
1587 .start = TEGRA_PMC_BASE + 0x1B0,
1588 /* 2 pmc registers mapped */
1589 .end = TEGRA_PMC_BASE + 0x1B0 + (2 * 4),
1590 .flags = IORESOURCE_MEM,
1591 },
1592};
1593
1594struct platform_device tegra_tsensor_device = {
1595 .name = "tegra-tsensor",
1596 .id = -1,
1597 .num_resources = ARRAY_SIZE(tegra_tsensor_resources),
1598 .resource = tegra_tsensor_resources,
1599 .dev = {
1600 .platform_data = 0,
1601 },
1602};
1603#endif
1604
1605#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
1606static u64 tegra_se_dma_mask = DMA_BIT_MASK(32);
1607
1608struct resource tegra_se_resources[] = {
1609 [0] = {
1610 .start = TEGRA_SE_BASE,
1611 .end = TEGRA_SE_BASE + TEGRA_SE_SIZE - 1,
1612 .flags = IORESOURCE_MEM,
1613 },
1614 [1] = {
1615 .start = TEGRA_PMC_BASE,
1616 .end = TEGRA_PMC_BASE + SZ_256 - 1,
1617 .flags = IORESOURCE_MEM,
1618 },
1619 [2] = {
1620 .start = INT_SE,
1621 .end = INT_SE,
1622 .flags = IORESOURCE_IRQ,
1623 },
1624};
1625
1626struct platform_device tegra_se_device = {
1627 .name = "tegra-se",
1628 .id = -1,
1629 .dev = {
1630 .coherent_dma_mask = DMA_BIT_MASK(32),
1631 .dma_mask = &tegra_se_dma_mask,
1632 },
1633 .resource = tegra_se_resources,
1634 .num_resources = ARRAY_SIZE(tegra_se_resources),
1635};
1636#endif
1637
1638static struct resource tegra_disp1_resources[] = {
1639 {
1640 .name = "irq",
1641 .start = INT_DISPLAY_GENERAL,
1642 .end = INT_DISPLAY_GENERAL,
1643 .flags = IORESOURCE_IRQ,
1644 },
1645 {
1646 .name = "regs",
1647 .start = TEGRA_DISPLAY_BASE,
1648 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
1649 .flags = IORESOURCE_MEM,
1650 },
1651 {
1652 .name = "fbmem",
1653 .start = 0,
1654 .end = 0,
1655 .flags = IORESOURCE_MEM,
1656 },
1657 {
1658 .name = "dsi_regs",
1659 .start = TEGRA_DSI_BASE,
1660 .end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
1661 .flags = IORESOURCE_MEM,
1662 },
1663};
1664
1665struct nvhost_device tegra_disp1_device = {
1666 .name = "tegradc",
1667 .id = 0,
1668 .resource = tegra_disp1_resources,
1669 .num_resources = ARRAY_SIZE(tegra_disp1_resources),
1670};
1671
1672struct platform_device tegra_nvmap_device = {
1673 .name = "tegra-nvmap",
1674 .id = -1,
1675};
1676
1677void __init tegra_init_debug_uart_rate(void)
1678{
1679 unsigned int uartclk;
1680 struct clk *debug_uart_parent = clk_get_sys(NULL, "pll_p");
1681
1682 BUG_ON(IS_ERR(debug_uart_parent));
1683 uartclk = clk_get_rate(debug_uart_parent);
1684
1685 debug_uarta_platform_data[0].uartclk = uartclk;
1686 debug_uartb_platform_data[0].uartclk = uartclk;
1687 debug_uartc_platform_data[0].uartclk = uartclk;
1688 debug_uartd_platform_data[0].uartclk = uartclk;
1689#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
1690 debug_uarte_platform_data[0].uartclk = uartclk;
1691#endif
1692}
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
new file mode 100644
index 00000000000..97a0c53ccfc
--- /dev/null
+++ b/arch/arm/mach-tegra/devices.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (C) 2010,2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.com>
6 * Erik Gilling <ccross@android.com>
7 *
8 * Copyright (C) 2010-2012 NVIDIA Corporation.
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_DEVICES_H
22#define __MACH_TEGRA_DEVICES_H
23
24#include <linux/platform_device.h>
25#include <linux/nvhost.h>
26
27extern struct platform_device tegra_sdhci_device1;
28extern struct platform_device tegra_sdhci_device2;
29extern struct platform_device tegra_sdhci_device3;
30extern struct platform_device tegra_sdhci_device4;
31extern struct platform_device tegra_i2c_device1;
32extern struct platform_device tegra_i2c_device2;
33extern struct platform_device tegra_i2c_device3;
34extern struct platform_device tegra_i2c_device4;
35extern struct platform_device tegra_kbc_device;
36extern struct platform_device tegra_pci_device;
37#ifndef CONFIG_ARCH_TEGRA_2x_SOC
38extern struct platform_device tegra_i2c_device5;
39#endif
40extern struct platform_device tegra_spi_device1;
41extern struct platform_device tegra_spi_device2;
42extern struct platform_device tegra_spi_device3;
43extern struct platform_device tegra_spi_device4;
44extern struct platform_device tegra_spi_slave_device1;
45extern struct platform_device tegra_spi_slave_device2;
46extern struct platform_device tegra_spi_slave_device3;
47extern struct platform_device tegra_spi_slave_device4;
48#ifndef CONFIG_ARCH_TEGRA_2x_SOC
49extern struct platform_device tegra_spi_device5;
50extern struct platform_device tegra_spi_device6;
51extern struct platform_device tegra_spi_slave_device5;
52extern struct platform_device tegra_spi_slave_device6;
53extern struct platform_device tegra_dtv_device;
54#endif
55extern struct platform_device tegra_ehci1_device;
56extern struct platform_device tegra_ehci2_device;
57extern struct platform_device tegra_ehci3_device;
58extern struct platform_device tegra_uarta_device;
59extern struct platform_device tegra_uartb_device;
60extern struct platform_device tegra_uartc_device;
61extern struct platform_device tegra_uartd_device;
62extern struct platform_device tegra_uarte_device;
63extern struct platform_device tegra_pmu_device;
64extern struct platform_device tegra_i2s_device1;
65extern struct platform_device tegra_i2s_device2;
66extern struct platform_device tegra_spdif_device;
67extern struct platform_device tegra_das_device;
68extern struct platform_device spdif_dit_device;
69extern struct platform_device bluetooth_dit_device;
70extern struct platform_device baseband_dit_device;
71extern struct platform_device tegra_pcm_device;
72extern struct platform_device tegra_w1_device;
73extern struct platform_device tegra_udc_device;
74extern struct platform_device tegra_ehci1_device;
75extern struct platform_device tegra_ehci2_device;
76extern struct platform_device tegra_ehci3_device;
77extern struct platform_device tegra_i2s_device1;
78extern struct platform_device tegra_i2s_device2;
79#ifndef CONFIG_ARCH_TEGRA_2x_SOC
80extern struct platform_device tegra_i2s_device0;
81extern struct platform_device tegra_i2s_device3;
82extern struct platform_device tegra_i2s_device4;
83extern struct platform_device tegra_ahub_device;
84extern struct platform_device tegra_apbif0_device;
85extern struct platform_device tegra_apbif1_device;
86extern struct platform_device tegra_apbif2_device;
87extern struct platform_device tegra_apbif3_device;
88extern struct platform_device tegra_dam_device0;
89extern struct platform_device tegra_dam_device1;
90extern struct platform_device tegra_dam_device2;
91extern struct platform_device tegra_hda_device;
92extern struct platform_device tegra_sata_device;
93#endif
94#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
95extern struct platform_device tegra_gart_device;
96#else
97extern struct platform_device tegra_smmu_device;
98#endif
99extern struct platform_device tegra_wdt_device;
100extern struct platform_device tegra_pwfm0_device;
101extern struct platform_device tegra_pwfm1_device;
102extern struct platform_device tegra_pwfm2_device;
103extern struct platform_device tegra_pwfm3_device;
104extern struct platform_device tegra_otg_device;
105extern struct platform_device tegra_uarta_device;
106extern struct platform_device tegra_uartb_device;
107extern struct platform_device tegra_uartc_device;
108extern struct platform_device tegra_uartd_device;
109extern struct platform_device tegra_uarte_device;
110extern struct platform_device tegra_avp_device;
111extern struct nvhost_device tegra_grhost_device;
112extern struct nvhost_device nvavp_device;
113extern struct platform_device tegra_aes_device;
114#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
115extern struct platform_device tegra_tsensor_device;
116#endif
117extern struct platform_device tegra_nor_device;
118extern struct platform_device debug_uarta_device;
119extern struct platform_device debug_uartb_device;
120extern struct platform_device debug_uartc_device;
121extern struct platform_device debug_uartd_device;
122#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
123extern struct platform_device tegra_se_device;
124extern struct platform_device debug_uarte_device;
125#endif
126
127extern struct nvhost_device tegra_disp1_device;
128extern struct platform_device tegra_nvmap_device;
129
130void __init tegra_init_debug_uart_rate(void);
131
132#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
new file mode 100644
index 00000000000..35499916e2b
--- /dev/null
+++ b/arch/arm/mach-tegra/dma.c
@@ -0,0 +1,1203 @@
1/*
2 * arch/arm/mach-tegra/dma.c
3 *
4 * System DMA driver for NVIDIA Tegra SoCs
5 *
6 * Copyright (c) 2008-2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/io.h>
24#include <linux/interrupt.h>
25#include <linux/module.h>
26#include <linux/spinlock.h>
27#include <linux/err.h>
28#include <linux/irq.h>
29#include <linux/delay.h>
30#include <linux/clk.h>
31#include <linux/syscore_ops.h>
32#include <mach/dma.h>
33#include <mach/irqs.h>
34#include <mach/iomap.h>
35#include <mach/clk.h>
36
37#define APB_DMA_GEN 0x000
38#define GEN_ENABLE (1<<31)
39
40#define APB_DMA_CNTRL 0x010
41
42#define APB_DMA_IRQ_MASK 0x01c
43
44#define APB_DMA_IRQ_MASK_SET 0x020
45
46#define APB_DMA_CHAN_CSR 0x000
47#define CSR_ENB (1<<31)
48#define CSR_IE_EOC (1<<30)
49#define CSR_HOLD (1<<29)
50#define CSR_DIR (1<<28)
51#define CSR_ONCE (1<<27)
52#define CSR_FLOW (1<<21)
53#define CSR_REQ_SEL_SHIFT 16
54#define CSR_WCOUNT_SHIFT 2
55#define CSR_WCOUNT_MASK 0xFFFC
56
57#define APB_DMA_CHAN_STA 0x004
58#define STA_BUSY (1<<31)
59#define STA_ISE_EOC (1<<30)
60#define STA_HALT (1<<29)
61#define STA_PING_PONG (1<<28)
62#define STA_COUNT_SHIFT 2
63#define STA_COUNT_MASK 0xFFFC
64
65#define APB_DMA_CHAN_AHB_PTR 0x010
66
67#define APB_DMA_CHAN_AHB_SEQ 0x014
68#define AHB_SEQ_INTR_ENB (1<<31)
69#define AHB_SEQ_BUS_WIDTH_SHIFT 28
70#define AHB_SEQ_BUS_WIDTH_MASK (0x7<<AHB_SEQ_BUS_WIDTH_SHIFT)
71#define AHB_SEQ_BUS_WIDTH_8 (0<<AHB_SEQ_BUS_WIDTH_SHIFT)
72#define AHB_SEQ_BUS_WIDTH_16 (1<<AHB_SEQ_BUS_WIDTH_SHIFT)
73#define AHB_SEQ_BUS_WIDTH_32 (2<<AHB_SEQ_BUS_WIDTH_SHIFT)
74#define AHB_SEQ_BUS_WIDTH_64 (3<<AHB_SEQ_BUS_WIDTH_SHIFT)
75#define AHB_SEQ_BUS_WIDTH_128 (4<<AHB_SEQ_BUS_WIDTH_SHIFT)
76#define AHB_SEQ_DATA_SWAP (1<<27)
77#define AHB_SEQ_BURST_MASK (0x7<<24)
78#define AHB_SEQ_BURST_1 (4<<24)
79#define AHB_SEQ_BURST_4 (5<<24)
80#define AHB_SEQ_BURST_8 (6<<24)
81#define AHB_SEQ_DBL_BUF (1<<19)
82#define AHB_SEQ_WRAP_SHIFT 16
83#define AHB_SEQ_WRAP_MASK (0x7<<AHB_SEQ_WRAP_SHIFT)
84
85#define APB_DMA_CHAN_APB_PTR 0x018
86
87#define APB_DMA_CHAN_APB_SEQ 0x01c
88#define APB_SEQ_BUS_WIDTH_SHIFT 28
89#define APB_SEQ_BUS_WIDTH_MASK (0x7<<APB_SEQ_BUS_WIDTH_SHIFT)
90#define APB_SEQ_BUS_WIDTH_8 (0<<APB_SEQ_BUS_WIDTH_SHIFT)
91#define APB_SEQ_BUS_WIDTH_16 (1<<APB_SEQ_BUS_WIDTH_SHIFT)
92#define APB_SEQ_BUS_WIDTH_32 (2<<APB_SEQ_BUS_WIDTH_SHIFT)
93#define APB_SEQ_BUS_WIDTH_64 (3<<APB_SEQ_BUS_WIDTH_SHIFT)
94#define APB_SEQ_BUS_WIDTH_128 (4<<APB_SEQ_BUS_WIDTH_SHIFT)
95#define APB_SEQ_DATA_SWAP (1<<27)
96#define APB_SEQ_WRAP_SHIFT 16
97#define APB_SEQ_WRAP_MASK (0x7<<APB_SEQ_WRAP_SHIFT)
98
99#ifdef CONFIG_ARCH_TEGRA_2x_SOC
100#define TEGRA_SYSTEM_DMA_CH_NR 16
101#else
102#define TEGRA_SYSTEM_DMA_CH_NR 32
103#endif
104#define TEGRA_SYSTEM_DMA_AVP_CH_NUM 4
105#define TEGRA_SYSTEM_DMA_CH_MIN 0
106#define TEGRA_SYSTEM_DMA_CH_MAX \
107 (TEGRA_SYSTEM_DMA_CH_NR - TEGRA_SYSTEM_DMA_AVP_CH_NUM - 1)
108
109/* Maximum dma transfer size */
110#define TEGRA_DMA_MAX_TRANSFER_SIZE 0x10000
111
112static struct clk *dma_clk;
113
114static const unsigned int ahb_addr_wrap_table[8] = {
115 0, 32, 64, 128, 256, 512, 1024, 2048
116};
117
118static const unsigned int apb_addr_wrap_table[8] = {
119 0, 1, 2, 4, 8, 16, 32, 64
120};
121
122static const unsigned int bus_width_table[5] = {
123 8, 16, 32, 64, 128
124};
125
126static void __iomem *general_dma_addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
127typedef void (*dma_isr_handler)(struct tegra_dma_channel *ch);
128
129#define TEGRA_DMA_NAME_SIZE 16
130struct tegra_dma_channel {
131 struct list_head list;
132 int id;
133 spinlock_t lock;
134 char name[TEGRA_DMA_NAME_SIZE];
135 char client_name[TEGRA_DMA_NAME_SIZE];
136 void __iomem *addr;
137 int mode;
138 int irq;
139 dma_callback callback;
140 struct tegra_dma_req *cb_req;
141 dma_isr_handler isr_handler;
142};
143
144#define NV_DMA_MAX_CHANNELS 32
145
146static bool tegra_dma_initialized;
147static DEFINE_MUTEX(tegra_dma_lock);
148static DEFINE_SPINLOCK(enable_lock);
149
150static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
151static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
152
153static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
154 struct tegra_dma_req *req);
155static bool tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
156 struct tegra_dma_req *req);
157static void handle_oneshot_dma(struct tegra_dma_channel *ch);
158static void handle_continuous_dbl_dma(struct tegra_dma_channel *ch);
159static void handle_continuous_sngl_dma(struct tegra_dma_channel *ch);
160
161void tegra_dma_flush(struct tegra_dma_channel *ch)
162{
163}
164EXPORT_SYMBOL(tegra_dma_flush);
165
166static void tegra_dma_stop(struct tegra_dma_channel *ch)
167{
168 u32 csr;
169 u32 status;
170
171 csr = readl(ch->addr + APB_DMA_CHAN_CSR);
172 csr &= ~CSR_IE_EOC;
173 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
174
175 csr &= ~CSR_ENB;
176 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
177
178 status = readl(ch->addr + APB_DMA_CHAN_STA);
179 if (status & STA_ISE_EOC)
180 writel(status, ch->addr + APB_DMA_CHAN_STA);
181}
182
183int tegra_dma_cancel(struct tegra_dma_channel *ch)
184{
185 unsigned long irq_flags;
186
187 spin_lock_irqsave(&ch->lock, irq_flags);
188 while (!list_empty(&ch->list))
189 list_del(ch->list.next);
190
191 tegra_dma_stop(ch);
192
193 spin_unlock_irqrestore(&ch->lock, irq_flags);
194 return 0;
195}
196EXPORT_SYMBOL(tegra_dma_cancel);
197
198static void pause_dma(bool wait_for_burst_complete)
199{
200 spin_lock(&enable_lock);
201 writel(0, general_dma_addr + APB_DMA_GEN);
202 if (wait_for_burst_complete)
203 udelay(20);
204}
205
206static void resume_dma(void)
207{
208 writel(GEN_ENABLE, general_dma_addr + APB_DMA_GEN);
209 spin_unlock(&enable_lock);
210}
211
212static void start_head_req(struct tegra_dma_channel *ch)
213{
214 struct tegra_dma_req *head_req;
215 if (!list_empty(&ch->list)) {
216 head_req = list_entry(ch->list.next, typeof(*head_req), node);
217 tegra_dma_update_hw(ch, head_req);
218 }
219}
220
221static void configure_next_req(struct tegra_dma_channel *ch,
222 struct tegra_dma_req *hreq)
223{
224 struct tegra_dma_req *next_req;
225 if (!list_is_last(&hreq->node, &ch->list)) {
226 next_req = list_entry(hreq->node.next, typeof(*next_req), node);
227 tegra_dma_update_hw_partial(ch, next_req);
228 }
229}
230
231static inline unsigned int get_req_xfer_word_count(
232 struct tegra_dma_channel *ch, struct tegra_dma_req *req)
233{
234 if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE)
235 return req->size >> 3;
236 else
237 return req->size >> 2;
238}
239
240static int get_current_xferred_count(struct tegra_dma_channel *ch,
241 struct tegra_dma_req *req, unsigned long status)
242{
243 int req_transfer_count;
244 req_transfer_count = get_req_xfer_word_count(ch, req) << 2;
245 return req_transfer_count - ((status & STA_COUNT_MASK) + 4);
246}
247
248static void tegra_dma_abort_req(struct tegra_dma_channel *ch,
249 struct tegra_dma_req *req, const char *warn_msg)
250{
251 unsigned long status = readl(ch->addr + APB_DMA_CHAN_STA);
252
253 /*
254 * Check if interrupt is pending.
255 * This api is called from isr and hence need not to call
256 * isr handle again, just update the byte_transferred.
257 */
258 if (status & STA_ISE_EOC)
259 req->bytes_transferred += get_req_xfer_word_count(ch, req) << 2;
260 tegra_dma_stop(ch);
261
262 req->bytes_transferred += get_current_xferred_count(ch, req, status);
263 req->status = -TEGRA_DMA_REQ_ERROR_STOPPED;
264 if (warn_msg)
265 WARN(1, KERN_WARNING "%s\n", warn_msg);
266 start_head_req(ch);
267}
268
269static void handle_continuous_head_request(struct tegra_dma_channel *ch,
270 struct tegra_dma_req *last_req)
271{
272 struct tegra_dma_req *hreq = NULL;
273
274 if (list_empty(&ch->list)) {
275 tegra_dma_abort_req(ch, last_req, NULL);
276 return;
277 }
278
279 /*
280 * Check that head req on list should be in flight.
281 * If it is not in flight then request came late
282 * and so need to abort dma and start next request
283 * immediately.
284 */
285 hreq = list_entry(ch->list.next, typeof(*hreq), node);
286 if (hreq->status != TEGRA_DMA_REQ_INFLIGHT) {
287 tegra_dma_abort_req(ch, last_req, "Req was not queued on time");
288 return;
289 }
290
291 /* Configure next request in single buffer mode */
292 if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_SINGLE)
293 configure_next_req(ch, hreq);
294}
295
296static unsigned int get_channel_status(struct tegra_dma_channel *ch,
297 struct tegra_dma_req *req, bool is_stop_dma)
298{
299 unsigned int status;
300
301 if (is_stop_dma) {
302 /* STOP the DMA and get the transfer count.
303 * Getting the transfer count is tricky.
304 * - Globally disable DMA on all channels
305 * - Read the channel's status register to know the number
306 * of pending bytes to be transfered.
307 * - Stop the dma channel
308 * - Globally re-enable DMA to resume other transfers
309 */
310 pause_dma(true);
311 status = readl(ch->addr + APB_DMA_CHAN_STA);
312 tegra_dma_stop(ch);
313 resume_dma();
314 if (status & STA_ISE_EOC) {
315 pr_err("Got Dma Int here clearing");
316 writel(status, ch->addr + APB_DMA_CHAN_STA);
317 }
318 req->status = TEGRA_DMA_REQ_ERROR_ABORTED;
319 } else {
320 status = readl(ch->addr + APB_DMA_CHAN_STA);
321 }
322 return status;
323}
324
325/* should be called with the channel lock held */
326static unsigned int dma_active_count(struct tegra_dma_channel *ch,
327 struct tegra_dma_req *req, unsigned int status)
328{
329 unsigned int to_transfer;
330 unsigned int req_transfer_count;
331
332 unsigned int bytes_transferred;
333
334 to_transfer = ((status & STA_COUNT_MASK) >> STA_COUNT_SHIFT) + 1;
335 req_transfer_count = get_req_xfer_word_count(ch, req);
336 bytes_transferred = req_transfer_count;
337
338 if (status & STA_BUSY)
339 bytes_transferred -= to_transfer;
340
341 /*
342 * In continuous transfer mode, DMA only tracks the count of the
343 * half DMA buffer. So, if the DMA already finished half the DMA
344 * then add the half buffer to the completed count.
345 */
346 if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE)
347 if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
348 bytes_transferred += req_transfer_count;
349
350 if (status & STA_ISE_EOC)
351 bytes_transferred += req_transfer_count;
352
353 bytes_transferred *= 4;
354
355 return bytes_transferred;
356}
357
358int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
359 struct tegra_dma_req *_req)
360{
361 struct tegra_dma_req *req = NULL;
362 int found = 0;
363 unsigned int status;
364 unsigned long irq_flags;
365 int stop = 0;
366
367 spin_lock_irqsave(&ch->lock, irq_flags);
368
369 if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req)
370 stop = 1;
371
372 list_for_each_entry(req, &ch->list, node) {
373 if (req == _req) {
374 list_del(&req->node);
375 found = 1;
376 break;
377 }
378 }
379 if (!found) {
380 spin_unlock_irqrestore(&ch->lock, irq_flags);
381 return -ENOENT;
382 }
383
384 if (!stop)
385 goto skip_status;
386
387 status = get_channel_status(ch, req, true);
388 req->bytes_transferred = dma_active_count(ch, req, status);
389
390 if (!list_empty(&ch->list)) {
391 /* if the list is not empty, queue the next request */
392 struct tegra_dma_req *next_req;
393 next_req = list_entry(ch->list.next,
394 typeof(*next_req), node);
395 tegra_dma_update_hw(ch, next_req);
396 }
397skip_status:
398 req->status = -TEGRA_DMA_REQ_ERROR_ABORTED;
399
400 spin_unlock_irqrestore(&ch->lock, irq_flags);
401
402 /* Callback should be called without any lock */
403 req->complete(req);
404 return 0;
405}
406EXPORT_SYMBOL(tegra_dma_dequeue_req);
407
408bool tegra_dma_is_empty(struct tegra_dma_channel *ch)
409{
410 unsigned long irq_flags;
411 bool is_empty;
412
413 spin_lock_irqsave(&ch->lock, irq_flags);
414 if (list_empty(&ch->list))
415 is_empty = true;
416 else
417 is_empty = false;
418 spin_unlock_irqrestore(&ch->lock, irq_flags);
419 return is_empty;
420}
421EXPORT_SYMBOL(tegra_dma_is_empty);
422
423bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
424 struct tegra_dma_req *_req)
425{
426 unsigned long irq_flags;
427 struct tegra_dma_req *req;
428
429 spin_lock_irqsave(&ch->lock, irq_flags);
430 list_for_each_entry(req, &ch->list, node) {
431 if (req == _req) {
432 spin_unlock_irqrestore(&ch->lock, irq_flags);
433 return true;
434 }
435 }
436 spin_unlock_irqrestore(&ch->lock, irq_flags);
437 return false;
438}
439EXPORT_SYMBOL(tegra_dma_is_req_inflight);
440
441int tegra_dma_get_transfer_count(struct tegra_dma_channel *ch,
442 struct tegra_dma_req *req)
443{
444 unsigned int status;
445 unsigned long irq_flags;
446 int bytes_transferred = 0;
447
448 if (IS_ERR_OR_NULL(ch))
449 BUG();
450
451 spin_lock_irqsave(&ch->lock, irq_flags);
452
453 if (list_entry(ch->list.next, struct tegra_dma_req, node) != req) {
454 spin_unlock_irqrestore(&ch->lock, irq_flags);
455 pr_debug("The dma request is not the head req\n");
456 return req->bytes_transferred;
457 }
458
459 if (req->status != TEGRA_DMA_REQ_INFLIGHT) {
460 spin_unlock_irqrestore(&ch->lock, irq_flags);
461 pr_debug("The dma request is not running\n");
462 return req->bytes_transferred;
463 }
464
465 status = get_channel_status(ch, req, false);
466 bytes_transferred = dma_active_count(ch, req, status);
467 spin_unlock_irqrestore(&ch->lock, irq_flags);
468 return bytes_transferred;
469}
470EXPORT_SYMBOL(tegra_dma_get_transfer_count);
471
472int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
473 struct tegra_dma_req *req)
474{
475 unsigned long irq_flags;
476 struct tegra_dma_req *_req;
477 int start_dma = 0;
478 struct tegra_dma_req *hreq, *hnreq;
479
480 if (req->size > TEGRA_DMA_MAX_TRANSFER_SIZE ||
481 req->source_addr & 0x3 || req->dest_addr & 0x3) {
482 pr_err("Invalid DMA request for channel %d\n", ch->id);
483 return -EINVAL;
484 }
485
486 if ((req->size & 0x3) ||
487 ((ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE) && (req->size & 0x7)))
488 {
489 pr_err("Invalid DMA request size 0x%08x for channel %d\n",
490 req->size, ch->id);
491 return -EINVAL;
492 }
493
494 spin_lock_irqsave(&ch->lock, irq_flags);
495
496 list_for_each_entry(_req, &ch->list, node) {
497 if (req == _req) {
498 spin_unlock_irqrestore(&ch->lock, irq_flags);
499 return -EEXIST;
500 }
501 }
502
503 req->bytes_transferred = 0;
504 req->status = 0;
505 /* STATUS_EMPTY just means the DMA hasn't processed the buf yet. */
506 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_EMPTY;
507 if (list_empty(&ch->list))
508 start_dma = 1;
509
510 list_add_tail(&req->node, &ch->list);
511
512 if (start_dma) {
513 tegra_dma_update_hw(ch, req);
514 } else {
515 /*
516 * Check to see if this request needs to be configured
517 * immediately in continuous mode.
518 */
519 if (ch->mode & TEGRA_DMA_MODE_ONESHOT)
520 goto end;
521
522 hreq = list_entry(ch->list.next, typeof(*hreq), node);
523 hnreq = list_entry(hreq->node.next, typeof(*hnreq), node);
524 if (hnreq != req)
525 goto end;
526
527 if ((ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE) &&
528 (req->buffer_status != TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL))
529 goto end;
530
531 /* Need to configure the new request now */
532 tegra_dma_update_hw_partial(ch, req);
533 }
534
535end:
536 spin_unlock_irqrestore(&ch->lock, irq_flags);
537 return 0;
538}
539EXPORT_SYMBOL(tegra_dma_enqueue_req);
540
541static void tegra_dma_dump_channel_usage(void)
542{
543 int i;
544 pr_info("DMA channel allocation dump:\n");
545 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
546 struct tegra_dma_channel *ch = &dma_channels[i];
547 pr_warn("dma %d used by %s\n", i, ch->client_name);
548 }
549 return;
550}
551
552struct tegra_dma_channel *tegra_dma_allocate_channel(int mode,
553 const char namefmt[], ...)
554{
555 int channel;
556 struct tegra_dma_channel *ch = NULL;
557 va_list args;
558 dma_isr_handler isr_handler = NULL;
559
560 if (WARN_ON(!tegra_dma_initialized))
561 return NULL;
562
563 mutex_lock(&tegra_dma_lock);
564
565 /* first channel is the shared channel */
566 if (mode & TEGRA_DMA_SHARED) {
567 channel = TEGRA_SYSTEM_DMA_CH_MIN;
568 } else {
569 channel = find_first_zero_bit(channel_usage,
570 ARRAY_SIZE(dma_channels));
571 if (channel >= ARRAY_SIZE(dma_channels)) {
572 tegra_dma_dump_channel_usage();
573 goto out;
574 }
575 }
576
577 if (mode & TEGRA_DMA_MODE_ONESHOT)
578 isr_handler = handle_oneshot_dma;
579 else if (mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE)
580 isr_handler = handle_continuous_dbl_dma;
581 else if (mode & TEGRA_DMA_MODE_CONTINUOUS_SINGLE)
582 isr_handler = handle_continuous_sngl_dma;
583 else
584 pr_err("Bad channel mode for DMA ISR handler\n");
585
586 if (!isr_handler)
587 goto out;
588
589 __set_bit(channel, channel_usage);
590 ch = &dma_channels[channel];
591 ch->mode = mode;
592 ch->isr_handler = isr_handler;
593 va_start(args, namefmt);
594 vsnprintf(ch->client_name, sizeof(ch->client_name),
595 namefmt, args);
596 va_end(args);
597
598out:
599 mutex_unlock(&tegra_dma_lock);
600 return ch;
601}
602EXPORT_SYMBOL(tegra_dma_allocate_channel);
603
604void tegra_dma_free_channel(struct tegra_dma_channel *ch)
605{
606 if (ch->mode & TEGRA_DMA_SHARED)
607 return;
608 tegra_dma_cancel(ch);
609 mutex_lock(&tegra_dma_lock);
610 __clear_bit(ch->id, channel_usage);
611 memset(ch->client_name, 0, sizeof(ch->client_name));
612 ch->isr_handler = NULL;
613 ch->callback = NULL;
614 ch->cb_req = NULL;
615 mutex_unlock(&tegra_dma_lock);
616}
617EXPORT_SYMBOL(tegra_dma_free_channel);
618
619static bool tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
620 struct tegra_dma_req *req)
621{
622 u32 apb_ptr;
623 u32 ahb_ptr;
624 u32 csr;
625 unsigned long status;
626 unsigned int req_transfer_count;
627 bool configure = false;
628
629 if (req->to_memory) {
630 apb_ptr = req->source_addr;
631 ahb_ptr = req->dest_addr;
632 } else {
633 apb_ptr = req->dest_addr;
634 ahb_ptr = req->source_addr;
635 }
636
637 /*
638 * The dma controller reloads the new configuration for next transfer
639 * after last burst of current transfer completes.
640 * If there is no IEC status then this make sure that last burst
641 * has not be completed.
642 * If there is already IEC status then interrupt handle need to
643 * load new configuration after aborting current dma.
644 */
645 pause_dma(false);
646 status = readl(ch->addr + APB_DMA_CHAN_STA);
647
648 /*
649 * If interrupt is pending then do nothing as the ISR will handle
650 * the programing for new request.
651 */
652 if (status & STA_ISE_EOC) {
653 pr_warn("%s(): "
654 "Skipping new configuration as interrupt is pending\n",
655 __func__);
656 goto exit_config;
657 }
658
659 /* Safe to program new configuration */
660 writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
661 writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
662
663 req_transfer_count = get_req_xfer_word_count(ch, req);
664 csr = readl(ch->addr + APB_DMA_CHAN_CSR);
665 csr &= ~CSR_WCOUNT_MASK;
666 csr |= (req_transfer_count - 1) << CSR_WCOUNT_SHIFT;
667 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
668 req->status = TEGRA_DMA_REQ_INFLIGHT;
669 configure = true;
670
671exit_config:
672 resume_dma();
673 return configure;
674}
675
676static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
677 struct tegra_dma_req *req)
678{
679 int ahb_addr_wrap;
680 int apb_addr_wrap;
681 int ahb_bus_width;
682 int apb_bus_width;
683 int index;
684 unsigned int req_transfer_count;
685
686 u32 ahb_seq;
687 u32 apb_seq;
688 u32 ahb_ptr;
689 u32 apb_ptr;
690 u32 csr;
691
692 csr = CSR_IE_EOC | CSR_FLOW;
693 ahb_seq = AHB_SEQ_INTR_ENB;
694
695 switch (req->req_sel) {
696 case TEGRA_DMA_REQ_SEL_SL2B1:
697 case TEGRA_DMA_REQ_SEL_SL2B2:
698 case TEGRA_DMA_REQ_SEL_SL2B3:
699 case TEGRA_DMA_REQ_SEL_SL2B4:
700#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
701 case TEGRA_DMA_REQ_SEL_SL2B5:
702 case TEGRA_DMA_REQ_SEL_SL2B6:
703 case TEGRA_DMA_REQ_SEL_APBIF_CH0:
704 case TEGRA_DMA_REQ_SEL_APBIF_CH1:
705 case TEGRA_DMA_REQ_SEL_APBIF_CH2:
706 case TEGRA_DMA_REQ_SEL_APBIF_CH3:
707#endif
708 case TEGRA_DMA_REQ_SEL_SPI:
709 /* dtv interface has fixed burst size of 4 */
710 if (req->fixed_burst_size) {
711 ahb_seq |= AHB_SEQ_BURST_4;
712 break;
713 }
714 /* For spi/slink the burst size based on transfer size
715 * i.e. if multiple of 32 bytes then busrt is 8
716 * word(8x32bits) else if multiple of 16 bytes then
717 * burst is 4 word(4x32bits) else burst size is 1
718 * word(1x32bits) */
719 if (req->size & 0xF)
720 ahb_seq |= AHB_SEQ_BURST_1;
721 else if ((req->size >> 4) & 0x1)
722 ahb_seq |= AHB_SEQ_BURST_4;
723 else
724 ahb_seq |= AHB_SEQ_BURST_8;
725 break;
726#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
727 case TEGRA_DMA_REQ_SEL_I2S_2:
728 case TEGRA_DMA_REQ_SEL_I2S_1:
729 case TEGRA_DMA_REQ_SEL_SPD_I:
730 case TEGRA_DMA_REQ_SEL_UI_I:
731 case TEGRA_DMA_REQ_SEL_I2S2_2:
732 case TEGRA_DMA_REQ_SEL_I2S2_1:
733 /* For ARCH_2x i2s/spdif burst size is 4 word */
734 ahb_seq |= AHB_SEQ_BURST_4;
735 break;
736#endif
737
738 default:
739 ahb_seq |= AHB_SEQ_BURST_1;
740 break;
741 }
742
743 apb_seq = 0;
744
745 csr |= req->req_sel << CSR_REQ_SEL_SHIFT;
746
747 req_transfer_count = get_req_xfer_word_count(ch, req);
748
749 /* One shot mode is always single buffered. Continuous mode could
750 * support either.
751 */
752 if (ch->mode & TEGRA_DMA_MODE_ONESHOT)
753 csr |= CSR_ONCE;
754
755 if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE)
756 ahb_seq |= AHB_SEQ_DBL_BUF;
757
758 csr |= (req_transfer_count - 1) << CSR_WCOUNT_SHIFT;
759
760 if (req->to_memory) {
761 apb_ptr = req->source_addr;
762 ahb_ptr = req->dest_addr;
763
764 apb_addr_wrap = req->source_wrap;
765 ahb_addr_wrap = req->dest_wrap;
766 apb_bus_width = req->source_bus_width;
767 ahb_bus_width = req->dest_bus_width;
768
769 } else {
770 csr |= CSR_DIR;
771 apb_ptr = req->dest_addr;
772 ahb_ptr = req->source_addr;
773
774 apb_addr_wrap = req->dest_wrap;
775 ahb_addr_wrap = req->source_wrap;
776 apb_bus_width = req->dest_bus_width;
777 ahb_bus_width = req->source_bus_width;
778 }
779
780 apb_addr_wrap >>= 2;
781 ahb_addr_wrap >>= 2;
782
783 /* set address wrap for APB size */
784 index = 0;
785 do {
786 if (apb_addr_wrap_table[index] == apb_addr_wrap)
787 break;
788 index++;
789 } while (index < ARRAY_SIZE(apb_addr_wrap_table));
790 BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table));
791 apb_seq |= index << APB_SEQ_WRAP_SHIFT;
792
793 /* set address wrap for AHB size */
794 index = 0;
795 do {
796 if (ahb_addr_wrap_table[index] == ahb_addr_wrap)
797 break;
798 index++;
799 } while (index < ARRAY_SIZE(ahb_addr_wrap_table));
800 BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table));
801 ahb_seq |= index << AHB_SEQ_WRAP_SHIFT;
802
803 for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
804 if (bus_width_table[index] == ahb_bus_width)
805 break;
806 }
807 BUG_ON(index == ARRAY_SIZE(bus_width_table));
808 ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT;
809
810 for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
811 if (bus_width_table[index] == apb_bus_width)
812 break;
813 }
814 BUG_ON(index == ARRAY_SIZE(bus_width_table));
815 apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT;
816
817 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
818 writel(apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ);
819 writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
820 writel(ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ);
821 writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
822
823 csr |= CSR_ENB;
824 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
825
826 req->status = TEGRA_DMA_REQ_INFLIGHT;
827}
828
829static void handle_oneshot_dma(struct tegra_dma_channel *ch)
830{
831 struct tegra_dma_req *req;
832
833 req = list_entry(ch->list.next, typeof(*req), node);
834 list_del(&req->node);
835 req->bytes_transferred += req->size;
836 req->status = TEGRA_DMA_REQ_SUCCESS;
837
838 ch->callback = req->complete;
839 ch->cb_req = req;
840
841 start_head_req(ch);
842 return;
843}
844
845static void handle_continuous_dbl_dma(struct tegra_dma_channel *ch)
846{
847 struct tegra_dma_req *req;
848
849 req = list_entry(ch->list.next, typeof(*req), node);
850
851 if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) {
852 bool is_dma_ping_complete;
853 unsigned long status = readl(ch->addr + APB_DMA_CHAN_STA);
854 is_dma_ping_complete = (status & STA_PING_PONG) ? true : false;
855
856 /* Ping pong status shows in reverse if it is Memory write */
857 if (req->to_memory)
858 is_dma_ping_complete = !is_dma_ping_complete;
859
860 /* Out of sync - Release current buffer */
861 if (!is_dma_ping_complete) {
862 /*
863 * We should not land here if queue mechanism
864 * with system latency are properly configured.
865 */
866 req->bytes_transferred += req->size;
867
868 list_del(&req->node);
869 ch->callback = req->complete;
870 ch->cb_req = req;
871
872 tegra_dma_abort_req(ch, req,
873 "Dma becomes out of sync for ping-pong buffer");
874 return;
875 }
876
877 /*
878 * Configure next request so after full buffer transfer,
879 * it can be start without sw intervention.
880 */
881 configure_next_req(ch, req);
882
883 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL;
884 req->status = TEGRA_DMA_REQ_SUCCESS;
885 req->bytes_transferred += req->size >> 1;
886
887 ch->callback = req->threshold;
888 ch->cb_req = req;
889 return;
890 }
891
892 if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) {
893 /* Interrupt for full buffer complete */
894 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL;
895 req->bytes_transferred += req->size >> 1;
896 req->status = TEGRA_DMA_REQ_SUCCESS;
897
898 list_del(&req->node);
899 ch->callback = req->complete;
900 ch->cb_req = req;
901
902 handle_continuous_head_request(ch, req);
903 return;
904 }
905 tegra_dma_abort_req(ch, req, "Dma status is not on sync\n");
906 /* Dma should be stop much earlier */
907 BUG();
908 return;
909}
910
911static void handle_continuous_sngl_dma(struct tegra_dma_channel *ch)
912{
913 struct tegra_dma_req *req;
914
915 req = list_entry(ch->list.next, typeof(*req), node);
916 if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_FULL) {
917 tegra_dma_stop(ch);
918 pr_err("%s: DMA complete irq without corresponding req\n",
919 __func__);
920 WARN_ON(1);
921 return;
922 }
923
924 /* Handle the case when buffer is completely full */
925 req->bytes_transferred += req->size;
926 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL;
927 req->status = TEGRA_DMA_REQ_SUCCESS;
928
929 list_del(&req->node);
930 ch->callback = req->complete;
931 ch->cb_req = req;
932
933 handle_continuous_head_request(ch, req);
934 return;
935}
936
937static void handle_dma_isr_locked(struct tegra_dma_channel *ch)
938{
939 /* There should be proper isr handler */
940 BUG_ON(!ch->isr_handler);
941
942 if (list_empty(&ch->list)) {
943 tegra_dma_stop(ch);
944 pr_err("%s: No requests in the list.\n", __func__);
945 WARN_ON(1);
946 return;
947 }
948
949 ch->isr_handler(ch);
950}
951
952static irqreturn_t dma_isr(int irq, void *data)
953{
954 struct tegra_dma_channel *ch = data;
955 unsigned long irq_flags;
956 unsigned long status;
957 dma_callback callback = NULL;
958 struct tegra_dma_req *cb_req = NULL;
959
960 spin_lock_irqsave(&ch->lock, irq_flags);
961
962 /*
963 * Calbacks should be set and cleared while holding the spinlock,
964 * never left set
965 */
966 if (ch->callback || ch->cb_req)
967 pr_err("%s():"
968 "Channel %d callbacks are not initialized properly\n",
969 __func__, ch->id);
970 BUG_ON(ch->callback || ch->cb_req);
971
972 status = readl(ch->addr + APB_DMA_CHAN_STA);
973 if (status & STA_ISE_EOC) {
974 /* Clear dma int status */
975 writel(status, ch->addr + APB_DMA_CHAN_STA);
976 handle_dma_isr_locked(ch);
977 callback = ch->callback;
978 cb_req = ch->cb_req;
979 ch->callback = NULL;
980 ch->cb_req = NULL;
981 } else {
982 pr_info("Interrupt is already handled %d\n", ch->id);
983 }
984 spin_unlock_irqrestore(&ch->lock, irq_flags);
985
986 /* Call callback function to notify client if it is there */
987 if (callback)
988 callback(cb_req);
989 return IRQ_HANDLED;
990}
991
992int __init tegra_dma_init(void)
993{
994 int ret = 0;
995 int i;
996 unsigned int irq;
997
998 bitmap_fill(channel_usage, NV_DMA_MAX_CHANNELS);
999
1000 dma_clk = clk_get_sys("tegra-dma", NULL);
1001 if (IS_ERR_OR_NULL(dma_clk)) {
1002 pr_err("Unable to get clock for APB DMA\n");
1003 ret = PTR_ERR(dma_clk);
1004 goto fail;
1005 }
1006 ret = clk_enable(dma_clk);
1007 if (ret != 0) {
1008 pr_err("Unable to enable clock for APB DMA\n");
1009 goto fail;
1010 }
1011
1012 /*
1013 * Resetting all dma channels to make sure all channels are in init
1014 * state.
1015 */
1016 tegra_periph_reset_assert(dma_clk);
1017 udelay(10);
1018 tegra_periph_reset_deassert(dma_clk);
1019 udelay(10);
1020
1021 writel(GEN_ENABLE, general_dma_addr + APB_DMA_GEN);
1022 writel(0, general_dma_addr + APB_DMA_CNTRL);
1023 writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX),
1024 general_dma_addr + APB_DMA_IRQ_MASK_SET);
1025
1026 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
1027 struct tegra_dma_channel *ch = &dma_channels[i];
1028
1029 ch->id = i;
1030 ch->isr_handler = NULL;
1031 snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i);
1032
1033 memset(ch->client_name, 0, sizeof(ch->client_name));
1034
1035 ch->addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
1036 TEGRA_APB_DMA_CH0_SIZE * i);
1037
1038 spin_lock_init(&ch->lock);
1039 INIT_LIST_HEAD(&ch->list);
1040
1041#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1042 if (i >= 16)
1043 irq = INT_APB_DMA_CH16 + i - 16;
1044 else
1045#endif
1046 irq = INT_APB_DMA_CH0 + i;
1047 ret = request_irq(irq, dma_isr, 0, dma_channels[i].name, ch);
1048 if (ret) {
1049 pr_err("Failed to register IRQ %d for DMA %d\n",
1050 irq, i);
1051 goto fail;
1052 }
1053 ch->irq = irq;
1054
1055 __clear_bit(i, channel_usage);
1056 }
1057 /* mark the shared channel allocated */
1058 __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage);
1059
1060 tegra_dma_initialized = true;
1061
1062 return 0;
1063fail:
1064 writel(0, general_dma_addr + APB_DMA_GEN);
1065 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
1066 struct tegra_dma_channel *ch = &dma_channels[i];
1067 if (ch->irq)
1068 free_irq(ch->irq, ch);
1069 }
1070 return ret;
1071}
1072postcore_initcall(tegra_dma_init);
1073
1074#ifdef CONFIG_PM_SLEEP
1075
1076static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3];
1077
1078static int tegra_dma_suspend(void)
1079{
1080 u32 *ctx = apb_dma;
1081 int i;
1082
1083 *ctx++ = readl(general_dma_addr + APB_DMA_GEN);
1084 *ctx++ = readl(general_dma_addr + APB_DMA_CNTRL);
1085 *ctx++ = readl(general_dma_addr + APB_DMA_IRQ_MASK);
1086
1087 for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
1088 void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
1089 TEGRA_APB_DMA_CH0_SIZE * i);
1090
1091 *ctx++ = readl(addr + APB_DMA_CHAN_CSR);
1092 *ctx++ = readl(addr + APB_DMA_CHAN_AHB_PTR);
1093 *ctx++ = readl(addr + APB_DMA_CHAN_AHB_SEQ);
1094 *ctx++ = readl(addr + APB_DMA_CHAN_APB_PTR);
1095 *ctx++ = readl(addr + APB_DMA_CHAN_APB_SEQ);
1096 }
1097
1098 /* Disabling clock of dma. */
1099 clk_disable(dma_clk);
1100 return 0;
1101}
1102
1103static void tegra_dma_resume(void)
1104{
1105 u32 *ctx = apb_dma;
1106 int i;
1107
1108 /* Enabling clock of dma. */
1109 clk_enable(dma_clk);
1110
1111 writel(*ctx++, general_dma_addr + APB_DMA_GEN);
1112 writel(*ctx++, general_dma_addr + APB_DMA_CNTRL);
1113 writel(*ctx++, general_dma_addr + APB_DMA_IRQ_MASK);
1114
1115 for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
1116 void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
1117 TEGRA_APB_DMA_CH0_SIZE * i);
1118
1119 writel(*ctx++, addr + APB_DMA_CHAN_CSR);
1120 writel(*ctx++, addr + APB_DMA_CHAN_AHB_PTR);
1121 writel(*ctx++, addr + APB_DMA_CHAN_AHB_SEQ);
1122 writel(*ctx++, addr + APB_DMA_CHAN_APB_PTR);
1123 writel(*ctx++, addr + APB_DMA_CHAN_APB_SEQ);
1124 }
1125}
1126
1127static struct syscore_ops tegra_dma_syscore_ops = {
1128 .suspend = tegra_dma_suspend,
1129 .resume = tegra_dma_resume,
1130};
1131
1132static int tegra_dma_syscore_init(void)
1133{
1134 register_syscore_ops(&tegra_dma_syscore_ops);
1135
1136 return 0;
1137}
1138subsys_initcall(tegra_dma_syscore_init);
1139#endif
1140
1141#ifdef CONFIG_DEBUG_FS
1142
1143#include <linux/debugfs.h>
1144#include <linux/seq_file.h>
1145
1146static int dbg_dma_show(struct seq_file *s, void *unused)
1147{
1148 int i;
1149
1150 seq_printf(s, " APBDMA global register\n");
1151 seq_printf(s, "DMA_GEN: 0x%08x\n",
1152 __raw_readl(general_dma_addr + APB_DMA_GEN));
1153 seq_printf(s, "DMA_CNTRL: 0x%08x\n",
1154 __raw_readl(general_dma_addr + APB_DMA_CNTRL));
1155 seq_printf(s, "IRQ_MASK: 0x%08x\n",
1156 __raw_readl(general_dma_addr + APB_DMA_IRQ_MASK));
1157
1158 for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
1159 void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
1160 TEGRA_APB_DMA_CH0_SIZE * i);
1161
1162 seq_printf(s, " APBDMA channel %02d register\n", i);
1163 seq_printf(s, "0x00: 0x%08x 0x%08x 0x%08x 0x%08x\n",
1164 __raw_readl(addr + 0x0),
1165 __raw_readl(addr + 0x4),
1166 __raw_readl(addr + 0x8),
1167 __raw_readl(addr + 0xC));
1168 seq_printf(s, "0x10: 0x%08x 0x%08x 0x%08x 0x%08x\n",
1169 __raw_readl(addr + 0x10),
1170 __raw_readl(addr + 0x14),
1171 __raw_readl(addr + 0x18),
1172 __raw_readl(addr + 0x1C));
1173 }
1174 seq_printf(s, "\nAPB DMA users\n");
1175 seq_printf(s, "-------------\n");
1176 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
1177 struct tegra_dma_channel *ch = &dma_channels[i];
1178 if (strlen(ch->client_name) > 0)
1179 seq_printf(s, "dma %d -> %s\n", i, ch->client_name);
1180 }
1181 return 0;
1182}
1183
1184static int dbg_dma_open(struct inode *inode, struct file *file)
1185{
1186 return single_open(file, dbg_dma_show, &inode->i_private);
1187}
1188
1189static const struct file_operations debug_fops = {
1190 .open = dbg_dma_open,
1191 .read = seq_read,
1192 .llseek = seq_lseek,
1193 .release = single_release,
1194};
1195
1196static int __init tegra_dma_debuginit(void)
1197{
1198 (void) debugfs_create_file("tegra_dma", S_IRUGO,
1199 NULL, NULL, &debug_fops);
1200 return 0;
1201}
1202late_initcall(tegra_dma_debuginit);
1203#endif
diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c
new file mode 100644
index 00000000000..8723e6fa60d
--- /dev/null
+++ b/arch/arm/mach-tegra/dvfs.c
@@ -0,0 +1,846 @@
1/*
2 *
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * Author:
6 * Colin Cross <ccross@google.com>
7 *
8 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/clk.h>
23#include <linux/clkdev.h>
24#include <linux/debugfs.h>
25#include <linux/init.h>
26#include <linux/list.h>
27#include <linux/list_sort.h>
28#include <linux/module.h>
29#include <linux/regulator/consumer.h>
30#include <linux/seq_file.h>
31#include <linux/slab.h>
32#include <linux/suspend.h>
33#include <linux/delay.h>
34#include <linux/reboot.h>
35
36#include <mach/clk.h>
37
38#include "board.h"
39#include "clock.h"
40#include "dvfs.h"
41
42#define DVFS_RAIL_STATS_BIN 25
43#define DVFS_RAIL_STATS_SCALE 2
44#define DVFS_RAIL_STATS_RANGE ((DVFS_RAIL_STATS_TOP_BIN - 1) * \
45 DVFS_RAIL_STATS_BIN / DVFS_RAIL_STATS_SCALE)
46
47static LIST_HEAD(dvfs_rail_list);
48static DEFINE_MUTEX(dvfs_lock);
49static DEFINE_MUTEX(rail_disable_lock);
50
51static int dvfs_rail_update(struct dvfs_rail *rail);
52
53void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n)
54{
55 int i;
56 struct dvfs_relationship *rel;
57
58 mutex_lock(&dvfs_lock);
59
60 for (i = 0; i < n; i++) {
61 rel = &rels[i];
62 list_add_tail(&rel->from_node, &rel->to->relationships_from);
63 list_add_tail(&rel->to_node, &rel->from->relationships_to);
64 }
65
66 mutex_unlock(&dvfs_lock);
67}
68
69int tegra_dvfs_init_rails(struct dvfs_rail *rails[], int n)
70{
71 int i;
72
73 mutex_lock(&dvfs_lock);
74
75 for (i = 0; i < n; i++) {
76 INIT_LIST_HEAD(&rails[i]->dvfs);
77 INIT_LIST_HEAD(&rails[i]->relationships_from);
78 INIT_LIST_HEAD(&rails[i]->relationships_to);
79 rails[i]->millivolts = rails[i]->nominal_millivolts;
80 rails[i]->new_millivolts = rails[i]->nominal_millivolts;
81 if (!rails[i]->step)
82 rails[i]->step = rails[i]->max_millivolts;
83
84 list_add_tail(&rails[i]->node, &dvfs_rail_list);
85 }
86
87 mutex_unlock(&dvfs_lock);
88
89 return 0;
90};
91
92static int dvfs_solve_relationship(struct dvfs_relationship *rel)
93{
94 return rel->solve(rel->from, rel->to);
95}
96
97/* rail statistic - called during rail init, or under dfs_lock, or with
98 CPU0 only on-line, and interrupts disabled */
99static void dvfs_rail_stats_init(struct dvfs_rail *rail, int millivolts)
100{
101 rail->stats.last_update = ktime_get();
102 if (millivolts >= rail->min_millivolts) {
103 int i = 1 + (2 * (millivolts - rail->min_millivolts) *
104 DVFS_RAIL_STATS_SCALE + DVFS_RAIL_STATS_BIN) /
105 (2 * DVFS_RAIL_STATS_BIN);
106 rail->stats.last_index = min(i, DVFS_RAIL_STATS_TOP_BIN);
107 }
108
109 if (rail->max_millivolts >
110 rail->min_millivolts + DVFS_RAIL_STATS_RANGE)
111 pr_warn("tegra_dvfs: %s: stats above %d mV will be squashed\n",
112 rail->reg_id,
113 rail->min_millivolts + DVFS_RAIL_STATS_RANGE);
114}
115
116static void dvfs_rail_stats_update(
117 struct dvfs_rail *rail, int millivolts, ktime_t now)
118{
119 rail->stats.time_at_mv[rail->stats.last_index] = ktime_add(
120 rail->stats.time_at_mv[rail->stats.last_index], ktime_sub(
121 now, rail->stats.last_update));
122 rail->stats.last_update = now;
123
124 if (rail->stats.off)
125 return;
126
127 if (millivolts >= rail->min_millivolts) {
128 int i = 1 + (2 * (millivolts - rail->min_millivolts) *
129 DVFS_RAIL_STATS_SCALE + DVFS_RAIL_STATS_BIN) /
130 (2 * DVFS_RAIL_STATS_BIN);
131 rail->stats.last_index = min(i, DVFS_RAIL_STATS_TOP_BIN);
132 } else if (millivolts == 0)
133 rail->stats.last_index = 0;
134}
135
136static void dvfs_rail_stats_pause(struct dvfs_rail *rail,
137 ktime_t delta, bool on)
138{
139 int i = on ? rail->stats.last_index : 0;
140 rail->stats.time_at_mv[i] = ktime_add(rail->stats.time_at_mv[i], delta);
141}
142
143void tegra_dvfs_rail_off(struct dvfs_rail *rail, ktime_t now)
144{
145 if (rail) {
146 dvfs_rail_stats_update(rail, 0, now);
147 rail->stats.off = true;
148 }
149}
150
151void tegra_dvfs_rail_on(struct dvfs_rail *rail, ktime_t now)
152{
153 if (rail) {
154 rail->stats.off = false;
155 dvfs_rail_stats_update(rail, rail->millivolts, now);
156 }
157}
158
159void tegra_dvfs_rail_pause(struct dvfs_rail *rail, ktime_t delta, bool on)
160{
161 if (rail)
162 dvfs_rail_stats_pause(rail, delta, on);
163}
164
165/* Sets the voltage on a dvfs rail to a specific value, and updates any
166 * rails that depend on this rail. */
167static int dvfs_rail_set_voltage(struct dvfs_rail *rail, int millivolts)
168{
169 int ret = 0;
170 struct dvfs_relationship *rel;
171 int step = (millivolts > rail->millivolts) ? rail->step : -rail->step;
172 int i;
173 int steps;
174 bool jmp_to_zero;
175
176 if (!rail->reg) {
177 if (millivolts == rail->millivolts)
178 return 0;
179 else
180 return -EINVAL;
181 }
182
183 if (rail->disabled)
184 return 0;
185
186 rail->resolving_to = true;
187 jmp_to_zero = rail->jmp_to_zero &&
188 ((millivolts == 0) || (rail->millivolts == 0));
189 steps = jmp_to_zero ? 1 :
190 DIV_ROUND_UP(abs(millivolts - rail->millivolts), rail->step);
191
192 for (i = 0; i < steps; i++) {
193 if (!jmp_to_zero &&
194 (abs(millivolts - rail->millivolts) > rail->step))
195 rail->new_millivolts = rail->millivolts + step;
196 else
197 rail->new_millivolts = millivolts;
198
199 /* Before changing the voltage, tell each rail that depends
200 * on this rail that the voltage will change.
201 * This rail will be the "from" rail in the relationship,
202 * the rail that depends on this rail will be the "to" rail.
203 * from->millivolts will be the old voltage
204 * from->new_millivolts will be the new voltage */
205 list_for_each_entry(rel, &rail->relationships_to, to_node) {
206 ret = dvfs_rail_update(rel->to);
207 if (ret)
208 goto out;
209 }
210
211 if (!rail->disabled) {
212 rail->updating = true;
213 ret = regulator_set_voltage(rail->reg,
214 rail->new_millivolts * 1000,
215 rail->max_millivolts * 1000);
216 rail->updating = false;
217 }
218 if (ret) {
219 pr_err("Failed to set dvfs regulator %s\n", rail->reg_id);
220 goto out;
221 }
222
223 rail->millivolts = rail->new_millivolts;
224 dvfs_rail_stats_update(rail, rail->millivolts, ktime_get());
225
226 /* After changing the voltage, tell each rail that depends
227 * on this rail that the voltage has changed.
228 * from->millivolts and from->new_millivolts will be the
229 * new voltage */
230 list_for_each_entry(rel, &rail->relationships_to, to_node) {
231 ret = dvfs_rail_update(rel->to);
232 if (ret)
233 goto out;
234 }
235 }
236
237 if (unlikely(rail->millivolts != millivolts)) {
238 pr_err("%s: rail didn't reach target %d in %d steps (%d)\n",
239 __func__, millivolts, steps, rail->millivolts);
240 ret = -EINVAL;
241 }
242
243out:
244 rail->resolving_to = false;
245 return ret;
246}
247
248/* Determine the minimum valid voltage for a rail, taking into account
249 * the dvfs clocks and any rails that this rail depends on. Calls
250 * dvfs_rail_set_voltage with the new voltage, which will call
251 * dvfs_rail_update on any rails that depend on this rail. */
252static int dvfs_rail_update(struct dvfs_rail *rail)
253{
254 int millivolts = 0;
255 struct dvfs *d;
256 struct dvfs_relationship *rel;
257 int ret = 0;
258 int steps;
259
260 /* if dvfs is suspended, return and handle it during resume */
261 if (rail->suspended)
262 return 0;
263
264 /* if regulators are not connected yet, return and handle it later */
265 if (!rail->reg)
266 return 0;
267
268 /* if rail update is entered while resolving circular dependencies,
269 abort recursion */
270 if (rail->resolving_to)
271 return 0;
272
273 /* Find the maximum voltage requested by any clock */
274 list_for_each_entry(d, &rail->dvfs, reg_node)
275 millivolts = max(d->cur_millivolts, millivolts);
276
277 /* retry update if limited by from-relationship to account for
278 circular dependencies */
279 steps = DIV_ROUND_UP(abs(millivolts - rail->millivolts), rail->step);
280 for (; steps >= 0; steps--) {
281 rail->new_millivolts = millivolts;
282
283 /* Check any rails that this rail depends on */
284 list_for_each_entry(rel, &rail->relationships_from, from_node)
285 rail->new_millivolts = dvfs_solve_relationship(rel);
286
287 if (rail->new_millivolts == rail->millivolts)
288 break;
289
290 ret = dvfs_rail_set_voltage(rail, rail->new_millivolts);
291 }
292
293 return ret;
294}
295
296static int dvfs_rail_connect_to_regulator(struct dvfs_rail *rail)
297{
298 struct regulator *reg;
299 int v;
300
301 if (!rail->reg) {
302 reg = regulator_get(NULL, rail->reg_id);
303 if (IS_ERR(reg)) {
304 pr_err("tegra_dvfs: failed to connect %s rail\n",
305 rail->reg_id);
306 return -EINVAL;
307 }
308 rail->reg = reg;
309 }
310
311 v = regulator_get_voltage(rail->reg);
312 if (v < 0) {
313 pr_err("tegra_dvfs: failed initial get %s voltage\n",
314 rail->reg_id);
315 return v;
316 }
317 rail->millivolts = v / 1000;
318 rail->new_millivolts = rail->millivolts;
319 dvfs_rail_stats_init(rail, rail->millivolts);
320 return 0;
321}
322
323static inline unsigned long *dvfs_get_freqs(struct dvfs *d)
324{
325 return (d->alt_freqs_state == ALT_FREQS_ENABLED) ?
326 &d->alt_freqs[0] : &d->freqs[0];
327}
328
329static int
330__tegra_dvfs_set_rate(struct dvfs *d, unsigned long rate)
331{
332 int i = 0;
333 int ret;
334 unsigned long *freqs = dvfs_get_freqs(d);
335
336 if (freqs == NULL || d->millivolts == NULL)
337 return -ENODEV;
338
339 if (rate > freqs[d->num_freqs - 1]) {
340 pr_warn("tegra_dvfs: rate %lu too high for dvfs on %s\n", rate,
341 d->clk_name);
342 return -EINVAL;
343 }
344
345 if (rate == 0) {
346 d->cur_millivolts = 0;
347 } else {
348 while (i < d->num_freqs && rate > freqs[i])
349 i++;
350
351 if ((d->max_millivolts) &&
352 (d->millivolts[i] > d->max_millivolts)) {
353 pr_warn("tegra_dvfs: voltage %d too high for dvfs on"
354 " %s\n", d->millivolts[i], d->clk_name);
355 return -EINVAL;
356 }
357 d->cur_millivolts = d->millivolts[i];
358 }
359
360 d->cur_rate = rate;
361
362 ret = dvfs_rail_update(d->dvfs_rail);
363 if (ret)
364 pr_err("Failed to set regulator %s for clock %s to %d mV\n",
365 d->dvfs_rail->reg_id, d->clk_name, d->cur_millivolts);
366
367 return ret;
368}
369
370static inline int dvfs_alt_freqs_set(struct dvfs *d, bool enable)
371{
372 if (d->alt_freqs_state == ALT_FREQS_NOT_SUPPORTED)
373 return -ENOSYS;
374
375 d->alt_freqs_state = enable ? ALT_FREQS_ENABLED : ALT_FREQS_DISABLED;
376 return 0;
377}
378
379int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable)
380{
381 int ret;
382 enum dvfs_alt_freqs old_state;
383
384 mutex_lock(&dvfs_lock);
385
386 old_state = d->alt_freqs_state;
387 ret = dvfs_alt_freqs_set(d, enable);
388 if (!ret && (old_state != d->alt_freqs_state))
389 ret = __tegra_dvfs_set_rate(d, d->cur_rate);
390
391 mutex_unlock(&dvfs_lock);
392 return ret;
393}
394
395int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate)
396{
397 int i;
398
399 if (!rate || !c->dvfs)
400 return 0;
401
402 if (!c->dvfs->millivolts)
403 return -ENODEV;
404
405 /*
406 * Predicted voltage can not be used across the switch to alternative
407 * frequency limits. For now, just fail the call for clock that has
408 * alternative limits initialized.
409 */
410 if (c->dvfs->alt_freqs_state != ALT_FREQS_NOT_SUPPORTED)
411 return -ENOSYS;
412
413 for (i = 0; i < c->dvfs->num_freqs; i++) {
414 if (rate <= c->dvfs->freqs[i])
415 break;
416 }
417
418 if (i == c->dvfs->num_freqs)
419 return -EINVAL;
420
421 return c->dvfs->millivolts[i];
422}
423
424int tegra_dvfs_set_rate(struct clk *c, unsigned long rate)
425{
426 int ret;
427
428 if (!c->dvfs)
429 return -EINVAL;
430
431 mutex_lock(&dvfs_lock);
432 ret = __tegra_dvfs_set_rate(c->dvfs, rate);
433 mutex_unlock(&dvfs_lock);
434
435 return ret;
436}
437EXPORT_SYMBOL(tegra_dvfs_set_rate);
438
439/* May only be called during clock init, does not take any locks on clock c. */
440int __init tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d)
441{
442 int i;
443
444 if (c->dvfs) {
445 pr_err("Error when enabling dvfs on %s for clock %s:\n",
446 d->dvfs_rail->reg_id, c->name);
447 pr_err("DVFS already enabled for %s\n",
448 c->dvfs->dvfs_rail->reg_id);
449 return -EINVAL;
450 }
451
452 for (i = 0; i < MAX_DVFS_FREQS; i++) {
453 if (d->millivolts[i] == 0)
454 break;
455
456 d->freqs[i] *= d->freqs_mult;
457
458 /* If final frequencies are 0, pad with previous frequency */
459 if (d->freqs[i] == 0 && i > 1)
460 d->freqs[i] = d->freqs[i - 1];
461 }
462 d->num_freqs = i;
463
464 if (d->auto_dvfs) {
465 c->auto_dvfs = true;
466 clk_set_cansleep(c);
467 }
468
469 c->dvfs = d;
470
471 mutex_lock(&dvfs_lock);
472 list_add_tail(&d->reg_node, &d->dvfs_rail->dvfs);
473 mutex_unlock(&dvfs_lock);
474
475 return 0;
476}
477
478static bool tegra_dvfs_all_rails_suspended(void)
479{
480 struct dvfs_rail *rail;
481 bool all_suspended = true;
482
483 list_for_each_entry(rail, &dvfs_rail_list, node)
484 if (!rail->suspended && !rail->disabled)
485 all_suspended = false;
486
487 return all_suspended;
488}
489
490static bool tegra_dvfs_from_rails_suspended_or_solved(struct dvfs_rail *to)
491{
492 struct dvfs_relationship *rel;
493 bool all_suspended = true;
494
495 list_for_each_entry(rel, &to->relationships_from, from_node)
496 if (!rel->from->suspended && !rel->from->disabled &&
497 !rel->solved_at_nominal)
498 all_suspended = false;
499
500 return all_suspended;
501}
502
503static int tegra_dvfs_suspend_one(void)
504{
505 struct dvfs_rail *rail;
506 int ret;
507
508 list_for_each_entry(rail, &dvfs_rail_list, node) {
509 if (!rail->suspended && !rail->disabled &&
510 tegra_dvfs_from_rails_suspended_or_solved(rail)) {
511 ret = dvfs_rail_set_voltage(rail,
512 rail->nominal_millivolts);
513 if (ret)
514 return ret;
515 rail->suspended = true;
516 return 0;
517 }
518 }
519
520 return -EINVAL;
521}
522
523static void tegra_dvfs_resume(void)
524{
525 struct dvfs_rail *rail;
526
527 mutex_lock(&dvfs_lock);
528
529 list_for_each_entry(rail, &dvfs_rail_list, node)
530 rail->suspended = false;
531
532 list_for_each_entry(rail, &dvfs_rail_list, node)
533 dvfs_rail_update(rail);
534
535 mutex_unlock(&dvfs_lock);
536}
537
538static int tegra_dvfs_suspend(void)
539{
540 int ret = 0;
541
542 mutex_lock(&dvfs_lock);
543
544 while (!tegra_dvfs_all_rails_suspended()) {
545 ret = tegra_dvfs_suspend_one();
546 if (ret)
547 break;
548 }
549
550 mutex_unlock(&dvfs_lock);
551
552 if (ret)
553 tegra_dvfs_resume();
554
555 return ret;
556}
557
558static int tegra_dvfs_pm_notify(struct notifier_block *nb,
559 unsigned long event, void *data)
560{
561 switch (event) {
562 case PM_SUSPEND_PREPARE:
563 if (tegra_dvfs_suspend())
564 return NOTIFY_STOP;
565 break;
566 case PM_POST_SUSPEND:
567 tegra_dvfs_resume();
568 break;
569 }
570
571 return NOTIFY_OK;
572};
573
574static struct notifier_block tegra_dvfs_nb = {
575 .notifier_call = tegra_dvfs_pm_notify,
576};
577
578static int tegra_dvfs_reboot_notify(struct notifier_block *nb,
579 unsigned long event, void *data)
580{
581 switch (event) {
582 case SYS_RESTART:
583 case SYS_HALT:
584 case SYS_POWER_OFF:
585 tegra_dvfs_suspend();
586 return NOTIFY_OK;
587 }
588 return NOTIFY_DONE;
589}
590
591static struct notifier_block tegra_dvfs_reboot_nb = {
592 .notifier_call = tegra_dvfs_reboot_notify,
593};
594
595/* must be called with dvfs lock held */
596static void __tegra_dvfs_rail_disable(struct dvfs_rail *rail)
597{
598 int ret;
599
600 ret = dvfs_rail_set_voltage(rail, rail->nominal_millivolts);
601 if (ret)
602 pr_info("dvfs: failed to set regulator %s to disable "
603 "voltage %d\n", rail->reg_id,
604 rail->nominal_millivolts);
605 rail->disabled = true;
606}
607
608/* must be called with dvfs lock held */
609static void __tegra_dvfs_rail_enable(struct dvfs_rail *rail)
610{
611 rail->disabled = false;
612 dvfs_rail_update(rail);
613}
614
615void tegra_dvfs_rail_enable(struct dvfs_rail *rail)
616{
617 mutex_lock(&rail_disable_lock);
618
619 if (rail->disabled) {
620 mutex_lock(&dvfs_lock);
621 __tegra_dvfs_rail_enable(rail);
622 mutex_unlock(&dvfs_lock);
623
624 tegra_dvfs_rail_post_enable(rail);
625 }
626 mutex_unlock(&rail_disable_lock);
627
628}
629
630void tegra_dvfs_rail_disable(struct dvfs_rail *rail)
631{
632 mutex_lock(&rail_disable_lock);
633 if (rail->disabled)
634 goto out;
635
636 /* rail disable will set it to nominal voltage underneath clock
637 framework - need to re-configure clock rates that are not safe
638 at nominal (yes, unsafe at nominal is ugly, but possible). Rate
639 change must be done outside of dvfs lock. */
640 if (tegra_dvfs_rail_disable_prepare(rail)) {
641 pr_info("dvfs: failed to prepare regulator %s to disable\n",
642 rail->reg_id);
643 goto out;
644 }
645
646 mutex_lock(&dvfs_lock);
647 __tegra_dvfs_rail_disable(rail);
648 mutex_unlock(&dvfs_lock);
649out:
650 mutex_unlock(&rail_disable_lock);
651}
652
653int tegra_dvfs_rail_disable_by_name(const char *reg_id)
654{
655 struct dvfs_rail *rail = tegra_dvfs_get_rail_by_name(reg_id);
656 if (!rail)
657 return -EINVAL;
658
659 tegra_dvfs_rail_disable(rail);
660 return 0;
661}
662
663struct dvfs_rail *tegra_dvfs_get_rail_by_name(const char *reg_id)
664{
665 struct dvfs_rail *rail;
666
667 mutex_lock(&dvfs_lock);
668 list_for_each_entry(rail, &dvfs_rail_list, node) {
669 if (!strcmp(reg_id, rail->reg_id)) {
670 mutex_unlock(&dvfs_lock);
671 return rail;
672 }
673 }
674 mutex_unlock(&dvfs_lock);
675 return NULL;
676}
677
678bool tegra_dvfs_rail_updating(struct clk *clk)
679{
680 return (!clk ? false :
681 (!clk->dvfs ? false :
682 (!clk->dvfs->dvfs_rail ? false :
683 (clk->dvfs->dvfs_rail->updating))));
684}
685
686/*
687 * Iterate through all the dvfs regulators, finding the regulator exported
688 * by the regulator api for each one. Must be called in late init, after
689 * all the regulator api's regulators are initialized.
690 */
691int __init tegra_dvfs_late_init(void)
692{
693 bool connected = true;
694 struct dvfs_rail *rail;
695
696 mutex_lock(&dvfs_lock);
697
698 list_for_each_entry(rail, &dvfs_rail_list, node)
699 if (dvfs_rail_connect_to_regulator(rail))
700 connected = false;
701
702 list_for_each_entry(rail, &dvfs_rail_list, node)
703 if (connected)
704 dvfs_rail_update(rail);
705 else
706 __tegra_dvfs_rail_disable(rail);
707
708 mutex_unlock(&dvfs_lock);
709
710 register_pm_notifier(&tegra_dvfs_nb);
711 register_reboot_notifier(&tegra_dvfs_reboot_nb);
712
713 return 0;
714}
715late_initcall(tegra_dvfs_late_init);
716
717#ifdef CONFIG_DEBUG_FS
718static int dvfs_tree_sort_cmp(void *p, struct list_head *a, struct list_head *b)
719{
720 struct dvfs *da = list_entry(a, struct dvfs, reg_node);
721 struct dvfs *db = list_entry(b, struct dvfs, reg_node);
722 int ret;
723
724 ret = strcmp(da->dvfs_rail->reg_id, db->dvfs_rail->reg_id);
725 if (ret != 0)
726 return ret;
727
728 if (da->cur_millivolts < db->cur_millivolts)
729 return 1;
730 if (da->cur_millivolts > db->cur_millivolts)
731 return -1;
732
733 return strcmp(da->clk_name, db->clk_name);
734}
735
736static int dvfs_tree_show(struct seq_file *s, void *data)
737{
738 struct dvfs *d;
739 struct dvfs_rail *rail;
740 struct dvfs_relationship *rel;
741
742 seq_printf(s, " clock rate mV\n");
743 seq_printf(s, "--------------------------------\n");
744
745 mutex_lock(&dvfs_lock);
746
747 list_for_each_entry(rail, &dvfs_rail_list, node) {
748 seq_printf(s, "%s %d mV%s:\n", rail->reg_id,
749 rail->millivolts, rail->disabled ? " disabled" : "");
750 list_for_each_entry(rel, &rail->relationships_from, from_node) {
751 seq_printf(s, " %-10s %-7d mV %-4d mV\n",
752 rel->from->reg_id,
753 rel->from->millivolts,
754 dvfs_solve_relationship(rel));
755 }
756
757 list_sort(NULL, &rail->dvfs, dvfs_tree_sort_cmp);
758
759 list_for_each_entry(d, &rail->dvfs, reg_node) {
760 seq_printf(s, " %-10s %-10lu %-4d mV\n", d->clk_name,
761 d->cur_rate, d->cur_millivolts);
762 }
763 }
764
765 mutex_unlock(&dvfs_lock);
766
767 return 0;
768}
769
770static int dvfs_tree_open(struct inode *inode, struct file *file)
771{
772 return single_open(file, dvfs_tree_show, inode->i_private);
773}
774
775static const struct file_operations dvfs_tree_fops = {
776 .open = dvfs_tree_open,
777 .read = seq_read,
778 .llseek = seq_lseek,
779 .release = single_release,
780};
781
782static int rail_stats_show(struct seq_file *s, void *data)
783{
784 int i;
785 struct dvfs_rail *rail;
786
787 seq_printf(s, "%-12s %-10s (bin: %d.%dmV)\n", "millivolts", "time",
788 DVFS_RAIL_STATS_BIN / DVFS_RAIL_STATS_SCALE,
789 ((DVFS_RAIL_STATS_BIN * 100) / DVFS_RAIL_STATS_SCALE) % 100);
790
791 mutex_lock(&dvfs_lock);
792
793 list_for_each_entry(rail, &dvfs_rail_list, node) {
794 seq_printf(s, "%s\n", rail->reg_id);
795 dvfs_rail_stats_update(rail, -1, ktime_get());
796
797 seq_printf(s, "%-12d %-10llu\n", 0,
798 cputime64_to_clock_t(msecs_to_jiffies(
799 ktime_to_ms(rail->stats.time_at_mv[0]))));
800
801 for (i = 1; i <= DVFS_RAIL_STATS_TOP_BIN; i++) {
802 ktime_t ktime_zero = ktime_set(0, 0);
803 if (ktime_equal(rail->stats.time_at_mv[i], ktime_zero))
804 continue;
805 seq_printf(s, "%-12d %-10llu\n",
806 rail->min_millivolts + (i - 1) *
807 DVFS_RAIL_STATS_BIN / DVFS_RAIL_STATS_SCALE,
808 cputime64_to_clock_t(msecs_to_jiffies(
809 ktime_to_ms(rail->stats.time_at_mv[i])))
810 );
811 }
812 }
813 mutex_unlock(&dvfs_lock);
814 return 0;
815}
816
817static int rail_stats_open(struct inode *inode, struct file *file)
818{
819 return single_open(file, rail_stats_show, inode->i_private);
820}
821
822static const struct file_operations rail_stats_fops = {
823 .open = rail_stats_open,
824 .read = seq_read,
825 .llseek = seq_lseek,
826 .release = single_release,
827};
828
829int __init dvfs_debugfs_init(struct dentry *clk_debugfs_root)
830{
831 struct dentry *d;
832
833 d = debugfs_create_file("dvfs", S_IRUGO, clk_debugfs_root, NULL,
834 &dvfs_tree_fops);
835 if (!d)
836 return -ENOMEM;
837
838 d = debugfs_create_file("rails", S_IRUGO, clk_debugfs_root, NULL,
839 &rail_stats_fops);
840 if (!d)
841 return -ENOMEM;
842
843 return 0;
844}
845
846#endif
diff --git a/arch/arm/mach-tegra/dvfs.h b/arch/arm/mach-tegra/dvfs.h
new file mode 100644
index 00000000000..eaecf425fe8
--- /dev/null
+++ b/arch/arm/mach-tegra/dvfs.h
@@ -0,0 +1,180 @@
1/*
2 *
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * Author:
6 * Colin Cross <ccross@google.com>
7 *
8 * Copyright (C) 2010-2011 NVIDIA Corporation.
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 _TEGRA_DVFS_H_
22#define _TEGRA_DVFS_H_
23
24#define MAX_DVFS_FREQS 18
25#define DVFS_RAIL_STATS_TOP_BIN 40
26
27struct clk;
28struct dvfs_rail;
29
30/*
31 * dvfs_relationship between to rails, "from" and "to"
32 * when the rail changes, it will call dvfs_rail_update on the rails
33 * in the relationship_to list.
34 * when determining the voltage to set a rail to, it will consider each
35 * rail in the relationship_from list.
36 */
37struct dvfs_relationship {
38 struct dvfs_rail *to;
39 struct dvfs_rail *from;
40 int (*solve)(struct dvfs_rail *, struct dvfs_rail *);
41
42 struct list_head to_node; /* node in relationship_to list */
43 struct list_head from_node; /* node in relationship_from list */
44 bool solved_at_nominal;
45};
46
47struct rail_stats {
48 ktime_t time_at_mv[DVFS_RAIL_STATS_TOP_BIN + 1];
49 ktime_t last_update;
50 int last_index;
51 bool off;
52};
53
54struct dvfs_rail {
55 const char *reg_id;
56 int min_millivolts;
57 int max_millivolts;
58 int nominal_millivolts;
59 int step;
60 bool jmp_to_zero;
61 bool disabled;
62 bool updating;
63 bool resolving_to;
64
65 struct list_head node; /* node in dvfs_rail_list */
66 struct list_head dvfs; /* list head of attached dvfs clocks */
67 struct list_head relationships_to;
68 struct list_head relationships_from;
69 struct regulator *reg;
70 int millivolts;
71 int new_millivolts;
72 bool suspended;
73 struct rail_stats stats;
74};
75
76enum dvfs_alt_freqs {
77 ALT_FREQS_NOT_SUPPORTED = 0,
78 ALT_FREQS_DISABLED,
79 ALT_FREQS_ENABLED,
80};
81
82struct dvfs {
83 /* Used only by tegra2_clock.c */
84 const char *clk_name;
85 int speedo_id;
86 int process_id;
87
88 /* Must be initialized before tegra_dvfs_init */
89 int freqs_mult;
90 unsigned long freqs[MAX_DVFS_FREQS];
91 unsigned long alt_freqs[MAX_DVFS_FREQS];
92 const int *millivolts;
93 struct dvfs_rail *dvfs_rail;
94 bool auto_dvfs;
95 enum dvfs_alt_freqs alt_freqs_state;
96
97 /* Filled in by tegra_dvfs_init */
98 int max_millivolts;
99 int num_freqs;
100
101 int cur_millivolts;
102 unsigned long cur_rate;
103 struct list_head node;
104 struct list_head debug_node;
105 struct list_head reg_node;
106};
107
108extern struct dvfs_rail *tegra_cpu_rail;
109
110#ifdef CONFIG_TEGRA_SILICON_PLATFORM
111void tegra_soc_init_dvfs(void);
112int tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d);
113int dvfs_debugfs_init(struct dentry *clk_debugfs_root);
114int tegra_dvfs_late_init(void);
115int tegra_dvfs_init_rails(struct dvfs_rail *dvfs_rails[], int n);
116void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n);
117void tegra_dvfs_rail_enable(struct dvfs_rail *rail);
118void tegra_dvfs_rail_disable(struct dvfs_rail *rail);
119bool tegra_dvfs_rail_updating(struct clk *clk);
120void tegra_dvfs_rail_off(struct dvfs_rail *rail, ktime_t now);
121void tegra_dvfs_rail_on(struct dvfs_rail *rail, ktime_t now);
122void tegra_dvfs_rail_pause(struct dvfs_rail *rail, ktime_t delta, bool on);
123struct dvfs_rail *tegra_dvfs_get_rail_by_name(const char *reg_id);
124int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate);
125void tegra_dvfs_core_cap_enable(bool enable);
126void tegra_dvfs_core_cap_level_set(int level);
127int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable);
128void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update);
129#else
130static inline void tegra_soc_init_dvfs(void)
131{}
132static inline int tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d)
133{ return 0; }
134static inline int dvfs_debugfs_init(struct dentry *clk_debugfs_root)
135{ return 0; }
136static inline int tegra_dvfs_late_init(void)
137{ return 0; }
138static inline int tegra_dvfs_init_rails(struct dvfs_rail *dvfs_rails[], int n)
139{ return 0; }
140static inline void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n)
141{}
142static inline void tegra_dvfs_rail_enable(struct dvfs_rail *rail)
143{}
144static inline void tegra_dvfs_rail_disable(struct dvfs_rail *rail)
145{}
146static inline bool tegra_dvfs_rail_updating(struct clk *clk)
147{ return false; }
148static inline void tegra_dvfs_rail_off(struct dvfs_rail *rail, ktime_t now)
149{}
150static inline void tegra_dvfs_rail_on(struct dvfs_rail *rail, ktime_t now)
151{}
152static inline void tegra_dvfs_rail_pause(
153 struct dvfs_rail *rail, ktime_t delta, bool on)
154{}
155static inline struct dvfs_rail *tegra_dvfs_get_rail_by_name(const char *reg_id)
156{ return NULL; }
157static inline int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate)
158{ return 0; }
159static inline void tegra_dvfs_core_cap_enable(bool enable)
160{}
161static inline void tegra_dvfs_core_cap_level_set(int level)
162{}
163static inline int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable)
164{ return 0; }
165static inline void tegra_cpu_dvfs_alter(int edp_thermal_index,
166 bool before_clk_update)
167{}
168#endif
169
170#ifndef CONFIG_ARCH_TEGRA_2x_SOC
171int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail);
172int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail);
173#else
174static inline int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
175{ return 0; }
176static inline int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail)
177{ return 0; }
178#endif
179
180#endif
diff --git a/arch/arm/mach-tegra/edp.c b/arch/arm/mach-tegra/edp.c
new file mode 100644
index 00000000000..a4be48fed4d
--- /dev/null
+++ b/arch/arm/mach-tegra/edp.c
@@ -0,0 +1,515 @@
1/*
2 * arch/arm/mach-tegra/edp.c
3 *
4 * Copyright (C) 2011 NVIDIA, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/seq_file.h>
24#include <linux/slab.h>
25#include <mach/edp.h>
26
27#include "fuse.h"
28
29static const struct tegra_edp_limits *edp_limits;
30static int edp_limits_size;
31static unsigned int regulator_cur;
32
33static const unsigned int *system_edp_limits;
34
35/*
36 * Temperature step size cannot be less than 4C because of hysteresis
37 * delta
38 * Code assumes different temperatures for the same speedo_id /
39 * regulator_cur are adjacent in the table, and higest regulator_cur
40 * comes first
41 */
42static char __initdata tegra_edp_map[] = {
43 0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
44 0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
45 0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
46 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
47 0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
48 0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
49 0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
50 0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
51 0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
52 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
53 0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
54 0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
55 0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
56 0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
57 0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
58 0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
59 0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
60 0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
61 0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
62 0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
63 0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
64 0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
65 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
66 0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
67 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
68 0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
69 0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
70 0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
71 0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
72 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
73 0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
74 0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
75 0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
76 0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
77 0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
78 0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
79 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
80 0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
81 0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
82 0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
83 0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
84 0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
85 0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
86 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
87 0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
88 0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
89 0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
90 0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
91 0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
92 0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
93 0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
94 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
95 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
96 0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
97 0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
98 0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
99 0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
100 0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
101 0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
102 0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
103 0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
104 0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
105 0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
106 0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
107 0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
108 0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
109 0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
110 0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
111 0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
112 0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
113 0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
114 0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
115 0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
116 0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
117 0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
118 0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
119 0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
120 0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
121 0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
122 0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
123 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
124 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
125 0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
126 0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
127 0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
128 0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
129 0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
130 0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
131 0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
132 0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
133 0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
134 0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
135 0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
136 0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
137 0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
138 0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
139 0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
140 0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
141 0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
142 0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
143 0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
144 0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
145 0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
146 0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
147 0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
148 0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
149 0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
150 0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
151 0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
152 0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
153 0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
154 0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
155 0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
156 0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
157 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
158 0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
159 0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
160 0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
161 0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
162 0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
163 0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
164 0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
165 0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
166 0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
167 0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
168 0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
169 0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
170 0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
171 0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
172 0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
173 0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
174 0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
175 0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
176 0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
177 0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
178 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
179 0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
180 0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
181 0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
182 0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
183 0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
184 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
185 0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
186 0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
187 0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
188 0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
189 0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
190 0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
191 0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
192 0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
193 0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
194 0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
195 0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
196 0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
197 0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
198 0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
199 0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
200 0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
201 0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
202 0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
203 0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
204 0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
205 0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
206 0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
207 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
208 0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
209 0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
210 0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
211 0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
212 0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
213 0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
214 0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
215 0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
216 0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
217 0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
218 0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
219 0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
220 0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
221 0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
222 0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
223 0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
224 0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
225 0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
226 0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
227 0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
228 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
229 0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
230 0x5a, 0x46, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
231 0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
232 0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
233 0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
234 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
235 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
236 0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
237 0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
238 0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
239 0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
240 0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
241 0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
242 0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
243 0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
244 0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
245 0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
246 0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
247 0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
248 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
249 0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
250 0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
251 0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
252 0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
253 0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
254 0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
255 0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
256 0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
257 0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
258 0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
259 0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
260 0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
261 0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
262 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
263 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
264 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
265 0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
266 0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
267 0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
268 0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
269 0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
270 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
271 0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
272 0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
273 0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
274 0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
275 0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
276 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
277 0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
278 0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
279 0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
280 0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
281 0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
282 0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
283};
284
285
286static struct system_edp_entry __initdata tegra_system_edp_map[] = {
287
288/* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
289
290 { 1, 49, {130, 120, 120, 120} },
291 { 1, 44, {130, 120, 120, 110} },
292 { 1, 37, {130, 120, 110, 100} },
293 { 1, 35, {130, 120, 110, 90} },
294 { 1, 29, {130, 120, 100, 80} },
295 { 1, 27, {130, 120, 90, 80} },
296 { 1, 25, {130, 110, 80, 60} },
297 { 1, 21, {130, 100, 80, 40} },
298
299 { 4, 49, {130, 120, 120, 120} },
300 { 4, 44, {130, 120, 120, 110} },
301 { 4, 37, {130, 120, 110, 100} },
302 { 4, 35, {130, 120, 110, 90} },
303 { 4, 29, {130, 120, 100, 80} },
304 { 4, 27, {130, 120, 90, 80} },
305 { 4, 25, {130, 110, 80, 60} },
306 { 4, 21, {130, 100, 80, 40} },
307};
308
309/*
310 * "Safe entry" to be used when no match for speedo_id /
311 * regulator_cur is found; must be the last one
312 */
313static struct tegra_edp_limits edp_default_limits[] = {
314 {85, {1000000, 1000000, 1000000, 1000000} },
315};
316
317
318
319/*
320 * Specify regulator current in mA, e.g. 5000mA
321 * Use 0 for default
322 */
323void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
324{
325 int cpu_speedo_id = tegra_cpu_speedo_id();
326 int i, j;
327 struct tegra_edp_limits *e;
328 struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
329 int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
330
331 if (!regulator_mA) {
332 edp_limits = edp_default_limits;
333 edp_limits_size = ARRAY_SIZE(edp_default_limits);
334 return;
335 }
336 regulator_cur = regulator_mA;
337
338 for (i = 0; i < tsize; i++) {
339 if (t[i].speedo_id == cpu_speedo_id &&
340 t[i].regulator_100mA <= regulator_mA / 100)
341 break;
342 }
343
344 /* No entry found in tegra_edp_map */
345 if (i >= tsize) {
346 edp_limits = edp_default_limits;
347 edp_limits_size = ARRAY_SIZE(edp_default_limits);
348 return;
349 }
350
351 /* Find all rows for this entry */
352 for (j = i + 1; j < tsize; j++) {
353 if (t[i].speedo_id != t[j].speedo_id ||
354 t[i].regulator_100mA != t[j].regulator_100mA)
355 break;
356 }
357
358 edp_limits_size = j - i;
359 e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
360 GFP_KERNEL);
361 BUG_ON(!e);
362
363 for (j = 0; j < edp_limits_size; j++) {
364 e[j].temperature = (int)t[i+j].temperature;
365 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0] * 10000;
366 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1] * 10000;
367 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2] * 10000;
368 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3] * 10000;
369 }
370
371 if (edp_limits != edp_default_limits)
372 kfree(edp_limits);
373
374 edp_limits = e;
375}
376
377
378void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
379{
380 int cpu_speedo_id = tegra_cpu_speedo_id();
381 int i;
382 unsigned int *e;
383 struct system_edp_entry *t =
384 (struct system_edp_entry *)tegra_system_edp_map;
385 int tsize = sizeof(tegra_system_edp_map) /
386 sizeof(struct system_edp_entry);
387
388 if (!power_limit_mW) {
389 e = NULL;
390 goto out;
391 }
392
393 for (i = 0; i < tsize; i++)
394 if (t[i].speedo_id == cpu_speedo_id)
395 break;
396
397 if (i >= tsize) {
398 e = NULL;
399 goto out;
400 }
401
402 do {
403 if (t[i].power_limit_100mW <= power_limit_mW / 100)
404 break;
405 i++;
406 } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
407
408 if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
409 i--; /* No low enough entry in the table, use best possible */
410
411 e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
412 BUG_ON(!e);
413
414 e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
415 e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
416 e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
417 e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
418
419out:
420 kfree(system_edp_limits);
421
422 system_edp_limits = e;
423}
424
425
426void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
427{
428 *limits = edp_limits;
429 *size = edp_limits_size;
430}
431
432void tegra_get_system_edp_limits(const unsigned int **limits)
433{
434 *limits = system_edp_limits;
435}
436
437#ifdef CONFIG_DEBUG_FS
438
439static int edp_limit_debugfs_show(struct seq_file *s, void *data)
440{
441 seq_printf(s, "%u\n", tegra_get_edp_limit());
442 return 0;
443}
444
445static int edp_debugfs_show(struct seq_file *s, void *data)
446{
447 int i;
448
449 seq_printf(s, "-- CPU %sEDP table (%umA) --\n",
450 edp_limits == edp_default_limits ? "default " : "",
451 regulator_cur);
452 for (i = 0; i < edp_limits_size; i++) {
453 seq_printf(s, "%4dC: %10u %10u %10u %10u\n",
454 edp_limits[i].temperature,
455 edp_limits[i].freq_limits[0],
456 edp_limits[i].freq_limits[1],
457 edp_limits[i].freq_limits[2],
458 edp_limits[i].freq_limits[3]);
459 }
460
461 if (system_edp_limits) {
462 seq_printf(s, "\n-- System EDP table --\n");
463 seq_printf(s, "%10u %10u %10u %10u\n",
464 system_edp_limits[0],
465 system_edp_limits[1],
466 system_edp_limits[2],
467 system_edp_limits[3]);
468 }
469
470 return 0;
471}
472
473
474static int edp_debugfs_open(struct inode *inode, struct file *file)
475{
476 return single_open(file, edp_debugfs_show, inode->i_private);
477}
478
479static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
480{
481 return single_open(file, edp_limit_debugfs_show, inode->i_private);
482}
483
484
485static const struct file_operations edp_debugfs_fops = {
486 .open = edp_debugfs_open,
487 .read = seq_read,
488 .llseek = seq_lseek,
489 .release = single_release,
490};
491
492static const struct file_operations edp_limit_debugfs_fops = {
493 .open = edp_limit_debugfs_open,
494 .read = seq_read,
495 .llseek = seq_lseek,
496 .release = single_release,
497};
498
499static int __init tegra_edp_debugfs_init(void)
500{
501 struct dentry *d;
502
503 d = debugfs_create_file("edp", S_IRUGO, NULL, NULL,
504 &edp_debugfs_fops);
505 if (!d)
506 return -ENOMEM;
507
508 d = debugfs_create_file("edp_limit", S_IRUGO, NULL, NULL,
509 &edp_limit_debugfs_fops);
510
511 return 0;
512}
513
514late_initcall(tegra_edp_debugfs_init);
515#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-tegra/eeprom-wifi-mac.c b/arch/arm/mach-tegra/eeprom-wifi-mac.c
new file mode 100644
index 00000000000..fb35c090906
--- /dev/null
+++ b/arch/arm/mach-tegra/eeprom-wifi-mac.c
@@ -0,0 +1,65 @@
1#include <linux/i2c/at24.h>
2#include <linux/sysfs.h>
3#include <linux/device.h>
4#include <linux/slab.h>
5
6#define EEPROM_LEN 32
7
8static char wifi_mac[] = "ff:ff:ff:ff:ff:ff";
9
10static ssize_t show_addr_sysfs(struct device *dev,
11 struct device_attribute *attr, char *buf)
12{
13 return sprintf(buf, "%s\n", wifi_mac);
14}
15
16DEVICE_ATTR(addr, 0444, show_addr_sysfs, NULL);
17
18static struct attribute *wifi_mac_addr_attributes[] = {
19 &dev_attr_addr.attr,
20 NULL
21};
22
23static const struct attribute_group wifi_mac_addr_group = {
24 .attrs = wifi_mac_addr_attributes,
25};
26
27int create_sys_fs(void)
28{
29 int ret = -1;
30 static struct kobject *reg_kobj;
31 reg_kobj = kobject_create_and_add("wifi_mac_addr", kernel_kobj);
32 if (!reg_kobj)
33 return -ENOMEM;
34
35 ret = sysfs_create_group(reg_kobj, &wifi_mac_addr_group);
36 if (ret < 0) {
37 kobject_put(reg_kobj);
38 return ret;
39 }
40 return ret;
41}
42
43void get_mac_addr(struct memory_accessor *mem_acc, void *context)
44{
45 char *mac_addr;
46 int ret = 0;
47 off_t offset = (off_t)context;
48 mac_addr = kzalloc(sizeof(char)*EEPROM_LEN, GFP_ATOMIC);
49 if (!mac_addr) {
50 pr_err("no memory to allocate");
51 return;
52 }
53
54 /* Read MAC addr from EEPROM */
55 ret = mem_acc->read(mem_acc, mac_addr, offset, EEPROM_LEN);
56 if (ret == EEPROM_LEN) {
57 pr_err("Read MAC addr from EEPROM: %pM\n", (mac_addr+19));
58 sprintf(wifi_mac, "%02x:%02x:%02x:%02x:%02x:%02x",
59 *(mac_addr+19), *(mac_addr+20), *(mac_addr+21),
60 *(mac_addr+22), *(mac_addr+23), *(mac_addr+24));
61 } else
62 pr_err("Error reading MAC addr from EEPROM\n");
63
64 create_sys_fs();
65}
diff --git a/arch/arm/mach-tegra/fiq.c b/arch/arm/mach-tegra/fiq.c
new file mode 100644
index 00000000000..19f9c059d10
--- /dev/null
+++ b/arch/arm/mach-tegra/fiq.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 *
4 * Author:
5 * Brian Swetland <swetland@google.com>
6 * Iliyan Malchev <malchev@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/init.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/io.h>
24#include <linux/slab.h>
25
26#include <asm/hardware/gic.h>
27
28#include <mach/iomap.h>
29#include <mach/fiq.h>
30
31#include "board.h"
32
33#define ICTLR_CPU_IER 0x20
34#define ICTLR_CPU_IER_SET 0x24
35#define ICTLR_CPU_IER_CLR 0x28
36#define ICTLR_CPU_IEP_CLASS 0x2C
37
38#define FIRST_LEGACY_IRQ 32
39
40static void __iomem *ictlr_reg_base[] = {
41 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
42 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
43 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
44 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
45};
46
47static void tegra_legacy_select_fiq(unsigned int irq, bool fiq)
48{
49 void __iomem *base;
50 pr_debug("%s: %d\n", __func__, irq);
51
52 irq -= FIRST_LEGACY_IRQ;
53 base = ictlr_reg_base[irq>>5];
54 writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS);
55}
56
57static void tegra_fiq_mask(struct irq_data *d)
58{
59 void __iomem *base;
60 int leg_irq;
61
62 if (d->irq < FIRST_LEGACY_IRQ)
63 return;
64
65 leg_irq = d->irq - FIRST_LEGACY_IRQ;
66 base = ictlr_reg_base[leg_irq >> 5];
67 writel(1 << (leg_irq & 31), base + ICTLR_CPU_IER_CLR);
68}
69
70static void tegra_fiq_unmask(struct irq_data *d)
71{
72 void __iomem *base;
73 int leg_irq;
74
75 if (d->irq < FIRST_LEGACY_IRQ)
76 return;
77
78 leg_irq = d->irq - FIRST_LEGACY_IRQ;
79 base = ictlr_reg_base[leg_irq >> 5];
80 writel(1 << (leg_irq & 31), base + ICTLR_CPU_IER_SET);
81}
82
83void tegra_fiq_enable(int irq)
84{
85 void __iomem *base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100);
86 /* enable FIQ */
87 u32 val = readl(base + GIC_CPU_CTRL);
88 val &= ~8; /* pass FIQs through */
89 val |= 2; /* enableNS */
90 writel(val, base + GIC_CPU_CTRL);
91 tegra_legacy_select_fiq(irq, true);
92 tegra_fiq_unmask(irq_get_irq_data(irq));
93}
94
95void tegra_fiq_disable(int irq)
96{
97 tegra_fiq_mask(irq_get_irq_data(irq));
98 tegra_legacy_select_fiq(irq, false);
99}
diff --git a/arch/arm/mach-tegra/gic.c b/arch/arm/mach-tegra/gic.c
new file mode 100644
index 00000000000..6c2dc940675
--- /dev/null
+++ b/arch/arm/mach-tegra/gic.c
@@ -0,0 +1,135 @@
1/*
2 * Copyright (C) 2010-2012, NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/cpumask.h> /* Required by asm/hardware/gic.h */
17#include <linux/io.h>
18#include <linux/irqnr.h>
19
20#include <asm/hardware/gic.h>
21
22#include <mach/iomap.h>
23#include <mach/irqs.h>
24
25#include "gic.h"
26#include "pm.h"
27
28#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
29static void __iomem *gic_cpu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100);
30
31void tegra_gic_cpu_disable(void)
32{
33 writel(0, gic_cpu_base + GIC_CPU_CTRL);
34}
35
36void tegra_gic_cpu_enable(void)
37{
38 writel(1, gic_cpu_base + GIC_CPU_CTRL);
39}
40
41#ifndef CONFIG_ARCH_TEGRA_2x_SOC
42
43void tegra_gic_pass_through_disable(void)
44{
45 u32 val = readl(gic_cpu_base + GIC_CPU_CTRL);
46 val |= 2; /* enableNS = disable GIC pass through */
47 writel(val, gic_cpu_base + GIC_CPU_CTRL);
48}
49
50#endif
51#endif
52
53#if defined(CONFIG_PM_SLEEP)
54
55int tegra_gic_pending_interrupt(void)
56{
57 u32 irq = readl(gic_cpu_base + GIC_CPU_HIGHPRI);
58 irq &= 0x3FF;
59
60 return irq;
61}
62
63#ifndef CONFIG_ARCH_TEGRA_2x_SOC
64
65static void __iomem *gic_dist_base = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
66static u32 gic_affinity[INT_GIC_NR/4];
67
68void tegra_gic_dist_disable(void)
69{
70 writel(0, gic_dist_base + GIC_DIST_CTRL);
71}
72
73void tegra_gic_dist_enable(void)
74{
75 writel(1, gic_dist_base + GIC_DIST_CTRL);
76}
77
78void tegra_gic_disable_affinity(void)
79{
80 unsigned int i;
81
82 BUG_ON(is_lp_cluster());
83
84 /* The GIC distributor TARGET register is one byte per IRQ. */
85 for (i = 32; i < INT_GIC_NR; i += 4) {
86 /* Save the affinity. */
87 gic_affinity[i/4] = __raw_readl(gic_dist_base +
88 GIC_DIST_TARGET + i);
89
90 /* Force this interrupt to CPU0. */
91 __raw_writel(0x01010101, gic_dist_base + GIC_DIST_TARGET + i);
92 }
93
94 wmb();
95}
96
97void tegra_gic_restore_affinity(void)
98{
99 unsigned int i;
100
101 BUG_ON(is_lp_cluster());
102
103 /* The GIC distributor TARGET register is one byte per IRQ. */
104 for (i = 32; i < INT_GIC_NR; i += 4) {
105#ifdef CONFIG_BUG
106 u32 reg = __raw_readl(gic_dist_base + GIC_DIST_TARGET + i);
107 if (reg & 0xFEFEFEFE)
108 panic("GIC affinity changed!");
109#endif
110 /* Restore this interrupt's affinity. */
111 __raw_writel(gic_affinity[i/4], gic_dist_base +
112 GIC_DIST_TARGET + i);
113 }
114
115 wmb();
116}
117
118void tegra_gic_affinity_to_cpu0(void)
119{
120 unsigned int i;
121
122 BUG_ON(is_lp_cluster());
123
124 for (i = 32; i < INT_GIC_NR; i += 4)
125 __raw_writel(0x01010101, gic_dist_base + GIC_DIST_TARGET + i);
126 wmb();
127}
128#endif
129#endif
130
131void __init tegra_gic_init(void)
132{
133 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
134 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
135}
diff --git a/arch/arm/mach-tegra/gic.h b/arch/arm/mach-tegra/gic.h
new file mode 100644
index 00000000000..22bb85f1852
--- /dev/null
+++ b/arch/arm/mach-tegra/gic.h
@@ -0,0 +1,51 @@
1/*
2 * arch/arm/mach-tegra/include/mach/gic.h
3 *
4 * Copyright (C) 2010-2012 NVIDIA Corporation
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_GIC_H_
18#define _MACH_TEGRA_GIC_H_
19
20#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
21
22void tegra_gic_cpu_disable(void);
23void tegra_gic_cpu_enable(void);
24
25#ifndef CONFIG_ARCH_TEGRA_2x_SOC
26
27void tegra_gic_pass_through_disable(void);
28
29#endif
30#endif
31
32
33#if defined(CONFIG_PM_SLEEP)
34
35int tegra_gic_pending_interrupt(void);
36
37#ifndef CONFIG_ARCH_TEGRA_2x_SOC
38
39void tegra_gic_dist_disable(void);
40void tegra_gic_dist_enable(void);
41
42void tegra_gic_disable_affinity(void);
43void tegra_gic_restore_affinity(void);
44void tegra_gic_affinity_to_cpu0(void);
45
46#endif
47#endif
48
49void __init tegra_gic_init(void);
50
51#endif /* _MACH_TEGRA_GIC_H_ */
diff --git a/arch/arm/mach-tegra/i2c_error_recovery.c b/arch/arm/mach-tegra/i2c_error_recovery.c
new file mode 100644
index 00000000000..a3ac4e122a8
--- /dev/null
+++ b/arch/arm/mach-tegra/i2c_error_recovery.c
@@ -0,0 +1,103 @@
1/*
2 * arch/arm/mach-tegra/i2c_error_recovery.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include <linux/gpio.h>
21#include <linux/delay.h>
22#include <linux/init.h>
23
24#include "board.h"
25
26#define RETRY_MAX_COUNT (9*8+1) /*I2C controller supports eight-byte burst transfer*/
27
28int arb_lost_recovery(int scl_gpio, int sda_gpio)
29{
30 int ret;
31 int retry = RETRY_MAX_COUNT;
32 int recovered_successfully = 0;
33 int val;
34
35 if ((!scl_gpio) || (!sda_gpio)) {
36 pr_err("not proper input:scl_gpio 0x%08x,"
37 "sda_gpio 0x%08x\n", scl_gpio, sda_gpio);
38 return -EINVAL;;
39 }
40
41 ret = gpio_request(scl_gpio, "scl_gpio");
42 if (ret < 0) {
43 pr_err("error in gpio 0x%08x request 0x%08x\n",
44 scl_gpio, ret);
45 return -EINVAL;;
46 }
47 tegra_gpio_enable(scl_gpio);
48
49 ret = gpio_request(sda_gpio, "sda_gpio");
50 if (ret < 0) {
51 pr_err("error in gpio 0x%08x request 0x%08x\n",
52 sda_gpio, ret);
53 goto err;
54 }
55 tegra_gpio_enable(sda_gpio);
56 gpio_direction_input(sda_gpio);
57
58 while (retry--) {
59 gpio_direction_output(scl_gpio,0);
60 udelay(5);
61 gpio_direction_output(scl_gpio,1);
62 udelay(5);
63
64 /* check whether sda struct low release */
65 val = gpio_get_value(sda_gpio);
66 if (val) {
67 /* send START */
68 gpio_direction_output(sda_gpio,0);
69 udelay(5);
70
71 /* send STOP in next clock cycle */
72 gpio_direction_output(scl_gpio,0);
73 udelay(5);
74 gpio_direction_output(scl_gpio,1);
75 udelay(5);
76 gpio_direction_output(sda_gpio,1);
77 udelay(5);
78
79 recovered_successfully = 1;
80 break;
81 }
82 }
83
84 gpio_free(scl_gpio);
85 tegra_gpio_disable(scl_gpio);
86 gpio_free(sda_gpio);
87 tegra_gpio_disable(sda_gpio);
88
89 if (likely(recovered_successfully)) {
90 pr_err("arbitration lost recovered by re-try-count 0x%08x\n",
91 RETRY_MAX_COUNT - retry);
92 return 0;
93 } else {
94 pr_err("Un-recovered arbitration lost.\n");
95 return -EINVAL;
96 }
97
98err:
99 gpio_free(scl_gpio);
100 tegra_gpio_disable(scl_gpio);
101 return ret;
102}
103
diff --git a/arch/arm/mach-tegra/include/mach/arb_sema.h b/arch/arm/mach-tegra/include/mach/arb_sema.h
new file mode 100644
index 00000000000..9283f079cf6
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/arb_sema.h
@@ -0,0 +1,35 @@
1/*
2 * arch/arm/mach-tegra/include/mach/arb_sema.h
3 *
4 * Hardware arbitration semaphore interface
5 *
6 * Copyright (c) 2010, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef __MACH_TEGRA_ARB_SEMA_H
24#define __MACH_TEGRA_ARB_SEMA_H
25
26enum tegra_arb_module {
27 TEGRA_ARB_BSEV = 0,
28 TEGRA_ARB_BSEA,
29};
30
31int tegra_arb_mutex_lock_timeout(enum tegra_arb_module lock, int msecs);
32
33int tegra_arb_mutex_unlock(enum tegra_arb_module lock);
34
35#endif
diff --git a/arch/arm/mach-tegra/include/mach/audio.h b/arch/arm/mach-tegra/include/mach/audio.h
new file mode 100644
index 00000000000..5950ececae0
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/audio.h
@@ -0,0 +1,57 @@
1/*
2 * arch/arm/mach-tegra/include/mach/audio.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Iliyan Malchev <malchev@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 __ARCH_ARM_MACH_TEGRA_AUDIO_H
21#define __ARCH_ARM_MACH_TEGRA_AUDIO_H
22
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <mach/i2s.h>
26
27#define FIFO1 0
28#define FIFO2 1
29
30/* FIXME: this is not enforced by the hardware. */
31#define I2S_FIFO_TX FIFO1
32#define I2S_FIFO_RX FIFO2
33
34#define TEGRA_AUDIO_ENABLE_TX 1
35#define TEGRA_AUDIO_ENABLE_RX 2
36
37struct tegra_audio_platform_data {
38 bool i2s_master;
39 bool dsp_master;
40 int i2s_master_clk; /* When I2S mode and master, the framesync rate. */
41 int dsp_master_clk; /* When DSP mode and master, the framesync rate. */
42 bool dma_on;
43 unsigned long i2s_clk_rate;
44 const char *dap_clk;
45 const char *audio_sync_clk;
46
47 int mode; /* I2S, LJM, RJM, etc. */
48 int fifo_fmt;
49 int bit_size;
50 int i2s_bus_width; /* 32-bit for 16-bit packed I2S */
51 int dsp_bus_width; /* 16-bit for DSP data format */
52 int mask; /* enable tx and rx? */
53 bool stereo_capture; /* True if hardware supports stereo */
54 void *driver_data;
55};
56
57#endif /* __ARCH_ARM_MACH_TEGRA_AUDIO_H */
diff --git a/arch/arm/mach-tegra/include/mach/csi.h b/arch/arm/mach-tegra/include/mach/csi.h
new file mode 100644
index 00000000000..575de6fb497
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/csi.h
@@ -0,0 +1,40 @@
1/*
2 * arch/arm/mach-tegra/include/mach/csi.h
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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_CSI_H
18#define __MACH_TEGRA_CSI_H
19
20#define CSI_CILA_MIPI_CAL_CONFIG_0 0x22a
21#define MIPI_CAL_TERMOSA(x) (((x) & 0x1f) << 0)
22
23#define CSI_CILB_MIPI_CAL_CONFIG_0 0x22b
24#define MIPI_CAL_TERMOSB(x) (((x) & 0x1f) << 0)
25
26#define CSI_CIL_PAD_CONFIG 0x229
27#define PAD_CIL_PDVREG(x) (((x) & 0x01) << 1)
28
29#define CSI_DSI_MIPI_CAL_CONFIG 0x234
30#define MIPI_CAL_HSPDOSD(x) (((x) & 0x1f) << 16)
31#define MIPI_CAL_HSPUOSD(x) (((x) & 0x1f) << 8)
32
33#define CSI_MIPIBIAS_PAD_CONFIG 0x235
34#define PAD_DRIV_DN_REF(x) (((x) & 0x7) << 16)
35#define PAD_DRIV_UP_REF(x) (((x) & 0x7) << 8)
36
37int tegra_vi_csi_readl(u32 offset, u32 *val);
38int tegra_vi_csi_writel(u32 value, u32 offset);
39
40#endif
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
new file mode 100644
index 00000000000..a5f7210f2b2
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -0,0 +1,570 @@
1/*
2 * arch/arm/mach-tegra/include/mach/dc.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 *
9 * Copyright (C) 2010-2011 NVIDIA Corporation
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#ifndef __MACH_TEGRA_DC_H
23#define __MACH_TEGRA_DC_H
24
25#include <linux/pm.h>
26#include <linux/types.h>
27#include <drm/drm_fixed.h>
28
29#define TEGRA_MAX_DC 2
30#define DC_N_WINDOWS 3
31
32
33/* DSI pixel data format */
34enum {
35 TEGRA_DSI_PIXEL_FORMAT_16BIT_P,
36 TEGRA_DSI_PIXEL_FORMAT_18BIT_P,
37 TEGRA_DSI_PIXEL_FORMAT_18BIT_NP,
38 TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
39};
40
41/* DSI virtual channel number */
42enum {
43 TEGRA_DSI_VIRTUAL_CHANNEL_0,
44 TEGRA_DSI_VIRTUAL_CHANNEL_1,
45 TEGRA_DSI_VIRTUAL_CHANNEL_2,
46 TEGRA_DSI_VIRTUAL_CHANNEL_3,
47};
48
49/* DSI transmit method for video data */
50enum {
51 TEGRA_DSI_VIDEO_TYPE_VIDEO_MODE,
52 TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
53};
54
55/* DSI HS clock mode */
56enum {
57 TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS,
58 TEGRA_DSI_VIDEO_CLOCK_TX_ONLY,
59};
60
61/* DSI burst mode setting in video mode. Each mode is assigned with a
62 * fixed value. The rationale behind this is to avoid change of these
63 * values, since the calculation of dsi clock depends on them. */
64enum {
65 TEGRA_DSI_VIDEO_NONE_BURST_MODE = 0,
66 TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END = 1,
67 TEGRA_DSI_VIDEO_BURST_MODE_LOWEST_SPEED = 2,
68 TEGRA_DSI_VIDEO_BURST_MODE_LOW_SPEED = 3,
69 TEGRA_DSI_VIDEO_BURST_MODE_MEDIUM_SPEED = 4,
70 TEGRA_DSI_VIDEO_BURST_MODE_FAST_SPEED = 5,
71 TEGRA_DSI_VIDEO_BURST_MODE_FASTEST_SPEED = 6,
72};
73
74enum {
75 TEGRA_DSI_PACKET_CMD,
76 TEGRA_DSI_DELAY_MS,
77};
78
79struct tegra_dsi_cmd {
80 u8 cmd_type;
81 u8 data_id;
82 union {
83 u16 data_len;
84 u16 delay_ms;
85 struct {
86 u8 data0;
87 u8 data1;
88 } sp;
89 } sp_len_dly;
90 u8 *pdata;
91};
92
93#define DSI_CMD_SHORT(di, p0, p1) { \
94 .cmd_type = TEGRA_DSI_PACKET_CMD, \
95 .data_id = di, \
96 .sp_len_dly.sp.data0 = p0, \
97 .sp_len_dly.sp.data1 = p1, \
98 }
99#define DSI_DLY_MS(ms) { \
100 .cmd_type = TEGRA_DSI_DELAY_MS, \
101 .sp_len_dly.delay_ms = ms, \
102 }
103
104#define DSI_CMD_LONG(di, ptr) { \
105 .cmd_type = TEGRA_DSI_PACKET_CMD, \
106 .data_id = di, \
107 .sp_len_dly.data_len = ARRAY_SIZE(ptr), \
108 .pdata = ptr, \
109 }
110
111struct dsi_phy_timing_ns {
112 u16 t_hsdexit_ns;
113 u16 t_hstrail_ns;
114 u16 t_datzero_ns;
115 u16 t_hsprepare_ns;
116
117 u16 t_clktrail_ns;
118 u16 t_clkpost_ns;
119 u16 t_clkzero_ns;
120 u16 t_tlpx_ns;
121
122 u16 t_clkprepare_ns;
123 u16 t_clkpre_ns;
124 u16 t_wakeup_ns;
125
126 u16 t_taget_ns;
127 u16 t_tasure_ns;
128 u16 t_tago_ns;
129};
130
131struct tegra_dsi_out {
132 u8 n_data_lanes; /* required */
133 u8 pixel_format; /* required */
134 u8 refresh_rate; /* required */
135 u8 rated_refresh_rate;
136 u8 panel_reset; /* required */
137 u8 virtual_channel; /* required */
138 u8 dsi_instance;
139 u8 chip_id;
140 u8 chip_rev;
141
142 bool panel_has_frame_buffer; /* required*/
143
144 struct tegra_dsi_cmd *dsi_init_cmd; /* required */
145 u16 n_init_cmd; /* required */
146
147 struct tegra_dsi_cmd *dsi_early_suspend_cmd;
148 u16 n_early_suspend_cmd;
149
150 struct tegra_dsi_cmd *dsi_late_resume_cmd;
151 u16 n_late_resume_cmd;
152
153 struct tegra_dsi_cmd *dsi_suspend_cmd; /* required */
154 u16 n_suspend_cmd; /* required */
155
156 u8 video_data_type; /* required */
157 u8 video_clock_mode;
158 u8 video_burst_mode;
159
160 u16 panel_buffer_size_byte;
161 u16 panel_reset_timeout_msec;
162
163 bool hs_cmd_mode_supported;
164 bool hs_cmd_mode_on_blank_supported;
165 bool enable_hs_clock_on_lp_cmd_mode;
166 bool no_pkt_seq_eot; /* 1st generation panel may not
167 * support eot. Don't set it for
168 * most panels. */
169 bool te_polarity_low;
170 bool power_saving_suspend;
171
172 u32 max_panel_freq_khz;
173 u32 lp_cmd_mode_freq_khz;
174 u32 lp_read_cmd_mode_freq_khz;
175 u32 hs_clk_in_lp_cmd_mode_freq_khz;
176 u32 burst_mode_freq_khz;
177
178 struct dsi_phy_timing_ns phy_timing;
179};
180
181enum {
182 TEGRA_DC_STEREO_MODE_2D,
183 TEGRA_DC_STEREO_MODE_3D
184};
185
186enum {
187 TEGRA_DC_STEREO_LANDSCAPE,
188 TEGRA_DC_STEREO_PORTRAIT
189};
190
191struct tegra_stereo_out {
192 int mode_2d_3d;
193 int orientation;
194
195 void (*set_mode)(int mode);
196 void (*set_orientation)(int orientation);
197};
198
199struct tegra_dc_mode {
200 int pclk;
201 int rated_pclk;
202 int h_ref_to_sync;
203 int v_ref_to_sync;
204 int h_sync_width;
205 int v_sync_width;
206 int h_back_porch;
207 int v_back_porch;
208 int h_active;
209 int v_active;
210 int h_front_porch;
211 int v_front_porch;
212 int stereo_mode;
213 u32 flags;
214};
215
216#define TEGRA_DC_MODE_FLAG_NEG_V_SYNC (1 << 0)
217#define TEGRA_DC_MODE_FLAG_NEG_H_SYNC (1 << 1)
218
219enum {
220 TEGRA_DC_OUT_RGB,
221 TEGRA_DC_OUT_HDMI,
222 TEGRA_DC_OUT_DSI,
223};
224
225struct tegra_dc_out_pin {
226 int name;
227 int pol;
228};
229
230enum {
231 TEGRA_DC_OUT_PIN_DATA_ENABLE,
232 TEGRA_DC_OUT_PIN_H_SYNC,
233 TEGRA_DC_OUT_PIN_V_SYNC,
234 TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
235};
236
237enum {
238 TEGRA_DC_OUT_PIN_POL_LOW,
239 TEGRA_DC_OUT_PIN_POL_HIGH,
240};
241
242enum {
243 TEGRA_DC_DISABLE_DITHER = 1,
244 TEGRA_DC_ORDERED_DITHER,
245 TEGRA_DC_ERRDIFF_DITHER,
246};
247
248typedef u8 tegra_dc_bl_output[256];
249typedef u8 *p_tegra_dc_bl_output;
250
251struct tegra_dc_sd_blp {
252 u16 time_constant;
253 u8 step;
254};
255
256struct tegra_dc_sd_fc {
257 u8 time_limit;
258 u8 threshold;
259};
260
261struct tegra_dc_sd_rgb {
262 u8 r;
263 u8 g;
264 u8 b;
265};
266
267struct tegra_dc_sd_agg_priorities {
268 u8 pri_lvl;
269 u8 agg[4];
270};
271
272struct tegra_dc_sd_settings {
273 unsigned enable;
274 bool use_auto_pwm;
275 u8 hw_update_delay;
276 u8 aggressiveness;
277 short bin_width;
278 u8 phase_in_settings;
279 u8 phase_in_adjustments;
280 u8 cmd;
281 u8 final_agg;
282 u16 cur_agg_step;
283 u16 phase_settings_step;
284 u16 phase_adj_step;
285 u16 num_phase_in_steps;
286
287 struct tegra_dc_sd_agg_priorities agg_priorities;
288
289 bool use_vid_luma;
290 struct tegra_dc_sd_rgb coeff;
291
292 struct tegra_dc_sd_fc fc;
293 struct tegra_dc_sd_blp blp;
294 u8 bltf[4][4][4];
295 struct tegra_dc_sd_rgb lut[4][9];
296
297 atomic_t *sd_brightness;
298 struct platform_device *bl_device;
299};
300
301enum {
302 NO_CMD = 0x0,
303 ENABLE = 0x1,
304 DISABLE = 0x2,
305 PHASE_IN = 0x4,
306 AGG_CHG = 0x8,
307};
308
309enum {
310 TEGRA_PIN_OUT_CONFIG_SEL_LHP0_LD21,
311 TEGRA_PIN_OUT_CONFIG_SEL_LHP1_LD18,
312 TEGRA_PIN_OUT_CONFIG_SEL_LHP2_LD19,
313 TEGRA_PIN_OUT_CONFIG_SEL_LVP0_LVP0_Out,
314 TEGRA_PIN_OUT_CONFIG_SEL_LVP1_LD20,
315
316 TEGRA_PIN_OUT_CONFIG_SEL_LM1_M1,
317 TEGRA_PIN_OUT_CONFIG_SEL_LM1_LD21,
318 TEGRA_PIN_OUT_CONFIG_SEL_LM1_PM1,
319
320 TEGRA_PIN_OUT_CONFIG_SEL_LDI_LD22,
321 TEGRA_PIN_OUT_CONFIG_SEL_LPP_LD23,
322 TEGRA_PIN_OUT_CONFIG_SEL_LDC_SDC,
323 TEGRA_PIN_OUT_CONFIG_SEL_LSPI_DE,
324};
325
326struct tegra_dc_out {
327 int type;
328 unsigned flags;
329
330 /* size in mm */
331 unsigned h_size;
332 unsigned v_size;
333
334 int dcc_bus;
335 int hotplug_gpio;
336 const char *parent_clk;
337 const char *parent_clk_backup;
338
339 unsigned max_pixclock;
340 unsigned order;
341 unsigned align;
342 unsigned depth;
343 unsigned dither;
344
345 struct tegra_dc_mode *modes;
346 int n_modes;
347
348 struct tegra_dsi_out *dsi;
349 struct tegra_stereo_out *stereo;
350
351 unsigned height; /* mm */
352 unsigned width; /* mm */
353
354 struct tegra_dc_out_pin *out_pins;
355 unsigned n_out_pins;
356
357 struct tegra_dc_sd_settings *sd_settings;
358
359 u8 *out_sel_configs;
360 unsigned n_out_sel_configs;
361
362 int (*enable)(void);
363 int (*postpoweron)(void);
364 int (*disable)(void);
365
366 int (*hotplug_init)(void);
367 int (*postsuspend)(void);
368};
369
370/* bits for tegra_dc_out.flags */
371#define TEGRA_DC_OUT_HOTPLUG_HIGH (0 << 1)
372#define TEGRA_DC_OUT_HOTPLUG_LOW (1 << 1)
373#define TEGRA_DC_OUT_HOTPLUG_MASK (1 << 1)
374#define TEGRA_DC_OUT_NVHDCP_POLICY_ALWAYS_ON (0 << 2)
375#define TEGRA_DC_OUT_NVHDCP_POLICY_ON_DEMAND (1 << 2)
376#define TEGRA_DC_OUT_NVHDCP_POLICY_MASK (1 << 2)
377#define TEGRA_DC_OUT_CONTINUOUS_MODE (0 << 3)
378#define TEGRA_DC_OUT_ONE_SHOT_MODE (1 << 3)
379#define TEGRA_DC_OUT_N_SHOT_MODE (1 << 4)
380
381#define TEGRA_DC_ALIGN_MSB 0
382#define TEGRA_DC_ALIGN_LSB 1
383
384#define TEGRA_DC_ORDER_RED_BLUE 0
385#define TEGRA_DC_ORDER_BLUE_RED 1
386
387struct tegra_dc;
388struct nvmap_handle_ref;
389
390struct tegra_dc_csc {
391 unsigned short yof;
392 unsigned short kyrgb;
393 unsigned short kur;
394 unsigned short kvr;
395 unsigned short kug;
396 unsigned short kvg;
397 unsigned short kub;
398 unsigned short kvb;
399};
400
401/* palette lookup table */
402struct tegra_dc_lut {
403 u8 r[256];
404 u8 g[256];
405 u8 b[256];
406};
407
408struct tegra_dc_win {
409 u8 idx;
410 u8 fmt;
411 u8 ppflags; /* see TEGRA_WIN_PPFLAG* */
412 u32 flags;
413
414 void *virt_addr;
415 dma_addr_t phys_addr;
416 dma_addr_t phys_addr_u;
417 dma_addr_t phys_addr_v;
418 unsigned stride;
419 unsigned stride_uv;
420 fixed20_12 x;
421 fixed20_12 y;
422 fixed20_12 w;
423 fixed20_12 h;
424 unsigned out_x;
425 unsigned out_y;
426 unsigned out_w;
427 unsigned out_h;
428 unsigned z;
429
430 struct tegra_dc_csc csc;
431
432 int dirty;
433 int underflows;
434 struct tegra_dc *dc;
435
436 struct nvmap_handle_ref *cur_handle;
437 unsigned bandwidth;
438 unsigned new_bandwidth;
439 struct tegra_dc_lut lut;
440};
441
442#define TEGRA_WIN_PPFLAG_CP_ENABLE (1 << 0) /* enable RGB color lut */
443#define TEGRA_WIN_PPFLAG_CP_FBOVERRIDE (1 << 1) /* override fbdev color lut */
444
445#define TEGRA_WIN_FLAG_ENABLED (1 << 0)
446#define TEGRA_WIN_FLAG_BLEND_PREMULT (1 << 1)
447#define TEGRA_WIN_FLAG_BLEND_COVERAGE (1 << 2)
448#define TEGRA_WIN_FLAG_INVERT_H (1 << 3)
449#define TEGRA_WIN_FLAG_INVERT_V (1 << 4)
450#define TEGRA_WIN_FLAG_TILED (1 << 5)
451#define TEGRA_WIN_FLAG_H_FILTER (1 << 6)
452#define TEGRA_WIN_FLAG_V_FILTER (1 << 7)
453
454
455#define TEGRA_WIN_BLEND_FLAGS_MASK \
456 (TEGRA_WIN_FLAG_BLEND_PREMULT | TEGRA_WIN_FLAG_BLEND_COVERAGE)
457
458/* Note: These are the actual values written to the DC_WIN_COLOR_DEPTH register
459 * and may change in new tegra architectures.
460 */
461#define TEGRA_WIN_FMT_P1 0
462#define TEGRA_WIN_FMT_P2 1
463#define TEGRA_WIN_FMT_P4 2
464#define TEGRA_WIN_FMT_P8 3
465#define TEGRA_WIN_FMT_B4G4R4A4 4
466#define TEGRA_WIN_FMT_B5G5R5A 5
467#define TEGRA_WIN_FMT_B5G6R5 6
468#define TEGRA_WIN_FMT_AB5G5R5 7
469#define TEGRA_WIN_FMT_B8G8R8A8 12
470#define TEGRA_WIN_FMT_R8G8B8A8 13
471#define TEGRA_WIN_FMT_B6x2G6x2R6x2A8 14
472#define TEGRA_WIN_FMT_R6x2G6x2B6x2A8 15
473#define TEGRA_WIN_FMT_YCbCr422 16
474#define TEGRA_WIN_FMT_YUV422 17
475#define TEGRA_WIN_FMT_YCbCr420P 18
476#define TEGRA_WIN_FMT_YUV420P 19
477#define TEGRA_WIN_FMT_YCbCr422P 20
478#define TEGRA_WIN_FMT_YUV422P 21
479#define TEGRA_WIN_FMT_YCbCr422R 22
480#define TEGRA_WIN_FMT_YUV422R 23
481#define TEGRA_WIN_FMT_YCbCr422RA 24
482#define TEGRA_WIN_FMT_YUV422RA 25
483
484struct tegra_fb_data {
485 int win;
486
487 int xres;
488 int yres;
489 int bits_per_pixel; /* -1 means autodetect */
490
491 unsigned long flags;
492};
493
494#define TEGRA_FB_FLIP_ON_PROBE (1 << 0)
495
496struct tegra_dc_platform_data {
497 unsigned long flags;
498 unsigned long emc_clk_rate;
499 struct tegra_dc_out *default_out;
500 struct tegra_fb_data *fb;
501};
502
503#define TEGRA_DC_FLAG_ENABLED (1 << 0)
504
505struct tegra_dc *tegra_dc_get_dc(unsigned idx);
506struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win);
507bool tegra_dc_get_connected(struct tegra_dc *);
508
509void tegra_dc_blank(struct tegra_dc *dc);
510
511void tegra_dc_enable(struct tegra_dc *dc);
512void tegra_dc_disable(struct tegra_dc *dc);
513
514u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc, int i);
515u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc, int i);
516void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, int i, u32 val);
517
518/* tegra_dc_update_windows and tegra_dc_sync_windows do not support windows
519 * with differenct dcs in one call
520 */
521int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n);
522int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n);
523
524int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode);
525struct fb_videomode;
526int tegra_dc_set_fb_mode(struct tegra_dc *dc, const struct fb_videomode *fbmode,
527 bool stereo_mode);
528
529unsigned tegra_dc_get_out_height(const struct tegra_dc *dc);
530unsigned tegra_dc_get_out_width(const struct tegra_dc *dc);
531unsigned tegra_dc_get_out_max_pixclock(const struct tegra_dc *dc);
532
533/* PM0 and PM1 signal control */
534#define TEGRA_PWM_PM0 0
535#define TEGRA_PWM_PM1 1
536
537struct tegra_dc_pwm_params {
538 int which_pwm;
539 void (*switch_to_sfio)(int);
540 int gpio_conf_to_sfio;
541 unsigned int period;
542 unsigned int clk_div;
543 unsigned int clk_select;
544 unsigned int duty_cycle;
545};
546
547void tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg);
548
549int tegra_dsi_send_panel_short_cmd(struct tegra_dc *dc, u8 *pdata, u8 data_len);
550void tegra_dc_host_trigger(struct tegra_dc *dc);
551
552int tegra_dc_update_csc(struct tegra_dc *dc, int win_index);
553
554int tegra_dc_update_lut(struct tegra_dc *dc, int win_index, int fboveride);
555
556/*
557 * In order to get a dc's current EDID, first call tegra_dc_get_edid() from an
558 * interruptible context. The returned value (if non-NULL) points to a
559 * snapshot of the current state; after copying data from it, call
560 * tegra_dc_put_edid() on that pointer. Do not dereference anything through
561 * that pointer after calling tegra_dc_put_edid().
562 */
563struct tegra_dc_edid {
564 size_t len;
565 u8 buf[0];
566};
567struct tegra_dc_edid *tegra_dc_get_edid(struct tegra_dc *dc);
568void tegra_dc_put_edid(struct tegra_dc_edid *edid);
569
570#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
new file mode 100644
index 00000000000..e0ebe65c165
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -0,0 +1,35 @@
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#include <mach/iomap.h>
23
24 .macro addruart, rp, rv
25 ldr \rp, =IO_APB_PHYS @ physical
26 ldr \rv, =IO_APB_VIRT @ virtual
27 orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
28 orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
29 orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
30 orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
31 .endm
32
33#define UART_SHIFT 2
34#include <asm/hardware/debug-8250.S>
35
diff --git a/arch/arm/mach-tegra/include/mach/delay.h b/arch/arm/mach-tegra/include/mach/delay.h
new file mode 100644
index 00000000000..2defb7b9b65
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/delay.h
@@ -0,0 +1,41 @@
1/*
2 * arch/arm/mach-tegra/include/mach/delay.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#ifndef __MACH_TEGRA_DELAY_H
20#define __MACH_TEGRA_DELAY_H
21
22/* needed by loops_per_jiffy calculations */
23extern void __delay(int loops);
24
25extern void __udelay(unsigned long usecs);
26extern void __const_udelay(unsigned long usecs);
27
28/* we don't have any restrictions on maximum udelay length, but we'll enforce
29 * the same restriction as the ARM default so we don't introduce any
30 * incompatibilties in drivers.
31 */
32extern void __bad_udelay(void);
33
34#define MAX_UDELAY_MS 2
35
36#define udelay(n) \
37 ((__builtin_constant_p(n) && (n) > (MAX_UDELAY_MS * 1000)) ? \
38 __bad_udelay() : \
39 __udelay(n))
40
41#endif /* defined(__MACH_TEGRA_DELAY_H) */
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
new file mode 100644
index 00000000000..0b0a5d9fd1d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -0,0 +1,202 @@
1/*
2 * arch/arm/mach-tegra/include/mach/dma.h
3 *
4 * Copyright (c) 2008-2010, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_TEGRA_DMA_H
22#define __MACH_TEGRA_DMA_H
23
24#include <linux/list.h>
25
26#if defined(CONFIG_TEGRA_SYSTEM_DMA)
27
28struct tegra_dma_req;
29struct tegra_dma_channel;
30
31#define TEGRA_DMA_REQ_SEL_CNTR 0
32#define TEGRA_DMA_REQ_SEL_I2S_2 1
33#define TEGRA_DMA_REQ_SEL_APBIF_CH0 TEGRA_DMA_REQ_SEL_I2S_2
34#define TEGRA_DMA_REQ_SEL_I2S_1 2
35#define TEGRA_DMA_REQ_SEL_APBIF_CH1 TEGRA_DMA_REQ_SEL_I2S_1
36#define TEGRA_DMA_REQ_SEL_SPD_I 3
37#define TEGRA_DMA_REQ_SEL_APBIF_CH2 TEGRA_DMA_REQ_SEL_SPD_I
38#define TEGRA_DMA_REQ_SEL_UI_I 4
39#define TEGRA_DMA_REQ_SEL_APBIF_CH3 TEGRA_DMA_REQ_SEL_UI_I
40#define TEGRA_DMA_REQ_SEL_MIPI 5
41#define TEGRA_DMA_REQ_SEL_I2S2_2 6
42#define TEGRA_DMA_REQ_SEL_I2S2_1 7
43#define TEGRA_DMA_REQ_SEL_UARTA 8
44#define TEGRA_DMA_REQ_SEL_UARTB 9
45#define TEGRA_DMA_REQ_SEL_UARTC 10
46#define TEGRA_DMA_REQ_SEL_SPI 11
47#define TEGRA_DMA_REQ_SEL_DTV TEGRA_DMA_REQ_SEL_SPI
48#define TEGRA_DMA_REQ_SEL_AC97 12
49#define TEGRA_DMA_REQ_SEL_ACMODEM 13
50#define TEGRA_DMA_REQ_SEL_SL4B 14
51#define TEGRA_DMA_REQ_SEL_SL2B1 15
52#define TEGRA_DMA_REQ_SEL_SL2B2 16
53#define TEGRA_DMA_REQ_SEL_SL2B3 17
54#define TEGRA_DMA_REQ_SEL_SL2B4 18
55#define TEGRA_DMA_REQ_SEL_UARTD 19
56#define TEGRA_DMA_REQ_SEL_UARTE 20
57#define TEGRA_DMA_REQ_SEL_I2C 21
58#define TEGRA_DMA_REQ_SEL_I2C2 22
59#define TEGRA_DMA_REQ_SEL_I2C3 23
60#define TEGRA_DMA_REQ_SEL_DVC_I2C 24
61#define TEGRA_DMA_REQ_SEL_OWR 25
62#define TEGRA_DMA_REQ_SEL_I2C4 26
63#define TEGRA_DMA_REQ_SEL_SL2B5 27
64#define TEGRA_DMA_REQ_SEL_SL2B6 28
65#define TEGRA_DMA_REQ_SEL_INVALID 31
66
67enum tegra_dma_mode {
68 TEGRA_DMA_SHARED = 1,
69 TEGRA_DMA_MODE_CONTINUOUS = 2,
70 TEGRA_DMA_MODE_CONTINUOUS_DOUBLE = TEGRA_DMA_MODE_CONTINUOUS,
71 TEGRA_DMA_MODE_CONTINUOUS_SINGLE = 4,
72 TEGRA_DMA_MODE_ONESHOT = 8,
73};
74
75/*
76 * tegra_dma_req_status: Dma request status
77 * TEGRA_DMA_REQ_SUCCESS: The request has been successfully completed.
78 * The byte_transferred tells number of bytes transferred.
79 * TEGRA_DMA_REQ_ERROR_ABORTED: The request is aborted by client after
80 * calling tegra_dma_dequeue_req.
81 * The byte_transferred tells number of bytes transferred
82 * which may be more than request size due to buffer
83 * wrap-up in continuous mode.
84 * TEGRA_DMA_REQ_ERROR_STOPPED: Applicable in continuous mode.
85 * The request is stopped forcefully. This may be becasue of
86 * - due to non-available of next request.
87 * - not able to serve current interrupt before next buffer
88 * completed by dma. This can happen if buffer req size is
89 * not enough and it transfer completes before system actually
90 * serve the previous dma interrupts.
91 * The byte_transferred will not be accurate in this case. It will
92 * just give an idea that how much approximately have been
93 * transferred by dma.
94 * TEGRA_DMA_REQ_INFLIGHT: The request is configured in the dma register
95 * for transfer.
96 */
97
98enum tegra_dma_req_status {
99 TEGRA_DMA_REQ_SUCCESS = 0,
100 TEGRA_DMA_REQ_ERROR_ABORTED,
101 TEGRA_DMA_REQ_ERROR_STOPPED,
102 TEGRA_DMA_REQ_INFLIGHT,
103};
104
105enum tegra_dma_req_buff_status {
106 TEGRA_DMA_REQ_BUF_STATUS_EMPTY = 0,
107 TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL,
108 TEGRA_DMA_REQ_BUF_STATUS_FULL,
109};
110
111typedef void (*dma_callback)(struct tegra_dma_req *req);
112
113struct tegra_dma_req {
114 struct list_head node;
115 unsigned int modid;
116 int instance;
117
118 /* Called when the req is complete and from the DMA ISR context.
119 * When this is called the req structure is no longer queued by
120 * the DMA channel.
121 *
122 * State of the DMA depends on the number of req it has. If there are
123 * no DMA requests queued up, then it will STOP the DMA. It there are
124 * more requests in the DMA, then it will queue the next request.
125 */
126 dma_callback complete;
127
128 /* This is a called from the DMA ISR context when the DMA is still in
129 * progress and is actively filling same buffer.
130 *
131 * In case of continuous mode receive, this threshold is 1/2 the buffer
132 * size. In other cases, this will not even be called as there is no
133 * hardware support for it.
134 *
135 * In the case of continuous mode receive, if there is next req already
136 * queued, DMA programs the HW to use that req when this req is
137 * completed. If there is no "next req" queued, then DMA ISR doesn't do
138 * anything before calling this callback.
139 *
140 * This is mainly used by the cases, where the clients has queued
141 * only one req and want to get some sort of DMA threshold
142 * callback to program the next buffer.
143 *
144 */
145 dma_callback threshold;
146
147 /* 1 to copy to memory.
148 * 0 to copy from the memory to device FIFO */
149 int to_memory;
150
151 void *virt_addr;
152
153 unsigned long source_addr;
154 unsigned long dest_addr;
155 unsigned long dest_wrap;
156 unsigned long source_wrap;
157 unsigned long source_bus_width;
158 unsigned long dest_bus_width;
159 unsigned long req_sel;
160 unsigned int size;
161
162 int fixed_burst_size; /* only for dtv */
163
164 /* Updated by the DMA driver on the conpletion of the request. */
165 int bytes_transferred;
166 int status;
167
168 /* DMA completion tracking information */
169 int buffer_status;
170
171 /* Client specific data */
172 void *dev;
173};
174
175int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
176 struct tegra_dma_req *req);
177int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
178 struct tegra_dma_req *req);
179void tegra_dma_flush(struct tegra_dma_channel *ch);
180
181bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
182 struct tegra_dma_req *req);
183int tegra_dma_get_transfer_count(struct tegra_dma_channel *ch,
184 struct tegra_dma_req *req);
185bool tegra_dma_is_empty(struct tegra_dma_channel *ch);
186
187struct tegra_dma_channel *tegra_dma_allocate_channel(int mode,
188 const char namefmt[], ...);
189void tegra_dma_free_channel(struct tegra_dma_channel *ch);
190int tegra_dma_cancel(struct tegra_dma_channel *ch);
191
192int __init tegra_dma_init(void);
193
194#else /* !defined(CONFIG_TEGRA_SYSTEM_DMA) */
195static inline int tegra_dma_init(void)
196{
197 return 0;
198}
199
200#endif
201
202#endif
diff --git a/arch/arm/mach-tegra/include/mach/edp.h b/arch/arm/mach-tegra/include/mach/edp.h
new file mode 100644
index 00000000000..48321cae495
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/edp.h
@@ -0,0 +1,80 @@
1/*
2 * arch/arm/mach-tegra/include/mach/edp.h
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_EDP_H
22#define __MACH_EDP_H
23
24#include <linux/debugfs.h>
25
26struct tegra_edp_entry {
27 char speedo_id;
28 char regulator_100mA;
29 char temperature;
30 char freq_limits[4];
31};
32
33struct tegra_edp_limits {
34 int temperature;
35 unsigned int freq_limits[4];
36};
37
38struct system_edp_entry {
39 char speedo_id;
40 char power_limit_100mW;
41 char freq_limits[4];
42};
43
44#ifdef CONFIG_TEGRA_EDP_LIMITS
45
46
47int tegra_edp_update_thermal_zone(int temperature);
48void tegra_init_cpu_edp_limits(unsigned int regulator_mA);
49void tegra_init_system_edp_limits(unsigned int power_limit_mW);
50void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size);
51unsigned int tegra_get_edp_limit(void);
52void tegra_get_system_edp_limits(const unsigned int **limits);
53int tegra_system_edp_alarm(bool alarm);
54
55#else
56static inline void tegra_init_cpu_edp_limits(int regulator_mA)
57{}
58static inline void tegra_init_system_edp_limits(int power_limit_mW)
59{}
60static inline int tegra_edp_update_thermal_zone(int temperature)
61{ return -1; }
62static inline void tegra_get_cpu_edp_limits(struct tegra_edp_limits **limits,
63 int *size)
64{}
65static inline unsigned int tegra_get_edp_limit(void)
66{ return -1; }
67static inline void tegra_get_system_edp_limits(unsigned int **limits)
68{}
69static inline int tegra_system_edp_alarm(bool alarm)
70{ return -1; }
71#endif
72
73#ifdef CONFIG_ARCH_TEGRA_2x_SOC
74static inline void tegra_edp_throttle_cpu_now(u8 factor)
75{}
76#else
77void tegra_edp_throttle_cpu_now(u8 factor);
78#endif
79
80#endif /* __MACH_EDP_H */
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
new file mode 100644
index 00000000000..50d1b212da2
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -0,0 +1,37 @@
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#define HAVE_GET_IRQNR_PREAMBLE
20#include <asm/hardware/entry-macro-gic.S>
21
22 /* Uses the GIC interrupt controller built into the cpu */
23#define ICTRL_BASE (IO_CPU_VIRT + 0x40100)
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#else
36#error "Unsupported configuration"
37#endif
diff --git a/arch/arm/mach-tegra/include/mach/fb.h b/arch/arm/mach-tegra/include/mach/fb.h
new file mode 100644
index 00000000000..ced6f9c2cb4
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/fb.h
@@ -0,0 +1,61 @@
1/*
2 * arch/arm/mach-tegra/include/mach/fb.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_FB_H
21#define __MACH_TEGRA_FB_H
22
23#include <linux/fb.h>
24
25struct nvhost_device;
26struct tegra_dc;
27struct tegra_fb_data;
28struct tegra_fb_info;
29struct resource;
30
31#ifdef CONFIG_FB_TEGRA
32struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev,
33 struct tegra_dc *dc,
34 struct tegra_fb_data *fb_data,
35 struct resource *fb_mem);
36void tegra_fb_unregister(struct tegra_fb_info *fb_info);
37void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info,
38 struct fb_monspecs *specs,
39 bool (*mode_filter)(const struct tegra_dc *dc,
40 struct fb_videomode *mode));
41#else
42static inline struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev,
43 struct tegra_dc *dc,
44 struct tegra_fb_data *fb_data,
45 struct resource *fb_mem)
46{
47 return NULL;
48}
49
50static inline void tegra_fb_unregister(struct tegra_fb_info *fb_info)
51{
52}
53
54static inline void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info,
55 struct fb_monspecs *specs,
56 bool (*mode_filter)(struct fb_videomode *mode))
57{
58}
59#endif
60
61#endif
diff --git a/arch/arm/mach-tegra/include/mach/fiq.h b/arch/arm/mach-tegra/include/mach/fiq.h
new file mode 100644
index 00000000000..17625facf62
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/fiq.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 *
4 * Author:
5 * Iliyan Malchev <malchev@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#ifndef __ASM_ARCH_TEGRA_FIQ_H
19#define __ASM_ARCH_TEGRA_FIQ_H
20
21/* enable/disable an interrupt that is an FIQ (safe from FIQ context?) */
22void tegra_fiq_enable(int n);
23void tegra_fiq_disable(int n);
24
25#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
new file mode 100644
index 00000000000..b7357ab0c4d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -0,0 +1,80 @@
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 <linux/init.h>
24#include <mach/irqs.h>
25
26#define TEGRA_NR_GPIOS INT_GPIO_NR
27#define ARCH_NR_GPIOS (TEGRA_NR_GPIOS + 128)
28
29#include <asm-generic/gpio.h>
30#include "pinmux.h"
31
32struct gpio_init_pin_info {
33 char name[16];
34 int gpio_nr;
35 bool is_gpio;
36 bool is_input;
37 int value; /* Value if it is output*/
38};
39
40#define gpio_get_value __gpio_get_value
41#define gpio_set_value __gpio_set_value
42#define gpio_cansleep __gpio_cansleep
43
44#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
45#define TEGRA_IRQ_TO_GPIO(irq) ((irq) - INT_GPIO_BASE)
46
47static inline int gpio_to_irq(unsigned int gpio)
48{
49 /* SOC gpio */
50 if (gpio < TEGRA_NR_GPIOS)
51 return INT_GPIO_BASE + gpio;
52
53 /* For non soc gpio, the external peripheral driver need to
54 * provide the implementation */
55 return __gpio_to_irq(gpio);
56}
57
58static inline int irq_to_gpio(unsigned int irq)
59{
60 /* SOC gpio */
61 if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR))
62 return irq - INT_GPIO_BASE;
63
64 /* we don't supply reverse mappings for non-SOC gpios */
65 return -EIO;
66}
67
68struct tegra_gpio_table {
69 int gpio; /* GPIO number */
70 bool enable; /* Enable for GPIO at init? */
71};
72
73void tegra_gpio_config(struct tegra_gpio_table *table, int num);
74void tegra_gpio_enable(int gpio);
75void tegra_gpio_disable(int gpio);
76int tegra_gpio_resume_init(void);
77void tegra_gpio_init_configure(unsigned gpio, bool is_input, int value);
78void tegra_gpio_set_tristate(int gpio, enum tegra_tristate ts);
79int tegra_gpio_get_bank_int_nr(int gpio);
80#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpufuse.h b/arch/arm/mach-tegra/include/mach/gpufuse.h
new file mode 100644
index 00000000000..4aa6cb66d5d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpufuse.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-tegra/include/mach/gpufuse.h
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/* Number of register sets to handle in host context switching */
18int tegra_gpu_register_sets(void);
19
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h
new file mode 100644
index 00000000000..92600f75fd4
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/hardware.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 * Copyright (C) 2011 NVIDIA Corp.
4 *
5 * Author:
6 * Colin Cross <ccross@google.com>
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_HARDWARE_H
20#define MACH_TEGRA_HARDWARE_H
21
22#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
23#define pcibios_assign_all_busses() 1
24
25#else
26
27#define pcibios_assign_all_busses() 0
28#endif
29
30enum tegra_chipid {
31 TEGRA_CHIPID_UNKNOWN = 0,
32 TEGRA_CHIPID_TEGRA2 = 0x20,
33 TEGRA_CHIPID_TEGRA3 = 0x30,
34};
35
36enum tegra_revision {
37 TEGRA_REVISION_UNKNOWN = 0,
38 TEGRA_REVISION_A01,
39 TEGRA_REVISION_A02,
40 TEGRA_REVISION_A03,
41 TEGRA_REVISION_A03p,
42 TEGRA_REVISION_A04,
43 TEGRA_REVISION_A04p,
44 TEGRA_REVISION_MAX,
45};
46
47enum tegra_chipid tegra_get_chipid(void);
48enum tegra_revision tegra_get_revision(void);
49
50#endif
diff --git a/arch/arm/mach-tegra/include/mach/hdmi-audio.h b/arch/arm/mach-tegra/include/mach/hdmi-audio.h
new file mode 100644
index 00000000000..7d760690081
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/hdmi-audio.h
@@ -0,0 +1,46 @@
1/*
2 * arch/arm/mach-tegra/include/mach/hdmi-audio.h
3 *
4 * Copyright (c) 2008-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_TEGRA_HDMI_AUDIO_H
22#define __MACH_TEGRA_HDMI_AUDIO_H
23
24#include <linux/kernel.h>
25#include <linux/types.h>
26
27enum {
28 AUDIO_FREQ_32K = 32000,
29 AUDIO_FREQ_44_1K = 44100,
30 AUDIO_FREQ_48K = 48000,
31 AUDIO_FREQ_88_2K = 88200,
32 AUDIO_FREQ_96K = 96000,
33 AUDIO_FREQ_176_4K = 176400,
34 AUDIO_FREQ_192K = 192000,
35};
36
37enum {
38 AUTO = 0,
39 SPDIF,
40 HDA,
41};
42
43int tegra_hdmi_setup_audio_freq_source(unsigned audio_freq, unsigned audio_source);
44int tegra_hdmi_setup_hda_presence(void);
45
46#endif /* __MACH_TEGRA_HDMI_AUDIO_H */
diff --git a/arch/arm/mach-tegra/include/mach/i2s.h b/arch/arm/mach-tegra/include/mach/i2s.h
new file mode 100644
index 00000000000..42cce885cda
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/i2s.h
@@ -0,0 +1,316 @@
1/*
2 * arch/arm/mach-tegra/include/mach/i2s.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Iliyan Malchev <malchev@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 __ARCH_ARM_MACH_TEGRA_I2S_H
21#define __ARCH_ARM_MACH_TEGRA_I2S_H
22
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <linux/platform_device.h>
26
27/* Offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */
28
29#define I2S_I2S_CTRL_0 0
30#define I2S_I2S_STATUS_0 4
31#define I2S_I2S_TIMING_0 8
32#define I2S_I2S_FIFO_SCR_0 0x0c
33#define I2S_I2S_PCM_CTRL_0 0x10
34#define I2S_I2S_NW_CTRL_0 0x14
35#define I2S_I2S_TDM_CTRL_0 0x20
36#define I2S_I2S_TDM_TX_RX_CTRL_0 0x24
37#define I2S_I2S_FIFO1_0 0x40
38#define I2S_I2S_FIFO2_0 0x80
39
40/*
41 * I2S_I2S_CTRL_0
42 */
43
44#define I2S_I2S_CTRL_FIFO2_TX_ENABLE (1<<30)
45#define I2S_I2S_CTRL_FIFO1_ENABLE (1<<29)
46#define I2S_I2S_CTRL_FIFO2_ENABLE (1<<28)
47#define I2S_I2S_CTRL_FIFO1_RX_ENABLE (1<<27)
48#define I2S_I2S_CTRL_FIFO_LPBK_ENABLE (1<<26)
49#define I2S_I2S_CTRL_MASTER_ENABLE (1<<25)
50#define I2S_I2S_CTRL_L_R_CTRL (1<<24) /* 0 = L/R: low/high */
51
52#define I2S_BIT_FORMAT_I2S 0
53#define I2S_BIT_FORMAT_RJM 1
54#define I2S_BIT_FORMAT_LJM 2
55#define I2S_BIT_FORMAT_DSP 3
56#define I2S_BIT_FORMAT_SHIFT 10
57
58#define I2S_I2S_CTRL_BIT_FORMAT_MASK (3<<10)
59#define I2S_I2S_CTRL_BIT_FORMAT_I2S (I2S_BIT_FORMAT_I2S<<10)
60#define I2S_I2S_CTRL_BIT_FORMAT_RJM (I2S_BIT_FORMAT_RJM<<10)
61#define I2S_I2S_CTRL_BIT_FORMAT_LJM (I2S_BIT_FORMAT_LJM<<10)
62#define I2S_I2S_CTRL_BIT_FORMAT_DSP (I2S_BIT_FORMAT_DSP<<10)
63
64#define I2S_BIT_SIZE_16 0
65#define I2S_BIT_SIZE_20 1
66#define I2S_BIT_SIZE_24 2
67#define I2S_BIT_SIZE_32 3
68#define I2S_BIT_SIZE_SHIFT 8
69
70#define I2S_I2S_CTRL_BIT_SIZE_MASK (3 << I2S_BIT_SIZE_SHIFT)
71#define I2S_I2S_CTRL_BIT_SIZE_16 (I2S_BIT_SIZE_16 << I2S_BIT_SIZE_SHIFT)
72#define I2S_I2S_CTRL_BIT_SIZE_20 (I2S_BIT_SIZE_20 << I2S_BIT_SIZE_SHIFT)
73#define I2S_I2S_CTRL_BIT_SIZE_24 (I2S_BIT_SIZE_24 << I2S_BIT_SIZE_SHIFT)
74#define I2S_I2S_CTRL_BIT_SIZE_32 (I2S_BIT_SIZE_32 << I2S_BIT_SIZE_SHIFT)
75
76#define I2S_FIFO_16_LSB 0
77#define I2S_FIFO_20_LSB 1
78#define I2S_FIFO_24_LSB 2
79#define I2S_FIFO_32 3
80#define I2S_FIFO_PACKED 7
81#define I2S_FIFO_SHIFT 4
82
83#define I2S_I2S_CTRL_FIFO_FORMAT_MASK (7<<4)
84#define I2S_I2S_CTRL_FIFO_FORMAT_16_LSB \
85 (I2S_FIFO_16_LSB << I2S_FIFO_SHIFT)
86#define I2S_I2S_CTRL_FIFO_FORMAT_20_LSB \
87 (I2S_FIFO_20_LSB << I2S_FIFO_SHIFT)
88#define I2S_I2S_CTRL_FIFO_FORMAT_24_LSB \
89 (I2S_FIFO_24_LSB << I2S_FIFO_SHIFT)
90#define I2S_I2S_CTRL_FIFO_FORMAT_32 \
91 (I2S_FIFO_32 << I2S_FIFO_SHIFT)
92#define I2S_I2S_CTRL_FIFO_FORMAT_PACKED \
93 (I2S_FIFO_PACKED << I2S_FIFO_SHIFT)
94
95#define I2S_I2S_IE_FIFO1_ERR (1<<3)
96#define I2S_I2S_IE_FIFO2_ERR (1<<2)
97#define I2S_I2S_QE_FIFO1 (1<<1)
98#define I2S_I2S_QE_FIFO2 (1<<0)
99
100/*
101 * I2S_I2S_STATUS_0
102 */
103
104#define I2S_I2S_STATUS_FIFO1_RDY (1<<31)
105#define I2S_I2S_STATUS_FIFO2_RDY (1<<30)
106#define I2S_I2S_STATUS_FIFO1_BSY (1<<29)
107#define I2S_I2S_STATUS_FIFO2_BSY (1<<28)
108#define I2S_I2S_STATUS_FIFO1_ERR (1<<3)
109#define I2S_I2S_STATUS_FIFO2_ERR (1<<2)
110#define I2S_I2S_STATUS_QS_FIFO1 (1<<1)
111#define I2S_I2S_STATUS_QS_FIFO2 (1<<0)
112
113/*
114 * I2S_I2S_TIMING_0
115 */
116
117#define I2S_I2S_TIMING_NON_SYM_ENABLE (1<<12)
118#define I2S_I2S_TIMING_CHANNEL_BIT_COUNT_MASK 0x7ff
119#define I2S_I2S_TIMING_CHANNEL_BIT_COUNT (1<<0)
120
121/*
122 * I2S_I2S_FIFO_SCR_0
123 */
124
125#define I2S_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
126#define I2S_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
127#define I2S_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
128
129#define I2S_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_MASK (0x3f<<24)
130#define I2S_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_MASK (0x3f<<16)
131
132#define I2S_I2S_FIFO_SCR_FIFO2_CLR (1<<12)
133#define I2S_I2S_FIFO_SCR_FIFO1_CLR (1<<8)
134
135#define I2S_FIFO_ATN_LVL_ONE_SLOT 0
136#define I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
137#define I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
138#define I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
139#define I2S_FIFO2_ATN_LVL_SHIFT 4
140#define I2S_FIFO1_ATN_LVL_SHIFT 0
141
142#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK \
143 (3 << I2S_FIFO2_ATN_LVL_SHIFT)
144#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT \
145 (I2S_FIFO_ATN_LVL_ONE_SLOT << I2S_FIFO2_ATN_LVL_SHIFT)
146#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS \
147 (I2S_FIFO_ATN_LVL_FOUR_SLOTS << I2S_FIFO2_ATN_LVL_SHIFT)
148#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS \
149 (I2S_FIFO_ATN_LVL_EIGHT_SLOTS << I2S_FIFO2_ATN_LVL_SHIFT)
150#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS \
151 (I2S_FIFO_ATN_LVL_TWELVE_SLOTS << I2S_FIFO2_ATN_LVL_SHIFT)
152
153#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK \
154 (3 << I2S_FIFO1_ATN_LVL_SHIFT)
155#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT \
156 (I2S_FIFO_ATN_LVL_ONE_SLOT << I2S_FIFO1_ATN_LVL_SHIFT)
157#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS \
158 (I2S_FIFO_ATN_LVL_FOUR_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT)
159#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS \
160 (I2S_FIFO_ATN_LVL_EIGHT_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT)
161#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS \
162 (I2S_FIFO_ATN_LVL_TWELVE_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT)
163/*
164 * I2S_I2S_PCM_CTRL_0
165 */
166#define I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ 0
167#define I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ 1
168#define I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ 2
169#define I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ 3
170#define I2S_PCM_TRM_EDGE_CTRL_SHIFT 9
171
172#define I2S_I2S_PCM_TRM_EDGE_CTRL_MASK \
173 (3 << I2S_I2S_PCM_TRM_EDGE_CTRL_SHIFT)
174#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ \
175 (I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ \
176 << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
177#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ \
178 (I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ \
179 << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
180#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ \
181 (I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ \
182 << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
183#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ \
184 (I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ \
185 << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
186
187#define I2S_PCM_TRM_MASK_BITS_ZERO 0
188#define I2S_PCM_TRM_MASK_BITS_ONE 1
189#define I2S_PCM_TRM_MASK_BITS_TWO 2
190#define I2S_PCM_TRM_MASK_BITS_THREE 3
191#define I2S_PCM_TRM_MASK_BITS_FOUR 4
192#define I2S_PCM_TRM_MASK_BITS_FIVE 5
193#define I2S_PCM_TRM_MASK_BITS_SIX 6
194#define I2S_PCM_TRM_MASK_BITS_SEVEN 7
195#define I2S_PCM_TRM_MASK_BITS_SHIFT 6
196
197#define I2S_I2S_PCM_TRM_MASK_BITS_MASK \
198 (7 << I2S_PCM_TRM_MASK_BITS_SHIFT)
199#define I2S_I2S_PCM_TRM_MASK_BITS_ZERO \
200 (I2S_PCM_TRM_MASK_BITS_ZERO \
201 << I2S_PCM_TRM_MASK_BITS_SHIFT)
202#define I2S_I2S_PCM_TRM_MASK_BITS_ONE \
203 (I2S_PCM_TRM_MASK_BITS_ONE \
204 << I2S_PCM_TRM_MASK_BITS_SHIFT)
205#define I2S_I2S_PCM_TRM_MASK_BITS_TWO \
206 (I2S_PCM_TRM_MASK_BITS_TWO \
207 << I2S_PCM_TRM_MASK_BITS_SHIFT)
208#define I2S_I2S_PCM_TRM_MASK_BITS_THREE \
209 (I2S_PCM_TRM_MASK_BITS_THREE \
210 << I2S_PCM_TRM_MASK_BITS_SHIFT)
211#define I2S_I2S_PCM_TRM_MASK_BITS_FOUR \
212 (I2S_PCM_TRM_MASK_BITS_FOUR \
213 << I2S_PCM_TRM_MASK_BITS_SHIFT)
214#define I2S_I2S_PCM_TRM_MASK_BITS_FIVE \
215 (I2S_PCM_TRM_MASK_BITS_FIVE \
216 << I2S_PCM_TRM_MASK_BITS_SHIFT)
217#define I2S_I2S_PCM_TRM_MASK_BITS_SIX \
218 (I2S_PCM_TRM_MASK_BITS_SIX \
219 << I2S_PCM_TRM_MASK_BITS_SHIFT)
220#define I2S_I2S_PCM_TRM_MASK_BITS_SEVEN \
221 (I2S_PCM_TRM_MASK_BITS_SEVEN \
222 << I2S_PCM_TRM_MASK_BITS_SHIFT)
223
224#define I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL (1<<5)
225#define I2S_I2S_PCM_CTRL_TRM_MODE (1<<4)
226
227#define I2S_PCM_RCV_MASK_BITS_ZERO 0
228#define I2S_PCM_RCV_MASK_BITS_ONE 1
229#define I2S_PCM_RCV_MASK_BITS_TWO 2
230#define I2S_PCM_RCV_MASK_BITS_THREE 3
231#define I2S_PCM_RCV_MASK_BITS_FOUR 4
232#define I2S_PCM_RCV_MASK_BITS_FIVE 5
233#define I2S_PCM_RCV_MASK_BITS_SIX 6
234#define I2S_PCM_RCV_MASK_BITS_SEVEN 7
235#define I2S_PCM_RCV_MASK_BITS_SHIFT 1
236
237#define I2S_I2S_PCM_RCV_MASK_BITS_MASK \
238 (7 << I2S_PCM_RCV_MASK_BITS_SHIFT)
239#define I2S_I2S_PCM_RCV_MASK_BITS_ZERO \
240 (I2S_PCM_RCV_MASK_BITS_ZERO \
241 << I2S_PCM_RCV_MASK_BITS_SHIFT)
242#define I2S_I2S_PCM_RCV_MASK_BITS_ONE \
243 (I2S_PCM_RCV_MASK_BITS_ONE \
244 << I2S_PCM_RCV_MASK_BITS_SHIFT)
245#define I2S_I2S_PCM_RCV_MASK_BITS_TWO \
246 (I2S_PCM_RCV_MASK_BITS_TWO \
247 << I2S_PCM_RCV_MASK_BITS_SHIFT)
248#define I2S_I2S_PCM_RCV_MASK_BITS_THREE \
249 (I2S_PCM_RCV_MASK_BITS_THREE \
250 << I2S_PCM_RCV_MASK_BITS_SHIFT)
251#define I2S_I2S_PCM_RCV_MASK_BITS_FOUR \
252 (I2S_PCM_RCV_MASK_BITS_FOUR \
253 << I2S_PCM_RCV_MASK_BITS_SHIFT)
254#define I2S_I2S_PCM_RCV_MASK_BITS_FIVE \
255 (I2S_PCM_RCV_MASK_BITS_FIVE \
256 << I2S_PCM_RCV_MASK_BITS_SHIFT)
257#define I2S_I2S_PCM_RCV_MASK_BITS_SIX \
258 (I2S_PCM_RCV_MASK_BITS_SIX \
259 << I2S_PCM_RCV_MASK_BITS_SHIFT)
260#define I2S_I2S_PCM_RCV_MASK_BITS_SEVEN \
261 (I2S_PCM_RCV_MASK_BITS_SEVEN \
262 << I2S_PCM_RCV_MASK_BITS_SHIFT)
263
264#define I2S_I2S_PCM_CTRL_RCV_MODE (1<<0)
265
266/*
267 * I2S_I2S_NW_CTRL_0
268 */
269
270#define I2S_TRM_TLPHY_SLOT_SEL_SLOT1 0
271#define I2S_TRM_TLPHY_SLOT_SEL_SLOT2 1
272#define I2S_TRM_TLPHY_SLOT_SEL_SLOT3 2
273#define I2S_TRM_TLPHY_SLOT_SEL_SLOT4 3
274#define I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT 4
275
276#define I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_MASK \
277 (3 << I2S_TRM_TLPHY_SLOT_SEL_SHIFT)
278#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT1 \
279 (I2S_TRM_TLPHY_SLOT_SEL_SLOT1 \
280 << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT)
281#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT2 \
282 (I2S_TRM_TLPHY_SLOT_SEL_SLOT2 \
283 << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT)
284#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT3 \
285 (I2S_TRM_TLPHY_SLOT_SEL_SLOT3 \
286 << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT)
287#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT4 \
288 (I2S_TRM_TLPHY_SLOT_SEL_SLOT4 \
289 << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT)
290
291#define I2S_I2S_NW_CTRL_TRM_TLPHY_MODE (1<<3)
292
293#define I2S_RCV_TLPHY_SLOT_SEL_SLOT1 0
294#define I2S_RCV_TLPHY_SLOT_SEL_SLOT2 1
295#define I2S_RCV_TLPHY_SLOT_SEL_SLOT3 2
296#define I2S_RCV_TLPHY_SLOT_SEL_SLOT4 3
297#define I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT 1
298
299#define I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_MASK \
300 (3 << I2S_RCV_TLPHY_SLOT_SEL_SHIFT)
301#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT1 \
302 (I2S_RCV_TLPHY_SLOT_SEL_SLOT1 \
303 << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT)
304#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT2 \
305 (I2S_RCV_TLPHY_SLOT_SEL_SLOT2 \
306 << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT)
307#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT3 \
308 (I2S_RCV_TLPHY_SLOT_SEL_SLOT3 \
309 << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT)
310#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT4 \
311 (I2S_RCV_TLPHY_SLOT_SEL_SLOT4 \
312 << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT)
313
314#define I2S_I2S_NW_CTRL_RCV_TLPHY_MODE (1<<0)
315
316#endif /* __ARCH_ARM_MACH_TEGRA_I2S_H */
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
new file mode 100644
index 00000000000..2b091bf83f3
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -0,0 +1,136 @@
1/*
2 * arch/arm/mach-tegra/include/mach/io.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011-2012 NVIDIA Corporation.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 * Erik Gilling <konkers@google.com>
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#ifndef __MACH_TEGRA_IO_H
23#define __MACH_TEGRA_IO_H
24
25#ifdef CONFIG_ARCH_TEGRA_2x_SOC
26#define IO_SPACE_LIMIT 0xffff
27#else
28#define IO_SPACE_LIMIT 0xffffffff
29#endif
30
31/* On TEGRA, many peripherals are very closely packed in
32 * two 256MB io windows (that actually only use about 64KB
33 * at the start of each).
34 *
35 * We will just map the first 1MB of each window (to minimize
36 * pt entries needed) and provide a macro to transform physical
37 * io addresses to an appropriate void __iomem *.
38 *
39 */
40
41#define IO_IRAM_PHYS 0x40000000
42#define IO_IRAM_VIRT 0xFE400000
43#define IO_IRAM_SIZE SZ_256K
44
45#define IO_CPU_PHYS 0x50000000
46#define IO_CPU_VIRT 0xFE000000
47#define IO_CPU_SIZE SZ_1M
48
49#define IO_PPSB_PHYS 0x60000000
50#define IO_PPSB_VIRT 0xFE200000
51#define IO_PPSB_SIZE SZ_1M
52
53#define IO_APB_PHYS 0x70000000
54#define IO_APB_VIRT 0xFE300000
55#define IO_APB_SIZE SZ_1M
56
57#ifdef CONFIG_ARCH_TEGRA_2x_SOC
58#define IO_USB_PHYS 0xC5000000
59#else
60#define IO_USB_PHYS 0x7D000000
61#endif
62#define IO_USB_VIRT 0xFE500000
63#define IO_USB_SIZE SZ_1M
64
65#ifdef CONFIG_ARCH_TEGRA_2x_SOC
66#define IO_SDMMC_PHYS 0xC8000000
67#else
68#define IO_SDMMC_PHYS 0x78000000
69#endif
70#define IO_SDMMC_VIRT 0xFE600000
71#define IO_SDMMC_SIZE SZ_1M
72
73#define IO_HOST1X_PHYS 0x54000000
74#define IO_HOST1X_VIRT 0xFE700000
75#define IO_HOST1X_SIZE SZ_8M
76
77#ifdef CONFIG_ARCH_TEGRA_2x_SOC
78#define IO_PPCS_PHYS 0xC4000000
79#else
80#define IO_PPCS_PHYS 0x7C000000
81#endif
82#define IO_PPCS_VIRT 0xFE100000
83#define IO_PPCS_SIZE SZ_1M
84
85#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
86#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
87
88#define IO_TO_VIRT(n) ( \
89 IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \
90 IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \
91 IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \
92 IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \
93 IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \
94 IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \
95 IO_TO_VIRT_BETWEEN((n), IO_IRAM_PHYS, IO_IRAM_SIZE) ? \
96 IO_TO_VIRT_XLATE((n), IO_IRAM_PHYS, IO_IRAM_VIRT) : \
97 IO_TO_VIRT_BETWEEN((n), IO_HOST1X_PHYS, IO_HOST1X_SIZE) ? \
98 IO_TO_VIRT_XLATE((n), IO_HOST1X_PHYS, IO_HOST1X_VIRT) : \
99 IO_TO_VIRT_BETWEEN((n), IO_USB_PHYS, IO_USB_SIZE) ? \
100 IO_TO_VIRT_XLATE((n), IO_USB_PHYS, IO_USB_VIRT) : \
101 IO_TO_VIRT_BETWEEN((n), IO_SDMMC_PHYS, IO_SDMMC_SIZE) ? \
102 IO_TO_VIRT_XLATE((n), IO_SDMMC_PHYS, IO_SDMMC_VIRT) : \
103 IO_TO_VIRT_BETWEEN((n), IO_PPCS_PHYS, IO_PPCS_SIZE) ? \
104 IO_TO_VIRT_XLATE((n), IO_PPCS_PHYS, IO_PPCS_VIRT) : \
105 0)
106
107#ifndef __ASSEMBLER__
108
109#define __arch_ioremap tegra_ioremap
110#define __arch_iounmap tegra_iounmap
111
112void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
113void tegra_iounmap(volatile void __iomem *addr);
114
115#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
116
117#if defined(CONFIG_TEGRA_PCI)
118extern void __iomem *tegra_pcie_io_base;
119
120static inline void __iomem *__io(unsigned long addr)
121{
122 return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
123}
124#else
125static inline void __iomem *__io(unsigned long addr)
126{
127 return (void __iomem *)addr;
128}
129#endif
130
131#define __io(a) __io(a)
132#define __mem_pci(a) (a)
133
134#endif
135
136#endif
diff --git a/arch/arm/mach-tegra/include/mach/io_dpd.h b/arch/arm/mach-tegra/include/mach/io_dpd.h
new file mode 100644
index 00000000000..8d153792b79
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/io_dpd.h
@@ -0,0 +1,40 @@
1/*
2 * arch/arm/mach-tegra/include/mach/io_dpd.h
3 *
4 * Copyright (C) 2012 NVIDIA Corporation.
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_IO_DPD_H
18#define __MACH_TEGRA_IO_DPD_H
19
20/* Tegra io dpd APIs */
21#ifdef CONFIG_PM_SLEEP
22struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev); /* get handle */
23void tegra_io_dpd_enable(struct tegra_io_dpd *hnd); /* enable dpd */
24void tegra_io_dpd_disable(struct tegra_io_dpd *hnd); /* disable dpd */
25#else
26static inline struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
27{
28 return NULL;
29}
30static inline void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
31{
32 /* Do nothing */
33}
34static inline void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
35{
36 /* Do nothing */
37}
38#endif
39
40#endif /* end __MACH_TEGRA_IO_DPD_H */
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
new file mode 100644
index 00000000000..c491abafb8b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -0,0 +1,523 @@
1/*
2 * arch/arm/mach-tegra/include/mach/iomap.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 * Erik Gilling <konkers@google.com>
10 *
11 * Copyright (C) 2010-2011 NVIDIA Corporation
12 *
13 * This software is licensed under the terms of the GNU General Public
14 * License version 2, as published by the Free Software Foundation, and
15 * may be copied, distributed, and modified under those terms.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 */
23
24#ifndef __MACH_TEGRA_IOMAP_H
25#define __MACH_TEGRA_IOMAP_H
26
27#include <asm/sizes.h>
28
29#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
30#define TEGRA_NOR_FLASH_BASE 0xD0000000
31#define TEGRA_NOR_FLASH_SIZE SZ_256M
32#else
33#define TEGRA_NOR_FLASH_BASE 0x48000000
34#define TEGRA_NOR_FLASH_SIZE SZ_128M
35#endif
36
37#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
38#define TEGRA_DRAM_BASE 0x00000000
39#define TEGRA_DRAM_SIZE SZ_1G /* Maximum size */
40#else
41#define TEGRA_DRAM_BASE 0x80000000
42#define TEGRA_DRAM_SIZE (SZ_2G - SZ_1M) /* Maximum size */
43#endif
44
45#define TEGRA_IRAM_BASE 0x40000000
46#define TEGRA_IRAM_SIZE SZ_256K
47
48/* First 1K of IRAM is reserved for cpu reset handler. */
49#define TEGRA_RESET_HANDLER_BASE TEGRA_IRAM_BASE
50#define TEGRA_RESET_HANDLER_SIZE SZ_1K
51
52#define TEGRA_HOST1X_BASE 0x50000000
53#define TEGRA_HOST1X_SIZE 0x24000
54
55#define TEGRA_ARM_PERIF_BASE 0x50040000
56#define TEGRA_ARM_PERIF_SIZE SZ_8K
57
58#define TEGRA_MSELECT_BASE 0x50042000
59#define TEGRA_MSELECT_SIZE 80
60
61#define TEGRA_ARM_PL310_BASE 0x50043000
62#define TEGRA_ARM_PL310_SIZE SZ_4K
63
64#define TEGRA_ARM_INT_DIST_BASE 0x50041000
65#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
66
67#define TEGRA_MPE_BASE 0x54040000
68#define TEGRA_MPE_SIZE SZ_256K
69
70#define TEGRA_VI_BASE 0x54080000
71#define TEGRA_VI_SIZE SZ_256K
72
73#define TEGRA_ISP_BASE 0x54100000
74#define TEGRA_ISP_SIZE SZ_256K
75
76#define TEGRA_DISPLAY_BASE 0x54200000
77#define TEGRA_DISPLAY_SIZE SZ_256K
78
79#define TEGRA_DISPLAY2_BASE 0x54240000
80#define TEGRA_DISPLAY2_SIZE SZ_256K
81
82#define TEGRA_HDMI_BASE 0x54280000
83#define TEGRA_HDMI_SIZE SZ_256K
84
85#define TEGRA_DSI_BASE 0x54300000
86#define TEGRA_DSI_SIZE SZ_256K
87
88#define TEGRA_DSIB_BASE 0x54400000
89#define TEGRA_DSIB_SIZE SZ_256K
90
91#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
92
93#define TEGRA_GART_BASE 0x58000000
94#define TEGRA_GART_SIZE SZ_32M
95
96#else
97
98#define TEGRA_SMMU_BASE_TEGRA3_A01 0xe0000000
99#define TEGRA_SMMU_SIZE_TEGRA3_A01 SZ_256M
100#define TEGRA_SMMU_BASE 0x00001000
101#define TEGRA_SMMU_SIZE (SZ_1G - SZ_4K * 2)
102
103#endif
104
105#define TEGRA_RES_SEMA_SIZE SZ_4K
106#define TEGRA_RES_SEMA_BASE 0x60001000
107
108#define TEGRA_ARB_SEMA_BASE 0x60002000
109#define TEGRA_ARB_SEMA_SIZE SZ_4K
110
111#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
112#define TEGRA_PRIMARY_ICTLR_SIZE 64
113
114#define TEGRA_ARBGNT_ICTLR_BASE 0x60004040
115#define TEGRA_ARBGNT_ICTLR_SIZE 192
116
117#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100
118#define TEGRA_SECONDARY_ICTLR_SIZE 64
119
120#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200
121#define TEGRA_TERTIARY_ICTLR_SIZE 64
122
123#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
124#define TEGRA_QUATERNARY_ICTLR_SIZE 64
125
126#ifndef CONFIG_ARCH_TEGRA_2x_SOC
127
128#define TEGRA_QUINARY_ICTLR_BASE 0x60004400
129#define TEGRA_QUINARY_ICTLR_SIZE SZ_64
130
131#endif
132
133#define TEGRA_TMR1_BASE 0x60005000
134#define TEGRA_TMR1_SIZE SZ_8
135
136#define TEGRA_TMR2_BASE 0x60005008
137#define TEGRA_TMR2_SIZE SZ_8
138
139#define TEGRA_TMRUS_BASE 0x60005010
140#define TEGRA_TMRUS_SIZE 64
141
142#define TEGRA_TMR3_BASE 0x60005050
143#define TEGRA_TMR3_SIZE SZ_8
144
145#define TEGRA_TMR4_BASE 0x60005058
146#define TEGRA_TMR4_SIZE SZ_8
147
148#ifndef CONFIG_ARCH_TEGRA_2x_SOC
149
150#define TEGRA_TMR5_BASE 0x60005060
151#define TEGRA_TMR5_SIZE 8
152
153#define TEGRA_TMR6_BASE 0x60005068
154#define TEGRA_TMR6_SIZE 8
155
156#define TEGRA_TMR7_BASE 0x60005070
157#define TEGRA_TMR7_SIZE 8
158
159#define TEGRA_TMR8_BASE 0x60005078
160#define TEGRA_TMR8_SIZE 8
161
162#define TEGRA_TMR9_BASE 0x60005080
163#define TEGRA_TMR9_SIZE 8
164
165#define TEGRA_TMR10_BASE 0x60005088
166#define TEGRA_TMR10_SIZE 8
167
168#define TEGRA_WDT0_BASE 0x60005100
169#define TEGRA_WDT0_SIZE 32
170
171#define TEGRA_WDT1_BASE 0x60005120
172#define TEGRA_WDT1_SIZE 32
173
174#define TEGRA_WDT2_BASE 0x60005140
175#define TEGRA_WDT2_SIZE 32
176
177#define TEGRA_WDT3_BASE 0x60005160
178#define TEGRA_WDT3_SIZE 32
179
180#define TEGRA_WDT4_BASE 0x60005180
181#define TEGRA_WDT4_SIZE 32
182
183#endif
184
185#define TEGRA_CLK_RESET_BASE 0x60006000
186#define TEGRA_CLK_RESET_SIZE SZ_4K
187
188#define TEGRA_FLOW_CTRL_BASE 0x60007000
189#define TEGRA_FLOW_CTRL_SIZE 20
190
191#define TEGRA_AHB_DMA_BASE 0x60008000
192#define TEGRA_AHB_DMA_SIZE SZ_4K
193
194#define TEGRA_AHB_DMA_CH0_BASE 0x60009000
195#define TEGRA_AHB_DMA_CH0_SIZE 32
196
197#define TEGRA_APB_DMA_BASE 0x6000A000
198#define TEGRA_APB_DMA_SIZE SZ_4K
199
200#define TEGRA_APB_DMA_CH0_BASE 0x6000B000
201#define TEGRA_APB_DMA_CH0_SIZE 32
202
203#ifndef CONFIG_ARCH_TEGRA_2x_SOC
204
205#define TEGRA_AHB_ARB_BASE 0x6000C000
206#define TEGRA_AHB_ARB_SIZE 768 /* Overlaps with GISMO */
207
208#endif
209
210#define TEGRA_AHB_GIZMO_BASE 0x6000C004
211#define TEGRA_AHB_GIZMO_SIZE 0x10C
212
213#define TEGRA_SB_BASE 0x6000C200
214#define TEGRA_SB_SIZE 256
215
216#define TEGRA_STATMON_BASE 0x6000C400
217#define TEGRA_STATMON_SIZE SZ_1K
218
219#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
220
221#define TEGRA_ACTMON_BASE 0x6000C800
222#define TEGRA_ACTMON_SIZE SZ_1K
223
224#endif
225
226#define TEGRA_GPIO_BASE 0x6000D000
227#define TEGRA_GPIO_SIZE SZ_4K
228
229#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000
230#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K
231
232#define TEGRA_BSEA_BASE 0x60010000
233#define TEGRA_BSEA_SIZE SZ_4K
234
235#define TEGRA_VDE_BASE 0x6001A000
236#define TEGRA_VDE_SIZE 0x3c00
237
238#define TEGRA_APB_MISC_BASE 0x70000000
239#define TEGRA_APB_MISC_SIZE SZ_4K
240
241#define TEGRA_APB_MISC_DAS_BASE 0x70000c00
242#define TEGRA_APB_MISC_DAS_SIZE SZ_128
243
244#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
245
246#define TEGRA_AC97_BASE 0x70002000
247#define TEGRA_AC97_SIZE SZ_512
248
249#define TEGRA_SPDIF_BASE 0x70002400
250#define TEGRA_SPDIF_SIZE SZ_512
251
252#define TEGRA_I2S1_BASE 0x70002800
253#define TEGRA_I2S1_SIZE SZ_256
254
255#define TEGRA_I2S2_BASE 0x70002A00
256#define TEGRA_I2S2_SIZE SZ_256
257
258#define TEGRA_PCIE_BASE 0x80000000
259#define TEGRA_PCIE_SIZE SZ_1G
260
261#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
262
263#define TEGRA_TSENSOR_BASE 0x70014000
264#define TEGRA_TSENSOR_SIZE SZ_4K
265
266#define TEGRA_HDA_BASE 0x70030000
267#define TEGRA_HDA_SIZE SZ_64K
268
269#define TEGRA_AUDIO_CLUSTER_BASE 0x70080000
270#define TEGRA_AUDIO_CLUSTER_SIZE SZ_4K
271
272#define TEGRA_APBIF0_BASE TEGRA_AUDIO_CLUSTER_BASE
273#define TEGRA_APBIF0_SIZE 32
274
275#define TEGRA_APBIF1_BASE 0x70080020
276#define TEGRA_APBIF1_SIZE 32
277
278#define TEGRA_APBIF2_BASE 0x70080040
279#define TEGRA_APBIF2_SIZE 32
280
281#define TEGRA_APBIF3_BASE 0x70080060
282#define TEGRA_APBIF3_SIZE 32
283
284#define TEGRA_AHUB_BASE 0x70080200
285#define TEGRA_AHUB_SIZE SZ_256
286
287#define TEGRA_I2S0_BASE 0x70080300
288#define TEGRA_I2S0_SIZE SZ_256
289
290#define TEGRA_I2S1_BASE 0x70080400
291#define TEGRA_I2S1_SIZE SZ_256
292
293#define TEGRA_I2S2_BASE 0x70080500
294#define TEGRA_I2S2_SIZE SZ_256
295
296#define TEGRA_I2S3_BASE 0x70080600
297#define TEGRA_I2S3_SIZE SZ_256
298
299#define TEGRA_I2S4_BASE 0x70080700
300#define TEGRA_I2S4_SIZE SZ_256
301
302#define TEGRA_DAM0_BASE 0x70080800
303#define TEGRA_DAM0_SIZE SZ_256
304
305#define TEGRA_DAM1_BASE 0x70080900
306#define TEGRA_DAM1_SIZE SZ_256
307
308#define TEGRA_DAM2_BASE 0x70080A00
309#define TEGRA_DAM2_SIZE SZ_256
310
311#define TEGRA_SPDIF_BASE 0x70080B00
312#define TEGRA_SPDIF_SIZE SZ_256
313
314#define TEGRA_PCIE_BASE 0x00000000
315#define TEGRA_PCIE_SIZE SZ_1G
316
317#endif
318
319#define TEGRA_UARTA_BASE 0x70006000
320#define TEGRA_UARTA_SIZE 64
321
322#define TEGRA_UARTB_BASE 0x70006040
323#define TEGRA_UARTB_SIZE 64
324
325#define TEGRA_UARTC_BASE 0x70006200
326#define TEGRA_UARTC_SIZE SZ_256
327
328#define TEGRA_UARTD_BASE 0x70006300
329#define TEGRA_UARTD_SIZE SZ_256
330
331#define TEGRA_UARTE_BASE 0x70006400
332#define TEGRA_UARTE_SIZE SZ_256
333
334#define TEGRA_NAND_BASE 0x70008000
335#define TEGRA_NAND_SIZE SZ_256
336
337#define TEGRA_HSMMC_BASE 0x70008500
338#define TEGRA_HSMMC_SIZE SZ_256
339
340#define TEGRA_SNOR_BASE 0x70009000
341#define TEGRA_SNOR_SIZE SZ_4K
342
343#define TEGRA_PWFM_BASE 0x7000A000
344#define TEGRA_PWFM_SIZE SZ_256
345
346#define TEGRA_PWFM0_BASE 0x7000A000
347#define TEGRA_PWFM0_SIZE 4
348
349#define TEGRA_PWFM1_BASE 0x7000A010
350#define TEGRA_PWFM1_SIZE 4
351
352#define TEGRA_PWFM2_BASE 0x7000A020
353#define TEGRA_PWFM2_SIZE 4
354
355#define TEGRA_PWFM3_BASE 0x7000A030
356#define TEGRA_PWFM3_SIZE 4
357
358#define TEGRA_MIPI_BASE 0x7000B000
359#define TEGRA_MIPI_SIZE SZ_256
360
361#define TEGRA_I2C_BASE 0x7000C000
362#define TEGRA_I2C_SIZE SZ_256
363
364#define TEGRA_TWC_BASE 0x7000C100
365#define TEGRA_TWC_SIZE SZ_256
366
367#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
368
369#define TEGRA_SPI_BASE 0x7000C380
370#define TEGRA_SPI_SIZE 48
371
372#else
373
374#define TEGRA_DTV_BASE 0x7000C300
375#define TEGRA_DTV_SIZE SZ_256
376
377#endif
378
379#define TEGRA_I2C2_BASE 0x7000C400
380#define TEGRA_I2C2_SIZE SZ_256
381
382#define TEGRA_I2C3_BASE 0x7000C500
383#define TEGRA_I2C3_SIZE SZ_256
384
385#define TEGRA_OWR_BASE 0x7000C600
386#define TEGRA_OWR_SIZE 80
387
388#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
389
390#define TEGRA_DVC_BASE 0x7000D000
391#define TEGRA_DVC_SIZE SZ_512
392
393#else
394
395#define TEGRA_I2C4_BASE 0x7000C700
396#define TEGRA_I2C4_SIZE SZ_512
397
398#define TEGRA_I2C5_BASE 0x7000D000
399#define TEGRA_I2C5_SIZE SZ_512
400
401#endif
402
403#define TEGRA_SPI1_BASE 0x7000D400
404#define TEGRA_SPI1_SIZE SZ_512
405
406#define TEGRA_SPI2_BASE 0x7000D600
407#define TEGRA_SPI2_SIZE SZ_512
408
409#define TEGRA_SPI3_BASE 0x7000D800
410#define TEGRA_SPI3_SIZE SZ_512
411
412#define TEGRA_SPI4_BASE 0x7000DA00
413#define TEGRA_SPI4_SIZE SZ_512
414
415#ifndef CONFIG_ARCH_TEGRA_2x_SOC
416
417#define TEGRA_SPI5_BASE 0x7000DC00
418#define TEGRA_SPI5_SIZE SZ_512
419
420#define TEGRA_SPI6_BASE 0x7000DE00
421#define TEGRA_SPI6_SIZE SZ_512
422
423#endif
424
425#define TEGRA_RTC_BASE 0x7000E000
426#define TEGRA_RTC_SIZE SZ_256
427
428#define TEGRA_KBC_BASE 0x7000E200
429#define TEGRA_KBC_SIZE SZ_256
430
431#define TEGRA_PMC_BASE 0x7000E400
432#define TEGRA_PMC_SIZE SZ_256
433
434#define TEGRA_MC_BASE 0x7000F000
435#define TEGRA_MC_SIZE SZ_1K
436
437#define TEGRA_EMC_BASE 0x7000F400
438#define TEGRA_EMC_SIZE SZ_1K
439
440#define TEGRA_FUSE_BASE 0x7000F800
441#define TEGRA_FUSE_SIZE SZ_1K
442
443#define TEGRA_KFUSE_BASE 0x7000FC00
444#define TEGRA_KFUSE_SIZE SZ_1K
445
446#define TEGRA_CSITE_BASE 0x70040000
447#define TEGRA_CSITE_SIZE SZ_256K
448
449#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
450
451#define TEGRA_USB_BASE 0xC5000000
452#define TEGRA_USB_SIZE SZ_16K
453
454#define TEGRA_USB2_BASE 0xC5004000
455#define TEGRA_USB2_SIZE SZ_16K
456
457#define TEGRA_USB3_BASE 0xC5008000
458#define TEGRA_USB3_SIZE SZ_16K
459
460#define TEGRA_SDMMC1_BASE 0xC8000000
461#define TEGRA_SDMMC1_SIZE SZ_512
462
463#define TEGRA_SDMMC2_BASE 0xC8000200
464#define TEGRA_SDMMC2_SIZE SZ_512
465
466#define TEGRA_SDMMC3_BASE 0xC8000400
467#define TEGRA_SDMMC3_SIZE SZ_512
468
469#define TEGRA_SDMMC4_BASE 0xC8000600
470#define TEGRA_SDMMC4_SIZE SZ_512
471
472#else
473
474#define TEGRA_SATA_BASE 0x70020000
475#define TEGRA_SATA_SIZE SZ_64K
476
477#define TEGRA_SATA_CONFIG_BASE 0x70021000
478#define TEGRA_SATA_CONFIG_SIZE SZ_4K
479
480#define TEGRA_SATA_BAR5_BASE 0x70027000
481#define TEGRA_SATA_BAR5_SIZE SZ_8K
482
483#define TEGRA_SDMMC1_BASE 0x78000000
484#define TEGRA_SDMMC1_SIZE SZ_512
485
486#define TEGRA_SDMMC2_BASE 0x78000200
487#define TEGRA_SDMMC2_SIZE SZ_512
488
489#define TEGRA_SDMMC3_BASE 0x78000400
490#define TEGRA_SDMMC3_SIZE SZ_512
491
492#define TEGRA_SDMMC4_BASE 0x78000600
493#define TEGRA_SDMMC4_SIZE SZ_512
494
495#define TEGRA_USB_BASE 0x7D000000
496#define TEGRA_USB_SIZE SZ_16K
497
498#define TEGRA_USB2_BASE 0x7D004000
499#define TEGRA_USB2_SIZE SZ_16K
500
501#define TEGRA_USB3_BASE 0x7D008000
502#define TEGRA_USB3_SIZE SZ_16K
503
504#define TEGRA_SE_BASE 0x70012000
505#define TEGRA_SE_SIZE SZ_8K
506
507#endif
508
509#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
510# define TEGRA_DEBUG_UART_BASE 0
511#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
512# define TEGRA_DEBUG_UART_BASE TEGRA_UARTA_BASE
513#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
514# define TEGRA_DEBUG_UART_BASE TEGRA_UARTB_BASE
515#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
516# define TEGRA_DEBUG_UART_BASE TEGRA_UARTC_BASE
517#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
518# define TEGRA_DEBUG_UART_BASE TEGRA_UARTD_BASE
519#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
520# define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE
521#endif
522
523#endif
diff --git a/arch/arm/mach-tegra/include/mach/iovmm.h b/arch/arm/mach-tegra/include/mach/iovmm.h
new file mode 100644
index 00000000000..fd83a326e12
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/iovmm.h
@@ -0,0 +1,323 @@
1/*
2 * arch/arm/mach-tegra/include/mach/iovmm.h
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed i the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/list.h>
22#include <linux/platform_device.h>
23#include <linux/miscdevice.h>
24#include <linux/rbtree.h>
25#include <linux/rwsem.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28
29#ifndef _MACH_TEGRA_IOVMM_H_
30#define _MACH_TEGRA_IOVMM_H_
31
32typedef u32 tegra_iovmm_addr_t;
33
34struct tegra_iovmm_device_ops;
35
36/*
37 * each I/O virtual memory manager unit should register a device with
38 * the iovmm system
39 */
40struct tegra_iovmm_device {
41 struct tegra_iovmm_device_ops *ops;
42 const char *name;
43 struct list_head list;
44 int pgsize_bits;
45};
46
47/*
48 * tegra_iovmm_domain serves a purpose analagous to mm_struct as defined in
49 * <linux/mm_types.h> - it defines a virtual address space within which
50 * tegra_iovmm_areas can be created.
51 */
52struct tegra_iovmm_domain {
53 atomic_t clients;
54 atomic_t locks;
55 spinlock_t block_lock; /* RB-tree for iovmm_area blocks */
56 unsigned long flags;
57 wait_queue_head_t delay_lock; /* when lock_client fails */
58 struct rw_semaphore map_lock;
59 struct rb_root all_blocks; /* ordered by address */
60 struct rb_root free_blocks; /* ordered by size */
61 struct tegra_iovmm_device *dev;
62};
63
64/*
65 * tegra_iovmm_client is analagous to an individual task in the task group
66 * which owns an mm_struct.
67 */
68
69struct iovmm_share_group;
70
71struct tegra_iovmm_client {
72 const char *name;
73 unsigned long flags;
74 struct iovmm_share_group *group;
75 struct tegra_iovmm_domain *domain;
76 struct miscdevice *misc_dev;
77 struct list_head list;
78};
79
80/*
81 * tegra_iovmm_area serves a purpose analagous to vm_area_struct as defined
82 * in <linux/mm_types.h> - it defines a virtual memory area which can be
83 * mapped to physical memory by a client-provided mapping function. */
84
85struct tegra_iovmm_area {
86 struct tegra_iovmm_domain *domain;
87 tegra_iovmm_addr_t iovm_start;
88 size_t iovm_length;
89 pgprot_t pgprot;
90 struct tegra_iovmm_area_ops *ops;
91};
92
93struct tegra_iovmm_device_ops {
94 /* maps a VMA using the page residency functions provided by the VMA */
95 int (*map)(struct tegra_iovmm_domain *domain,
96 struct tegra_iovmm_area *io_vma);
97 /* marks all PTEs in a VMA as invalid; decommits the virtual addres
98 * space (potentially freeing PDEs when decommit is true.) */
99 void (*unmap)(struct tegra_iovmm_domain *domain,
100 struct tegra_iovmm_area *io_vma, bool decommit);
101 void (*map_pfn)(struct tegra_iovmm_domain *domain,
102 struct tegra_iovmm_area *io_vma,
103 unsigned long offs, unsigned long pfn);
104 /*
105 * ensures that a domain is resident in the hardware's mapping region
106 * so that it may be used by a client
107 */
108 int (*lock_domain)(struct tegra_iovmm_domain *domain,
109 struct tegra_iovmm_client *client);
110 void (*unlock_domain)(struct tegra_iovmm_domain *domain,
111 struct tegra_iovmm_client *client);
112 /*
113 * allocates a vmm_domain for the specified client; may return the same
114 * domain for multiple clients
115 */
116 struct tegra_iovmm_domain* (*alloc_domain)(
117 struct tegra_iovmm_device *dev,
118 struct tegra_iovmm_client *client);
119 void (*free_domain)(struct tegra_iovmm_domain *domain,
120 struct tegra_iovmm_client *client);
121 int (*suspend)(struct tegra_iovmm_device *dev);
122 void (*resume)(struct tegra_iovmm_device *dev);
123};
124
125struct tegra_iovmm_area_ops {
126 /*
127 * ensures that the page of data starting at the specified offset
128 * from the start of the iovma is resident and pinned for use by
129 * DMA, returns the system pfn, or an invalid pfn if the
130 * operation fails.
131 */
132 unsigned long (*lock_makeresident)(struct tegra_iovmm_area *area,
133 tegra_iovmm_addr_t offs);
134 /* called when the page is unmapped from the I/O VMA */
135 void (*release)(struct tegra_iovmm_area *area, tegra_iovmm_addr_t offs);
136};
137
138#ifdef CONFIG_TEGRA_IOVMM
139/*
140 * called by clients to allocate an I/O VMM client mapping context which
141 * will be shared by all clients in the same share_group
142 */
143struct tegra_iovmm_client *tegra_iovmm_alloc_client(const char *name,
144 const char *share_group, struct miscdevice *misc_dev);
145
146size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client);
147
148void tegra_iovmm_free_client(struct tegra_iovmm_client *client);
149
150/*
151 * called by clients to ensure that their mapping context is resident
152 * before performing any DMA operations addressing I/O VMM regions.
153 * client_lock may return -EINTR.
154 */
155int tegra_iovmm_client_lock(struct tegra_iovmm_client *client);
156int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client);
157
158/* called by clients after DMA operations are complete */
159void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client);
160
161/*
162 * called by clients to allocate a new iovmm_area and reserve I/O virtual
163 * address space for it. if ops is NULL, clients should subsequently call
164 * tegra_iovmm_vm_map_pages and/or tegra_iovmm_vm_insert_pfn to explicitly
165 * map the I/O virtual address to an OS-allocated page or physical address,
166 * respectively. VM operations may be called before this call returns
167 */
168struct tegra_iovmm_area *tegra_iovmm_create_vm(
169 struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops,
170 size_t size, size_t align, pgprot_t pgprot, unsigned long iovm_start);
171
172/*
173 * called by clients to "zap" an iovmm_area, and replace all mappings
174 * in it with invalid ones, without freeing the virtual address range
175 */
176void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm);
177
178/*
179 * after zapping a demand-loaded iovmm_area, the client should unzap it
180 * to allow the VMM device to remap the page range.
181 */
182void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm);
183
184/* called by clients to return an iovmm_area to the free pool for the domain */
185void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm);
186
187/* returns size of largest free iovm block */
188size_t tegra_iovmm_get_max_free(struct tegra_iovmm_client *client);
189
190/*
191 * called by client software to map the page-aligned I/O address vaddr to
192 * a specific physical address pfn. I/O VMA should have been created with
193 * a NULL tegra_iovmm_area_ops structure.
194 */
195void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area,
196 tegra_iovmm_addr_t vaddr, unsigned long pfn);
197
198/*
199 * called by clients to return the iovmm_area containing addr, or NULL if
200 * addr has not been allocated. caller should call tegra_iovmm_area_put when
201 * finished using the returned pointer
202 */
203struct tegra_iovmm_area *tegra_iovmm_find_area_get(
204 struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr);
205
206struct tegra_iovmm_area *tegra_iovmm_area_get(struct tegra_iovmm_area *vm);
207void tegra_iovmm_area_put(struct tegra_iovmm_area *vm);
208
209/* called by drivers to initialize a tegra_iovmm_domain structure */
210int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain,
211 struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start,
212 tegra_iovmm_addr_t end);
213
214/* called by drivers to register an I/O VMM device with the system */
215int tegra_iovmm_register(struct tegra_iovmm_device *dev);
216
217/* called by drivers to remove an I/O VMM device from the system */
218int tegra_iovmm_unregister(struct tegra_iovmm_device *dev);
219
220#else /* CONFIG_TEGRA_IOVMM */
221
222static inline struct tegra_iovmm_client *tegra_iovmm_alloc_client(
223 const char *name, const char *share_group, struct miscdevice *misc_dev)
224{
225 return NULL;
226}
227
228static inline size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client)
229{
230 return 0;
231}
232
233static inline void tegra_iovmm_free_client(struct tegra_iovmm_client *client)
234{
235}
236
237static inline int tegra_iovmm_client_lock(struct tegra_iovmm_client *client)
238{
239 return 0;
240}
241
242static inline int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client)
243{
244 return 0;
245}
246
247static inline void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client)
248{
249}
250
251static inline struct tegra_iovmm_area *tegra_iovmm_create_vm(
252 struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops,
253 size_t size, size_t align, pgprot_t pgprot, unsigned long iovm_start)
254{
255 return NULL;
256}
257
258static inline void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm)
259{
260}
261
262static inline void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm)
263{
264}
265
266static inline void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm)
267{
268}
269
270static inline size_t tegra_iovmm_get_max_free(struct tegra_iovmm_client *client)
271{
272 return 0;
273}
274
275static inline void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area,
276 tegra_iovmm_addr_t vaddr, unsigned long pfn)
277{
278}
279
280static inline struct tegra_iovmm_area *tegra_iovmm_find_area_get(
281 struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr)
282{
283 return NULL;
284}
285
286static inline struct tegra_iovmm_area *tegra_iovmm_area_get(
287 struct tegra_iovmm_area *vm)
288{
289 return NULL;
290}
291
292static inline void tegra_iovmm_area_put(struct tegra_iovmm_area *vm)
293{
294}
295
296static inline int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain,
297 struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start,
298 tegra_iovmm_addr_t end)
299{
300 return 0;
301}
302
303static inline int tegra_iovmm_register(struct tegra_iovmm_device *dev)
304{
305 return 0;
306}
307
308static inline int tegra_iovmm_unregister(struct tegra_iovmm_device *dev)
309{
310 return 0;
311}
312
313static inline int tegra_iovmm_suspend(void)
314{
315 return 0;
316}
317
318static inline void tegra_iovmm_resume(void)
319{
320}
321
322#endif /* CONFIG_TEGRA_IOVMM */
323#endif /* _MACH_TEGRA_IOVMM_H_*/
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
new file mode 100644
index 00000000000..bf1b12559be
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -0,0 +1,391 @@
1/*
2 * arch/arm/mach-tegra/include/mach/irqs.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 * Erik Gilling <konkers@google.com>
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#ifndef __MACH_TEGRA_IRQS_H
23#define __MACH_TEGRA_IRQS_H
24
25#define INT_GIC_BASE 0
26
27#define IRQ_LOCALTIMER 29
28
29#ifdef CONFIG_ARCH_TEGRA_2x_SOC
30/* Primary Interrupt Controller */
31#define INT_PRI_BASE (INT_GIC_BASE + 32)
32#define INT_TMR1 (INT_PRI_BASE + 0)
33#define INT_TMR2 (INT_PRI_BASE + 1)
34#define INT_RTC (INT_PRI_BASE + 2)
35#define INT_I2S2 (INT_PRI_BASE + 3)
36#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4)
37#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5)
38#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)
39#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7)
40#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8)
41#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9)
42#define INT_VDE_BSE_V (INT_PRI_BASE + 10)
43#define INT_VDE_BSE_A (INT_PRI_BASE + 11)
44#define INT_VDE_SXE (INT_PRI_BASE + 12)
45#define INT_I2S1 (INT_PRI_BASE + 13)
46#define INT_SDMMC1 (INT_PRI_BASE + 14)
47#define INT_SDMMC2 (INT_PRI_BASE + 15)
48#define INT_XIO (INT_PRI_BASE + 16)
49#define INT_VDE (INT_PRI_BASE + 17)
50#define INT_AVP_UCQ (INT_PRI_BASE + 18)
51#define INT_SDMMC3 (INT_PRI_BASE + 19)
52#define INT_USB (INT_PRI_BASE + 20)
53#define INT_USB2 (INT_PRI_BASE + 21)
54#define INT_PRI_RES_22 (INT_PRI_BASE + 22)
55#define INT_EIDE (INT_PRI_BASE + 23)
56#define INT_NANDFLASH (INT_PRI_BASE + 24)
57#define INT_VCP (INT_PRI_BASE + 25)
58#define INT_APB_DMA (INT_PRI_BASE + 26)
59#define INT_AHB_DMA (INT_PRI_BASE + 27)
60#define INT_GNT_0 (INT_PRI_BASE + 28)
61#define INT_GNT_1 (INT_PRI_BASE + 29)
62#define INT_OWR (INT_PRI_BASE + 30)
63#define INT_SDMMC4 (INT_PRI_BASE + 31)
64
65/* Secondary Interrupt Controller */
66#define INT_SEC_BASE (INT_PRI_BASE + 32)
67#define INT_GPIO1 (INT_SEC_BASE + 0)
68#define INT_GPIO2 (INT_SEC_BASE + 1)
69#define INT_GPIO3 (INT_SEC_BASE + 2)
70#define INT_GPIO4 (INT_SEC_BASE + 3)
71#define INT_UARTA (INT_SEC_BASE + 4)
72#define INT_UARTB (INT_SEC_BASE + 5)
73#define INT_I2C (INT_SEC_BASE + 6)
74#define INT_SPI (INT_SEC_BASE + 7)
75#define INT_TWC (INT_SEC_BASE + 8)
76#define INT_TMR3 (INT_SEC_BASE + 9)
77#define INT_TMR4 (INT_SEC_BASE + 10)
78#define INT_FLOW_RSM0 (INT_SEC_BASE + 11)
79#define INT_FLOW_RSM1 (INT_SEC_BASE + 12)
80#define INT_SPDIF (INT_SEC_BASE + 13)
81#define INT_UARTC (INT_SEC_BASE + 14)
82#define INT_MIPI (INT_SEC_BASE + 15)
83#define INT_EVENTA (INT_SEC_BASE + 16)
84#define INT_EVENTB (INT_SEC_BASE + 17)
85#define INT_EVENTC (INT_SEC_BASE + 18)
86#define INT_EVENTD (INT_SEC_BASE + 19)
87#define INT_VFIR (INT_SEC_BASE + 20)
88#define INT_DVC (INT_SEC_BASE + 21)
89#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
90#define INT_GPIO5 (INT_SEC_BASE + 23)
91#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24)
92#define INT_CPU1_PMU_INTR (INT_SEC_BASE + 25)
93#define INT_SEC_RES_26 (INT_SEC_BASE + 26)
94#define INT_SPI_1 (INT_SEC_BASE + 27)
95#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
96#define INT_AHB_DMA_COP (INT_SEC_BASE + 29)
97#define INT_DMA_TX (INT_SEC_BASE + 30)
98#define INT_DMA_RX (INT_SEC_BASE + 31)
99
100/* Tertiary Interrupt Controller */
101#define INT_TRI_BASE (INT_SEC_BASE + 32)
102#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0)
103#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1)
104#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2)
105#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3)
106#define INT_MPE_GENERAL (INT_TRI_BASE + 4)
107#define INT_VI_GENERAL (INT_TRI_BASE + 5)
108#define INT_EPP_GENERAL (INT_TRI_BASE + 6)
109#define INT_ISP_GENERAL (INT_TRI_BASE + 7)
110#define INT_2D_GENERAL (INT_TRI_BASE + 8)
111#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9)
112#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10)
113#define INT_HDMI (INT_TRI_BASE + 11)
114#define INT_TVO_GENERAL (INT_TRI_BASE + 12)
115#define INT_MC_GENERAL (INT_TRI_BASE + 13)
116#define INT_EMC_GENERAL (INT_TRI_BASE + 14)
117#define INT_TRI_RES_15 (INT_TRI_BASE + 15)
118#define INT_TRI_RES_16 (INT_TRI_BASE + 16)
119#define INT_AC97 (INT_TRI_BASE + 17)
120#define INT_SPI_2 (INT_TRI_BASE + 18)
121#define INT_SPI_3 (INT_TRI_BASE + 19)
122#define INT_I2C2 (INT_TRI_BASE + 20)
123#define INT_KBC (INT_TRI_BASE + 21)
124#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
125#define INT_GPIO6 (INT_TRI_BASE + 23)
126#define INT_TVDAC (INT_TRI_BASE + 24)
127#define INT_GPIO7 (INT_TRI_BASE + 25)
128#define INT_UARTD (INT_TRI_BASE + 26)
129#define INT_UARTE (INT_TRI_BASE + 27)
130#define INT_I2C3 (INT_TRI_BASE + 28)
131#define INT_SPI_4 (INT_TRI_BASE + 29)
132#define INT_TRI_RES_30 (INT_TRI_BASE + 30)
133#define INT_SW_RESERVED (INT_TRI_BASE + 31)
134
135/* Quaternary Interrupt Controller */
136#define INT_QUAD_BASE (INT_TRI_BASE + 32)
137#define INT_SNOR (INT_QUAD_BASE + 0)
138#define INT_USB3 (INT_QUAD_BASE + 1)
139#define INT_PCIE_INTR (INT_QUAD_BASE + 2)
140#define INT_PCIE_MSI (INT_QUAD_BASE + 3)
141#define INT_QUAD_RES_4 (INT_QUAD_BASE + 4)
142#define INT_QUAD_RES_5 (INT_QUAD_BASE + 5)
143#define INT_QUAD_RES_6 (INT_QUAD_BASE + 6)
144#define INT_QUAD_RES_7 (INT_QUAD_BASE + 7)
145#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8)
146#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9)
147#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10)
148#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11)
149#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12)
150#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13)
151#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14)
152#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15)
153#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16)
154#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17)
155#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18)
156#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19)
157#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20)
158#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21)
159#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22)
160#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23)
161#define INT_QUAD_RES_24 (INT_QUAD_BASE + 24)
162#define INT_QUAD_RES_25 (INT_QUAD_BASE + 25)
163#define INT_QUAD_RES_26 (INT_QUAD_BASE + 26)
164#define INT_QUAD_RES_27 (INT_QUAD_BASE + 27)
165#define INT_QUAD_RES_28 (INT_QUAD_BASE + 28)
166#define INT_QUAD_RES_29 (INT_QUAD_BASE + 29)
167#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
168#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
169
170#define INT_GIC_NR (INT_QUAD_BASE + 32)
171
172#define INT_MAIN_NR (INT_GIC_NR - INT_PRI_BASE)
173
174#define INT_SYNCPT_THRESH_BASE (INT_QUAD_BASE + 32)
175#define INT_SYNCPT_THRESH_NR 32
176
177#define INT_GPIO_BASE (INT_SYNCPT_THRESH_BASE + \
178 INT_SYNCPT_THRESH_NR)
179#define INT_GPIO_NR (28 * 8)
180
181#define INT_PCI_MSI_BASE (INT_GPIO_BASE + \
182 INT_GPIO_NR)
183#define INT_PCI_MSI_NR (0)
184
185#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
186
187/* Primary Interrupt Controller */
188#define INT_PRI_BASE (INT_GIC_BASE + 32)
189#define INT_TMR1 (INT_PRI_BASE + 0)
190#define INT_TMR2 (INT_PRI_BASE + 1)
191#define INT_RTC (INT_PRI_BASE + 2)
192#define INT_CEC (INT_PRI_BASE + 3)
193#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4)
194#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5)
195#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)
196#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7)
197#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8)
198#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9)
199#define INT_VDE_BSE_V (INT_PRI_BASE + 10)
200#define INT_VDE_BSE_A (INT_PRI_BASE + 11)
201#define INT_VDE_SXE (INT_PRI_BASE + 12)
202#define INT_SATA_RX_STAT (INT_PRI_BASE + 13)
203#define INT_SDMMC1 (INT_PRI_BASE + 14)
204#define INT_SDMMC2 (INT_PRI_BASE + 15)
205#define INT_XIO (INT_PRI_BASE + 16)
206#define INT_VDE (INT_PRI_BASE + 17)
207#define INT_AVP_UCQ (INT_PRI_BASE + 18)
208#define INT_SDMMC3 (INT_PRI_BASE + 19)
209#define INT_USB (INT_PRI_BASE + 20)
210#define INT_USB2 (INT_PRI_BASE + 21)
211#define INT_HSMMC (INT_PRI_BASE + 22)
212#define INT_SATA_CTL (INT_PRI_BASE + 23)
213#define INT_NANDFLASH (INT_PRI_BASE + 24)
214#define INT_VCP (INT_PRI_BASE + 25)
215#define INT_APB_DMA (INT_PRI_BASE + 26)
216#define INT_AHB_DMA (INT_PRI_BASE + 27)
217#define INT_GNT_0 (INT_PRI_BASE + 28)
218#define INT_GNT_1 (INT_PRI_BASE + 29)
219#define INT_OWR (INT_PRI_BASE + 30)
220#define INT_SDMMC4 (INT_PRI_BASE + 31)
221
222/* Secondary Interrupt Controller */
223#define INT_SEC_BASE (INT_PRI_BASE + 32)
224#define INT_GPIO1 (INT_SEC_BASE + 0)
225#define INT_GPIO2 (INT_SEC_BASE + 1)
226#define INT_GPIO3 (INT_SEC_BASE + 2)
227#define INT_GPIO4 (INT_SEC_BASE + 3)
228#define INT_UARTA (INT_SEC_BASE + 4)
229#define INT_UARTB (INT_SEC_BASE + 5)
230#define INT_I2C (INT_SEC_BASE + 6)
231#define INT_SPI (INT_SEC_BASE + 7)
232#define INT_DTV INT_SPI
233#define INT_TWC (INT_SEC_BASE + 8)
234#define INT_TMR3 (INT_SEC_BASE + 9)
235#define INT_TMR4 (INT_SEC_BASE + 10)
236#define INT_FLOW_RSM0 (INT_SEC_BASE + 11)
237#define INT_FLOW_RSM1 (INT_SEC_BASE + 12)
238#define INT_ACTMON (INT_SEC_BASE + 13)
239#define INT_UARTC (INT_SEC_BASE + 14)
240#define INT_MIPI (INT_SEC_BASE + 15)
241#define INT_EVENTA (INT_SEC_BASE + 16)
242#define INT_EVENTB (INT_SEC_BASE + 17)
243#define INT_EVENTC (INT_SEC_BASE + 18)
244#define INT_EVENTD (INT_SEC_BASE + 19)
245#define INT_VFIR (INT_SEC_BASE + 20)
246#define INT_I2C5 (INT_SEC_BASE + 21)
247#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
248#define INT_GPIO5 (INT_SEC_BASE + 23)
249#define INT_SPEEDO_PMON_0 (INT_SEC_BASE + 24)
250#define INT_SPEEDO_PMON_1 (INT_SEC_BASE + 25)
251#define INT_SE (INT_SEC_BASE + 26)
252#define INT_SPI_1 (INT_SEC_BASE + 27)
253#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
254#define INT_AHB_DMA_COP (INT_SEC_BASE + 29)
255#define INT_DMA_TX (INT_SEC_BASE + 30)
256#define INT_DMA_RX (INT_SEC_BASE + 31)
257
258/* Tertiary Interrupt Controller */
259#define INT_TRI_BASE (INT_SEC_BASE + 32)
260#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0)
261#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1)
262#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2)
263#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3)
264#define INT_MPE_GENERAL (INT_TRI_BASE + 4)
265#define INT_VI_GENERAL (INT_TRI_BASE + 5)
266#define INT_EPP_GENERAL (INT_TRI_BASE + 6)
267#define INT_ISP_GENERAL (INT_TRI_BASE + 7)
268#define INT_2D_GENERAL (INT_TRI_BASE + 8)
269#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9)
270#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10)
271#define INT_HDMI (INT_TRI_BASE + 11)
272#define INT_TVO_GENERAL (INT_TRI_BASE + 12)
273#define INT_MC_GENERAL (INT_TRI_BASE + 13)
274#define INT_EMC_GENERAL (INT_TRI_BASE + 14)
275#define INT_SPI_6 (INT_SEC_BASE + 15)
276#define INT_NOR_FLASH (INT_TRI_BASE + 16)
277#define INT_HDA (INT_TRI_BASE + 17)
278#define INT_SPI_2 (INT_TRI_BASE + 18)
279#define INT_SPI_3 (INT_TRI_BASE + 19)
280#define INT_I2C2 (INT_TRI_BASE + 20)
281#define INT_KBC (INT_TRI_BASE + 21)
282#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
283#define INT_GPIO6 (INT_TRI_BASE + 23)
284#define INT_TVDAC (INT_TRI_BASE + 24)
285#define INT_GPIO7 (INT_TRI_BASE + 25)
286#define INT_UARTD (INT_TRI_BASE + 26)
287#define INT_UARTE (INT_TRI_BASE + 27)
288#define INT_I2C3 (INT_TRI_BASE + 28)
289#define INT_SPI_4 (INT_TRI_BASE + 29)
290#define INT_SPI_5 (INT_TRI_BASE + 30)
291#define INT_SW_RESERVED (INT_TRI_BASE + 31)
292
293/* Quaternary Interrupt Controller */
294#define INT_QUAD_BASE (INT_TRI_BASE + 32)
295#define INT_SNOR (INT_QUAD_BASE + 0)
296#define INT_USB3 (INT_QUAD_BASE + 1)
297#define INT_PCIE_INTR (INT_QUAD_BASE + 2)
298#define INT_PCIE_MSI (INT_QUAD_BASE + 3)
299#define INT_PCIE (INT_QUAD_BASE + 4)
300#define INT_AVP_CACHE (INT_QUAD_BASE + 5)
301#define INT_TSENSOR (INT_QUAD_BASE + 6)
302#define INT_AUDIO_CLUSTER (INT_QUAD_BASE + 7)
303#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8)
304#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9)
305#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10)
306#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11)
307#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12)
308#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13)
309#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14)
310#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15)
311#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16)
312#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17)
313#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18)
314#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19)
315#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20)
316#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21)
317#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22)
318#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23)
319#define INT_I2C4 (INT_QUAD_BASE + 24)
320#define INT_TMR5 (INT_QUAD_BASE + 25)
321#define INT_TMR_SHARED (INT_QUAD_BASE + 26) /* Deprecated */
322#define INT_WDT_CPU (INT_QUAD_BASE + 27)
323#define INT_WDT_AVP (INT_QUAD_BASE + 28)
324#define INT_GPIO8 (INT_QUAD_BASE + 29)
325#define INT_CAR (INT_QUAD_BASE + 30)
326#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
327
328/* Quintary Interrupt Controller */
329#define INT_QUINT_BASE (INT_QUAD_BASE + 32)
330#define INT_APB_DMA_CH16 (INT_QUINT_BASE + 0)
331#define INT_APB_DMA_CH17 (INT_QUINT_BASE + 1)
332#define INT_APB_DMA_CH18 (INT_QUINT_BASE + 2)
333#define INT_APB_DMA_CH19 (INT_QUINT_BASE + 3)
334#define INT_APB_DMA_CH20 (INT_QUINT_BASE + 4)
335#define INT_APB_DMA_CH21 (INT_QUINT_BASE + 5)
336#define INT_APB_DMA_CH22 (INT_QUINT_BASE + 6)
337#define INT_APB_DMA_CH23 (INT_QUINT_BASE + 7)
338#define INT_APB_DMA_CH24 (INT_QUINT_BASE + 8)
339#define INT_APB_DMA_CH25 (INT_QUINT_BASE + 9)
340#define INT_APB_DMA_CH26 (INT_QUINT_BASE + 10)
341#define INT_APB_DMA_CH27 (INT_QUINT_BASE + 11)
342#define INT_APB_DMA_CH28 (INT_QUINT_BASE + 12)
343#define INT_APB_DMA_CH29 (INT_QUINT_BASE + 13)
344#define INT_APB_DMA_CH30 (INT_QUINT_BASE + 14)
345#define INT_APB_DMA_CH31 (INT_QUINT_BASE + 15)
346#define INT_CPU0_PMU_INTR (INT_QUINT_BASE + 16)
347#define INT_CPU1_PMU_INTR (INT_QUINT_BASE + 17)
348#define INT_CPU2_PMU_INTR (INT_QUINT_BASE + 18)
349#define INT_CPU3_PMU_INTR (INT_QUINT_BASE + 19)
350#define INT_CPU4_PMU_INTR (INT_QUINT_BASE + 20)
351#define INT_CPU5_PMU_INTR (INT_QUINT_BASE + 21)
352#define INT_CPU6_PMU_INTR (INT_QUINT_BASE + 22)
353#define INT_CPU7_PMU_INTR (INT_QUINT_BASE + 23)
354#define INT_TMR6 (INT_QUINT_BASE + 24)
355#define INT_TMR7 (INT_QUINT_BASE + 25)
356#define INT_TMR8 (INT_QUINT_BASE + 26)
357#define INT_TMR9 (INT_QUINT_BASE + 27)
358#define INT_TMR10 (INT_QUINT_BASE + 28)
359#define INT_QUINT_RES_29 (INT_QUINT_BASE + 29)
360#define INT_QUINT_RES_30 (INT_QUINT_BASE + 30)
361#define INT_QUINT_RES_31 (INT_QUINT_BASE + 31)
362
363#define INT_GIC_NR (INT_QUINT_BASE + 32)
364
365#define INT_MAIN_NR (INT_GIC_NR - INT_PRI_BASE)
366
367#define INT_SYNCPT_THRESH_BASE (INT_QUINT_BASE + 32)
368#define INT_SYNCPT_THRESH_NR 32
369
370#define INT_GPIO_BASE (INT_SYNCPT_THRESH_BASE + \
371 INT_SYNCPT_THRESH_NR)
372#define INT_GPIO_NR (32 * 8)
373
374#define INT_PCI_MSI_BASE (INT_GPIO_BASE + \
375 INT_GPIO_NR)
376#define INT_PCI_MSI_NR (32 * 8)
377
378#endif
379
380#define FIQ_START INT_GIC_BASE
381
382#define TEGRA_NR_IRQS (INT_PCI_MSI_BASE + \
383 INT_PCI_MSI_NR)
384
385#define INT_BOARD_BASE TEGRA_NR_IRQS
386
387#define NR_BOARD_IRQS 64
388
389#define NR_IRQS (INT_BOARD_BASE + NR_BOARD_IRQS)
390
391#endif
diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h
new file mode 100644
index 00000000000..7b68baa04f1
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/kbc.h
@@ -0,0 +1,86 @@
1/*
2 * Platform definitions for tegra-kbc keyboard input driver
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef ASMARM_ARCH_TEGRA_KBC_H
22#define ASMARM_ARCH_TEGRA_KBC_H
23
24#include <linux/types.h>
25#include <linux/input/matrix_keypad.h>
26
27#define KBC_MAX_GPIO 24
28#define KBC_MAX_KPENT 8
29
30#define KBC_MAX_ROW 16
31#define KBC_MAX_COL 8
32#define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL)
33
34#define KBC_PIN_GPIO_0 0
35#define KBC_PIN_GPIO_1 1
36#define KBC_PIN_GPIO_2 2
37#define KBC_PIN_GPIO_3 3
38#define KBC_PIN_GPIO_4 4
39#define KBC_PIN_GPIO_5 5
40#define KBC_PIN_GPIO_6 6
41#define KBC_PIN_GPIO_7 7
42#define KBC_PIN_GPIO_8 8
43#define KBC_PIN_GPIO_9 9
44#define KBC_PIN_GPIO_10 10
45#define KBC_PIN_GPIO_11 11
46#define KBC_PIN_GPIO_12 12
47#define KBC_PIN_GPIO_13 13
48#define KBC_PIN_GPIO_14 14
49#define KBC_PIN_GPIO_15 15
50#define KBC_PIN_GPIO_16 16
51#define KBC_PIN_GPIO_17 17
52#define KBC_PIN_GPIO_18 18
53#define KBC_PIN_GPIO_19 19
54#define KBC_PIN_GPIO_20 20
55#define KBC_PIN_GPIO_21 21
56#define KBC_PIN_GPIO_22 22
57#define KBC_PIN_GPIO_23 23
58
59struct tegra_kbc_pin_cfg {
60 bool is_row;
61 bool en;
62 unsigned char num;
63};
64
65struct tegra_kbc_wake_key {
66 u8 row:4;
67 u8 col:4;
68};
69
70struct tegra_kbc_platform_data {
71 unsigned int debounce_cnt;
72 unsigned int repeat_cnt;
73 unsigned int scan_count;
74
75 unsigned int wake_cnt; /* 0:wake on any key >1:wake on wake_cfg */
76 const struct tegra_kbc_wake_key *wake_cfg;
77
78 struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
79 const struct matrix_keymap_data *keymap_data;
80
81 bool wakeup;
82 bool use_fn_map;
83 bool use_ghost_filter;
84 bool disable_ev_rep;
85};
86#endif
diff --git a/arch/arm/mach-tegra/include/mach/kfuse.h b/arch/arm/mach-tegra/include/mach/kfuse.h
new file mode 100644
index 00000000000..cfe85cc86ff
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/kfuse.h
@@ -0,0 +1,20 @@
1/*
2 * arch/arm/mach-tegra/kfuse.h
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/* there are 144 32-bit values in total */
18#define KFUSE_DATA_SZ (144 * 4)
19
20int tegra_kfuse_read(void *dest, size_t len);
diff --git a/arch/arm/mach-tegra/include/mach/latency_allowance.h b/arch/arm/mach-tegra/include/mach/latency_allowance.h
new file mode 100644
index 00000000000..f0d27f0b8ba
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/latency_allowance.h
@@ -0,0 +1,121 @@
1/*
2 * arch/arm/mach-tegra/include/mach/latency_allowance.h
3 *
4 * Copyright (C) 2011, NVIDIA Corporation.
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_LATENCY_ALLOWANCE_H_
18#define _MACH_TEGRA_LATENCY_ALLOWANCE_H_
19
20enum tegra_la_id {
21 TEGRA_LA_AFIR = 0,
22 TEGRA_LA_AFIW,
23 TEGRA_LA_AVPC_ARM7R,
24 TEGRA_LA_AVPC_ARM7W,
25 TEGRA_LA_DISPLAY_0A,
26 TEGRA_LA_DISPLAY_0B,
27 TEGRA_LA_DISPLAY_0C,
28 TEGRA_LA_DISPLAY_1B,
29 TEGRA_LA_DISPLAY_HC,
30 TEGRA_LA_DISPLAY_0AB,
31 TEGRA_LA_DISPLAY_0BB,
32 TEGRA_LA_DISPLAY_0CB,
33 TEGRA_LA_DISPLAY_1BB,
34 TEGRA_LA_DISPLAY_HCB,
35 TEGRA_LA_EPPUP,
36 TEGRA_LA_EPPU,
37 TEGRA_LA_EPPV,
38 TEGRA_LA_EPPY,
39 TEGRA_LA_G2PR,
40 TEGRA_LA_G2SR,
41 TEGRA_LA_G2DR,
42 TEGRA_LA_G2DW,
43 TEGRA_LA_HOST1X_DMAR,
44 TEGRA_LA_HOST1XR,
45 TEGRA_LA_HOST1XW,
46 TEGRA_LA_HDAR,
47 TEGRA_LA_HDAW,
48 TEGRA_LA_ISPW,
49 TEGRA_LA_MPCORER,
50 TEGRA_LA_MPCOREW,
51 TEGRA_LA_MPCORE_LPR,
52 TEGRA_LA_MPCORE_LPW,
53 TEGRA_LA_MPE_UNIFBR,
54 TEGRA_LA_MPE_IPRED,
55 TEGRA_LA_MPE_AMEMRD,
56 TEGRA_LA_MPE_CSRD,
57 TEGRA_LA_MPE_UNIFBW,
58 TEGRA_LA_MPE_CSWR,
59 TEGRA_LA_FDCDRD,
60 TEGRA_LA_IDXSRD,
61 TEGRA_LA_TEXSRD,
62 TEGRA_LA_FDCDWR,
63 TEGRA_LA_FDCDRD2,
64 TEGRA_LA_IDXSRD2,
65 TEGRA_LA_TEXSRD2,
66 TEGRA_LA_FDCDWR2,
67 TEGRA_LA_PPCS_AHBDMAR,
68 TEGRA_LA_PPCS_AHBSLVR,
69 TEGRA_LA_PPCS_AHBDMAW,
70 TEGRA_LA_PPCS_AHBSLVW,
71 TEGRA_LA_PTCR,
72 TEGRA_LA_SATAR,
73 TEGRA_LA_SATAW,
74 TEGRA_LA_VDE_BSEVR,
75 TEGRA_LA_VDE_MBER,
76 TEGRA_LA_VDE_MCER,
77 TEGRA_LA_VDE_TPER,
78 TEGRA_LA_VDE_BSEVW,
79 TEGRA_LA_VDE_DBGW,
80 TEGRA_LA_VDE_MBEW,
81 TEGRA_LA_VDE_TPMW,
82 TEGRA_LA_VI_RUV,
83 TEGRA_LA_VI_WSB,
84 TEGRA_LA_VI_WU,
85 TEGRA_LA_VI_WV,
86 TEGRA_LA_VI_WY,
87 TEGRA_LA_MAX_ID
88};
89
90#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_TEGRA_FPGA_PLATFORM)
91static inline int tegra_set_latency_allowance(enum tegra_la_id id,
92 int bandwidth_in_mbps)
93{
94 return 0;
95}
96
97static inline int tegra_enable_latency_scaling(enum tegra_la_id id,
98 unsigned int threshold_low,
99 unsigned int threshold_mid,
100 unsigned int threshold_high)
101{
102 return 0;
103}
104
105static inline void tegra_disable_latency_scaling(enum tegra_la_id id)
106{
107 return 0;
108}
109#else
110int tegra_set_latency_allowance(enum tegra_la_id id,
111 unsigned int bandwidth_in_mbps);
112
113int tegra_enable_latency_scaling(enum tegra_la_id id,
114 unsigned int threshold_low,
115 unsigned int threshold_mid,
116 unsigned int threshold_high);
117
118void tegra_disable_latency_scaling(enum tegra_la_id id);
119#endif
120
121#endif /* _MACH_TEGRA_LATENCY_ALLOWANCE_H_ */
diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h
new file mode 100644
index 00000000000..86f1ff7d06b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/legacy_irq.h
@@ -0,0 +1,23 @@
1/*
2 * arch/arm/mach-tegra/include/mach/legacy_irq.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Author: Colin Cross <ccross@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H
19#define _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H
20
21void tegra_init_legacy_irq_cop(void);
22
23#endif
diff --git a/arch/arm/mach-tegra/include/mach/mc.h b/arch/arm/mach-tegra/include/mach/mc.h
new file mode 100644
index 00000000000..576153ad08d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/mc.h
@@ -0,0 +1,109 @@
1/*
2 * arch/arm/mach-tegra/include/mach/mc.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_MC_H
21#define __MACH_TEGRA_MC_H
22
23#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
24#define TEGRA_MC_FPRI_CTRL_AVPC 0x17c
25#define TEGRA_MC_FPRI_CTRL_DC 0x180
26#define TEGRA_MC_FPRI_CTRL_DCB 0x184
27#define TEGRA_MC_FPRI_CTRL_EPP 0x188
28#define TEGRA_MC_FPRI_CTRL_G2 0x18c
29#define TEGRA_MC_FPRI_CTRL_HC 0x190
30#define TEGRA_MC_FPRI_CTRL_ISP 0x194
31#define TEGRA_MC_FPRI_CTRL_MPCORE 0x198
32#define TEGRA_MC_FPRI_CTRL_MPEA 0x19c
33#define TEGRA_MC_FPRI_CTRL_MPEB 0x1a0
34#define TEGRA_MC_FPRI_CTRL_MPEC 0x1a4
35#define TEGRA_MC_FPRI_CTRL_NV 0x1a8
36#define TEGRA_MC_FPRI_CTRL_PPCS 0x1ac
37#define TEGRA_MC_FPRI_CTRL_VDE 0x1b0
38#define TEGRA_MC_FPRI_CTRL_VI 0x1b4
39
40#define TEGRA_MC_CLIENT_AVPCARM7R ((TEGRA_MC_FPRI_CTRL_AVPC << 8) | 0)
41#define TEGRA_MC_CLIENT_AVPCARM7W ((TEGRA_MC_FPRI_CTRL_AVPC << 8) | 2)
42#define TEGRA_MC_CLIENT_DISPLAY0A ((TEGRA_MC_FPRI_CTRL_DC << 8) | 0)
43#define TEGRA_MC_CLIENT_DISPLAY0B ((TEGRA_MC_FPRI_CTRL_DC << 8) | 2)
44#define TEGRA_MC_CLIENT_DISPLAY0C ((TEGRA_MC_FPRI_CTRL_DC << 8) | 4)
45#define TEGRA_MC_CLIENT_DISPLAY1B ((TEGRA_MC_FPRI_CTRL_DC << 8) | 6)
46#define TEGRA_MC_CLIENT_DISPLAYHC ((TEGRA_MC_FPRI_CTRL_DC << 8) | 8)
47#define TEGRA_MC_CLIENT_DISPLAY0AB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 0)
48#define TEGRA_MC_CLIENT_DISPLAY0BB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 2)
49#define TEGRA_MC_CLIENT_DISPLAY0CB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 4)
50#define TEGRA_MC_CLIENT_DISPLAY1BB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 6)
51#define TEGRA_MC_CLIENT_DISPLAYHCB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 8)
52#define TEGRA_MC_CLIENT_EPPUP ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 0)
53#define TEGRA_MC_CLIENT_EPPU ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 2)
54#define TEGRA_MC_CLIENT_EPPV ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 4)
55#define TEGRA_MC_CLIENT_EPPY ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 6)
56#define TEGRA_MC_CLIENT_G2PR ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 0)
57#define TEGRA_MC_CLIENT_G2SR ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 2)
58#define TEGRA_MC_CLIENT_G2DR ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 4)
59#define TEGRA_MC_CLIENT_G2DW ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 6)
60#define TEGRA_MC_CLIENT_HOST1XDMAR ((TEGRA_MC_FPRI_CTRL_HC << 8) | 0)
61#define TEGRA_MC_CLIENT_HOST1XR ((TEGRA_MC_FPRI_CTRL_HC << 8) | 2)
62#define TEGRA_MC_CLIENT_HOST1XW ((TEGRA_MC_FPRI_CTRL_HC << 8) | 4)
63#define TEGRA_MC_CLIENT_ISPW ((TEGRA_MC_FPRI_CTRL_ISP << 8) | 0)
64#define TEGRA_MC_CLIENT_MPCORER ((TEGRA_MC_FPRI_CTRL_MPCORE << 8) | 0)
65#define TEGRA_MC_CLIENT_MPCOREW ((TEGRA_MC_FPRI_CTRL_MPCORE << 8) | 2)
66#define TEGRA_MC_CLIENT_MPEAMEMRD ((TEGRA_MC_FPRI_CTRL_MPEA << 8) | 0)
67#define TEGRA_MC_CLIENT_MPEUNIFBR ((TEGRA_MC_FPRI_CTRL_MPEB << 8) | 0)
68#define TEGRA_MC_CLIENT_MPE_IPRED ((TEGRA_MC_FPRI_CTRL_MPEB << 8) | 2)
69#define TEGRA_MC_CLIENT_MPEUNIFBW ((TEGRA_MC_FPRI_CTRL_MPEB << 8) | 4)
70#define TEGRA_MC_CLIENT_MPECSRD ((TEGRA_MC_FPRI_CTRL_MPEC << 8) | 0)
71#define TEGRA_MC_CLIENT_MPECSWR ((TEGRA_MC_FPRI_CTRL_MPEC << 8) | 2)
72#define TEGRA_MC_CLIENT_FDCDRD ((TEGRA_MC_FPRI_CTRL_NV << 8) | 0)
73#define TEGRA_MC_CLIENT_IDXSRD ((TEGRA_MC_FPRI_CTRL_NV << 8) | 2)
74#define TEGRA_MC_CLIENT_TEXSRD ((TEGRA_MC_FPRI_CTRL_NV << 8) | 4)
75#define TEGRA_MC_CLIENT_FDCDWR ((TEGRA_MC_FPRI_CTRL_NV << 8) | 6)
76#define TEGRA_MC_CLIENT_PPCSAHBDMAR ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 0)
77#define TEGRA_MC_CLIENT_PPCSAHBSLVR ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 2)
78#define TEGRA_MC_CLIENT_PPCSAHBDMAW ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 4)
79#define TEGRA_MC_CLIENT_PPCSAHBSLVW ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 6)
80#define TEGRA_MC_CLIENT_VDEBSEVR ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 0)
81#define TEGRA_MC_CLIENT_VDEMBER ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 2)
82#define TEGRA_MC_CLIENT_VDEMCER ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 4)
83#define TEGRA_MC_CLIENT_VDETPER ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 6)
84#define TEGRA_MC_CLIENT_VDEBSEVW ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 8)
85#define TEGRA_MC_CLIENT_VDEMBEW ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 10)
86#define TEGRA_MC_CLIENT_VDETPMW ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 12)
87#define TEGRA_MC_CLIENT_VIRUV ((TEGRA_MC_FPRI_CTRL_VI << 8) | 0)
88#define TEGRA_MC_CLIENT_VIWSB ((TEGRA_MC_FPRI_CTRL_VI << 8) | 2)
89#define TEGRA_MC_CLIENT_VIWU ((TEGRA_MC_FPRI_CTRL_VI << 8) | 4)
90#define TEGRA_MC_CLIENT_VIWV ((TEGRA_MC_FPRI_CTRL_VI << 8) | 6)
91#define TEGRA_MC_CLIENT_VIWY ((TEGRA_MC_FPRI_CTRL_VI << 8) | 8)
92
93#define TEGRA_MC_PRIO_LOWEST 0
94#define TEGRA_MC_PRIO_LOW 1
95#define TEGRA_MC_PRIO_MED 2
96#define TEGRA_MC_PRIO_HIGH 3
97#define TEGRA_MC_PRIO_MASK 3
98
99void tegra_mc_set_priority(unsigned long client, unsigned long prio);
100
101#else
102 /* !!!FIXME!!! IMPLEMENT ME */
103#define tegra_mc_set_priority(client, prio) \
104 do { /* nothing for now */ } while (0)
105#endif
106
107int tegra_mc_get_tiled_memory_bandwidth_multiplier(void);
108
109#endif
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
new file mode 100644
index 00000000000..5f51066482e
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -0,0 +1,42 @@
1/*
2 * arch/arm/mach-tegra/include/mach/memory.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 * Erik Gilling <konkers@google.com>
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#ifndef __MACH_TEGRA_MEMORY_H
23#define __MACH_TEGRA_MEMORY_H
24
25/* physical offset of RAM */
26#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
27#define PLAT_PHYS_OFFSET UL(0)
28#else
29#define PLAT_PHYS_OFFSET UL(0x80000000)
30#endif
31
32/*
33 * Unaligned DMA causes tegra dma to place data on 4-byte boundary after
34 * expected address. Call to skb_reserve(skb, NET_IP_ALIGN) was causing skb
35 * buffers in usbnet.c to become unaligned.
36 */
37#define NET_IP_ALIGN 0
38
39#define CONSISTENT_DMA_SIZE (14 * SZ_1M)
40
41#endif
42
diff --git a/arch/arm/mach-tegra/include/mach/nand.h b/arch/arm/mach-tegra/include/mach/nand.h
new file mode 100644
index 00000000000..91ad7d1c9ae
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/nand.h
@@ -0,0 +1,55 @@
1/*
2 * arch/arm/mach-tegra/include/mach/nand.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Dima Zavin <dmitriyz@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_NAND_H
22#define __MACH_TEGRA_NAND_H
23
24struct tegra_nand_chip_parms {
25 uint8_t vendor_id;
26 uint8_t device_id;
27 uint32_t flags;
28 uint8_t read_id_fourth_byte;
29 uint32_t capacity;
30
31 /* all timing info is in nanoseconds */
32 struct {
33 uint32_t trp;
34 uint32_t trh;
35 uint32_t twp;
36 uint32_t twh;
37 uint32_t tcs;
38 uint32_t twhr;
39 uint32_t tcr_tar_trr;
40 uint32_t twb;
41 uint32_t trp_resp;
42 uint32_t tadl;
43 } timing;
44};
45
46struct tegra_nand_platform {
47 uint8_t max_chips;
48 struct tegra_nand_chip_parms *chip_parms;
49 unsigned int nr_chip_parms;
50 struct mtd_partition *parts;
51 unsigned int nr_parts;
52 int wp_gpio;
53};
54
55#endif
diff --git a/arch/arm/mach-tegra/include/mach/nvmap.h b/arch/arm/mach-tegra/include/mach/nvmap.h
new file mode 100644
index 00000000000..88f913fc29d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/nvmap.h
@@ -0,0 +1,158 @@
1/*
2 * arch/arm/mach-tegra/include/mach/nvmap.h
3 *
4 * structure declarations for nvmem and nvmap user-space ioctls
5 *
6 * Copyright (c) 2009-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/ioctl.h>
24#include <linux/file.h>
25#include <linux/rbtree.h>
26
27#if !defined(__KERNEL__)
28#define __user
29#endif
30
31#ifndef __NVMAP_H
32#define __NVMAP_H
33
34#define NVMAP_HEAP_SYSMEM (1ul<<31)
35#define NVMAP_HEAP_IOVMM (1ul<<30)
36
37/* common carveout heaps */
38#define NVMAP_HEAP_CARVEOUT_IRAM (1ul<<29)
39#define NVMAP_HEAP_CARVEOUT_VPR (1ul<<28)
40#define NVMAP_HEAP_CARVEOUT_GENERIC (1ul<<0)
41
42#define NVMAP_HEAP_CARVEOUT_MASK (NVMAP_HEAP_IOVMM - 1)
43
44/* allocation flags */
45#define NVMAP_HANDLE_UNCACHEABLE (0x0ul << 0)
46#define NVMAP_HANDLE_WRITE_COMBINE (0x1ul << 0)
47#define NVMAP_HANDLE_INNER_CACHEABLE (0x2ul << 0)
48#define NVMAP_HANDLE_CACHEABLE (0x3ul << 0)
49#define NVMAP_HANDLE_CACHE_FLAG (0x3ul << 0)
50
51#define NVMAP_HANDLE_SECURE (0x1ul << 2)
52
53
54#if defined(__KERNEL__)
55
56#if defined(CONFIG_TEGRA_NVMAP)
57struct nvmap_handle;
58struct nvmap_client;
59struct nvmap_device;
60#define nvmap_ref_to_handle(_ref) (*(struct nvmap_handle **)(_ref))
61/* Convert User space handle to Kernel. */
62#define nvmap_convert_handle_u2k(h) (h)
63#elif defined(CONFIG_ION_TEGRA)
64/* For Ion Mem Manager support through nvmap_* API's. */
65#include "../../../../../drivers/gpu/ion/ion_priv.h"
66
67#define nvmap_client ion_client
68#define nvmap_device ion_device
69#define nvmap_handle ion_handle
70#define nvmap_handle_ref ion_handle
71#define nvmap_ref_to_handle(_ref) (struct ion_handle *)_ref
72/* Convert User space handle to Kernel. */
73#define nvmap_convert_handle_u2k(h) ({ \
74 if ((u32)h >= TASK_SIZE) { \
75 pr_err("Invalid user space handle."); \
76 BUG(); \
77 } \
78 (*((u32 *)h)); })
79#endif
80
81#define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id))
82
83
84struct nvmap_pinarray_elem {
85 __u32 patch_mem;
86 __u32 patch_offset;
87 __u32 pin_mem;
88 __u32 pin_offset;
89 __u32 reloc_shift;
90};
91
92#if defined(CONFIG_TEGRA_NVMAP)
93/* handle_ref objects are client-local references to an nvmap_handle;
94 * they are distinct objects so that handles can be unpinned and
95 * unreferenced the correct number of times when a client abnormally
96 * terminates */
97struct nvmap_handle_ref {
98 struct nvmap_handle *handle;
99 struct rb_node node;
100 atomic_t dupes; /* number of times to free on file close */
101 atomic_t pin; /* number of times to unpin on free */
102};
103#endif
104
105struct nvmap_client *nvmap_create_client(struct nvmap_device *dev,
106 const char *name);
107
108struct nvmap_handle_ref *nvmap_alloc(struct nvmap_client *client, size_t size,
109 size_t align, unsigned int flags,
110 unsigned int heap_mask);
111
112void nvmap_free(struct nvmap_client *client, struct nvmap_handle_ref *r);
113
114void *nvmap_mmap(struct nvmap_handle_ref *r);
115
116void nvmap_munmap(struct nvmap_handle_ref *r, void *addr);
117
118struct nvmap_client *nvmap_client_get_file(int fd);
119
120struct nvmap_client *nvmap_client_get(struct nvmap_client *client);
121
122void nvmap_client_put(struct nvmap_client *c);
123
124phys_addr_t nvmap_pin(struct nvmap_client *c, struct nvmap_handle_ref *r);
125
126phys_addr_t nvmap_handle_address(struct nvmap_client *c, unsigned long id);
127
128void nvmap_unpin(struct nvmap_client *client, struct nvmap_handle_ref *r);
129
130int nvmap_pin_array(struct nvmap_client *client, struct nvmap_handle *gather,
131 const struct nvmap_pinarray_elem *arr, int nr,
132 struct nvmap_handle **unique);
133
134void nvmap_unpin_handles(struct nvmap_client *client,
135 struct nvmap_handle **h, int nr);
136
137int nvmap_patch_word(struct nvmap_client *client,
138 struct nvmap_handle *patch,
139 u32 patch_offset, u32 patch_value);
140
141struct nvmap_platform_carveout {
142 const char *name;
143 unsigned int usage_mask;
144 phys_addr_t base;
145 size_t size;
146 size_t buddy_size;
147};
148
149struct nvmap_platform_data {
150 const struct nvmap_platform_carveout *carveouts;
151 unsigned int nr_carveouts;
152};
153
154extern struct nvmap_device *nvmap_dev;
155
156#endif
157
158#endif
diff --git a/arch/arm/mach-tegra/include/mach/pci.h b/arch/arm/mach-tegra/include/mach/pci.h
new file mode 100644
index 00000000000..388ad320775
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pci.h
@@ -0,0 +1,38 @@
1/*
2 * arch/arm/mach-tegra/include/mach/pci.h
3 *
4 * Header file containing constants for the tegra PCIe driver.
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
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, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#ifndef __MACH_PCI_H
23#define __MACH_PCI_H
24
25#include <linux/pci.h>
26
27#ifdef CONFIG_ARCH_TEGRA_2x_SOC
28 #define MAX_PCIE_SUPPORTED_PORTS 2
29#else
30 #define MAX_PCIE_SUPPORTED_PORTS 3
31#endif
32
33struct tegra_pci_platform_data {
34 int port_status[MAX_PCIE_SUPPORTED_PORTS];
35 bool use_dock_detect;
36 int gpio;
37};
38#endif
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t2.h b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
new file mode 100644
index 00000000000..4c262634726
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
@@ -0,0 +1,184 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux-t2.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_T2_H
18#define __MACH_TEGRA_PINMUX_T2_H
19
20enum tegra_pingroup {
21 TEGRA_PINGROUP_ATA = 0,
22 TEGRA_PINGROUP_ATB,
23 TEGRA_PINGROUP_ATC,
24 TEGRA_PINGROUP_ATD,
25 TEGRA_PINGROUP_ATE,
26 TEGRA_PINGROUP_CDEV1,
27 TEGRA_PINGROUP_CDEV2,
28 TEGRA_PINGROUP_CRTP,
29 TEGRA_PINGROUP_CSUS,
30 TEGRA_PINGROUP_DAP1,
31 TEGRA_PINGROUP_DAP2,
32 TEGRA_PINGROUP_DAP3,
33 TEGRA_PINGROUP_DAP4,
34 TEGRA_PINGROUP_DDC,
35 TEGRA_PINGROUP_DTA,
36 TEGRA_PINGROUP_DTB,
37 TEGRA_PINGROUP_DTC,
38 TEGRA_PINGROUP_DTD,
39 TEGRA_PINGROUP_DTE,
40 TEGRA_PINGROUP_DTF,
41 TEGRA_PINGROUP_GMA,
42 TEGRA_PINGROUP_GMB,
43 TEGRA_PINGROUP_GMC,
44 TEGRA_PINGROUP_GMD,
45 TEGRA_PINGROUP_GME,
46 TEGRA_PINGROUP_GPU,
47 TEGRA_PINGROUP_GPU7,
48 TEGRA_PINGROUP_GPV,
49 TEGRA_PINGROUP_HDINT,
50 TEGRA_PINGROUP_I2CP,
51 TEGRA_PINGROUP_IRRX,
52 TEGRA_PINGROUP_IRTX,
53 TEGRA_PINGROUP_KBCA,
54 TEGRA_PINGROUP_KBCB,
55 TEGRA_PINGROUP_KBCC,
56 TEGRA_PINGROUP_KBCD,
57 TEGRA_PINGROUP_KBCE,
58 TEGRA_PINGROUP_KBCF,
59 TEGRA_PINGROUP_LCSN,
60 TEGRA_PINGROUP_LD0,
61 TEGRA_PINGROUP_LD1,
62 TEGRA_PINGROUP_LD10,
63 TEGRA_PINGROUP_LD11,
64 TEGRA_PINGROUP_LD12,
65 TEGRA_PINGROUP_LD13,
66 TEGRA_PINGROUP_LD14,
67 TEGRA_PINGROUP_LD15,
68 TEGRA_PINGROUP_LD16,
69 TEGRA_PINGROUP_LD17,
70 TEGRA_PINGROUP_LD2,
71 TEGRA_PINGROUP_LD3,
72 TEGRA_PINGROUP_LD4,
73 TEGRA_PINGROUP_LD5,
74 TEGRA_PINGROUP_LD6,
75 TEGRA_PINGROUP_LD7,
76 TEGRA_PINGROUP_LD8,
77 TEGRA_PINGROUP_LD9,
78 TEGRA_PINGROUP_LDC,
79 TEGRA_PINGROUP_LDI,
80 TEGRA_PINGROUP_LHP0,
81 TEGRA_PINGROUP_LHP1,
82 TEGRA_PINGROUP_LHP2,
83 TEGRA_PINGROUP_LHS,
84 TEGRA_PINGROUP_LM0,
85 TEGRA_PINGROUP_LM1,
86 TEGRA_PINGROUP_LPP,
87 TEGRA_PINGROUP_LPW0,
88 TEGRA_PINGROUP_LPW1,
89 TEGRA_PINGROUP_LPW2,
90 TEGRA_PINGROUP_LSC0,
91 TEGRA_PINGROUP_LSC1,
92 TEGRA_PINGROUP_LSCK,
93 TEGRA_PINGROUP_LSDA,
94 TEGRA_PINGROUP_LSDI,
95 TEGRA_PINGROUP_LSPI,
96 TEGRA_PINGROUP_LVP0,
97 TEGRA_PINGROUP_LVP1,
98 TEGRA_PINGROUP_LVS,
99 TEGRA_PINGROUP_OWC,
100 TEGRA_PINGROUP_PMC,
101 TEGRA_PINGROUP_PTA,
102 TEGRA_PINGROUP_RM,
103 TEGRA_PINGROUP_SDB,
104 TEGRA_PINGROUP_SDC,
105 TEGRA_PINGROUP_SDD,
106 TEGRA_PINGROUP_SDIO1,
107 TEGRA_PINGROUP_SLXA,
108 TEGRA_PINGROUP_SLXC,
109 TEGRA_PINGROUP_SLXD,
110 TEGRA_PINGROUP_SLXK,
111 TEGRA_PINGROUP_SPDI,
112 TEGRA_PINGROUP_SPDO,
113 TEGRA_PINGROUP_SPIA,
114 TEGRA_PINGROUP_SPIB,
115 TEGRA_PINGROUP_SPIC,
116 TEGRA_PINGROUP_SPID,
117 TEGRA_PINGROUP_SPIE,
118 TEGRA_PINGROUP_SPIF,
119 TEGRA_PINGROUP_SPIG,
120 TEGRA_PINGROUP_SPIH,
121 TEGRA_PINGROUP_UAA,
122 TEGRA_PINGROUP_UAB,
123 TEGRA_PINGROUP_UAC,
124 TEGRA_PINGROUP_UAD,
125 TEGRA_PINGROUP_UCA,
126 TEGRA_PINGROUP_UCB,
127 TEGRA_PINGROUP_UDA,
128 /* these pin groups only have pullup and pull down control */
129 TEGRA_PINGROUP_CK32,
130 TEGRA_PINGROUP_DDRC,
131 TEGRA_PINGROUP_PMCA,
132 TEGRA_PINGROUP_PMCB,
133 TEGRA_PINGROUP_PMCC,
134 TEGRA_PINGROUP_PMCD,
135 TEGRA_PINGROUP_PMCE,
136 TEGRA_PINGROUP_XM2C,
137 TEGRA_PINGROUP_XM2D,
138 TEGRA_MAX_PINGROUP,
139};
140
141enum tegra_drive_pingroup {
142 TEGRA_DRIVE_PINGROUP_AO1 = 0,
143 TEGRA_DRIVE_PINGROUP_AO2,
144 TEGRA_DRIVE_PINGROUP_AT1,
145 TEGRA_DRIVE_PINGROUP_AT2,
146 TEGRA_DRIVE_PINGROUP_CDEV1,
147 TEGRA_DRIVE_PINGROUP_CDEV2,
148 TEGRA_DRIVE_PINGROUP_CSUS,
149 TEGRA_DRIVE_PINGROUP_DAP1,
150 TEGRA_DRIVE_PINGROUP_DAP2,
151 TEGRA_DRIVE_PINGROUP_DAP3,
152 TEGRA_DRIVE_PINGROUP_DAP4,
153 TEGRA_DRIVE_PINGROUP_DBG,
154 TEGRA_DRIVE_PINGROUP_LCD1,
155 TEGRA_DRIVE_PINGROUP_LCD2,
156 TEGRA_DRIVE_PINGROUP_SDMMC2,
157 TEGRA_DRIVE_PINGROUP_SDMMC3,
158 TEGRA_DRIVE_PINGROUP_SPI,
159 TEGRA_DRIVE_PINGROUP_UAA,
160 TEGRA_DRIVE_PINGROUP_UAB,
161 TEGRA_DRIVE_PINGROUP_UART2,
162 TEGRA_DRIVE_PINGROUP_UART3,
163 TEGRA_DRIVE_PINGROUP_VI1,
164 TEGRA_DRIVE_PINGROUP_VI2,
165 TEGRA_DRIVE_PINGROUP_XM2A,
166 TEGRA_DRIVE_PINGROUP_XM2C,
167 TEGRA_DRIVE_PINGROUP_XM2D,
168 TEGRA_DRIVE_PINGROUP_XM2CLK,
169 TEGRA_DRIVE_PINGROUP_MEMCOMP,
170 TEGRA_DRIVE_PINGROUP_SDIO1,
171 TEGRA_DRIVE_PINGROUP_CRT,
172 TEGRA_DRIVE_PINGROUP_DDC,
173 TEGRA_DRIVE_PINGROUP_GMA,
174 TEGRA_DRIVE_PINGROUP_GMB,
175 TEGRA_DRIVE_PINGROUP_GMC,
176 TEGRA_DRIVE_PINGROUP_GMD,
177 TEGRA_DRIVE_PINGROUP_GME,
178 TEGRA_DRIVE_PINGROUP_OWR,
179 TEGRA_DRIVE_PINGROUP_UAD,
180 TEGRA_MAX_DRIVE_PINGROUP,
181};
182
183#endif
184
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t3.h b/arch/arm/mach-tegra/include/mach/pinmux-t3.h
new file mode 100644
index 00000000000..12fd5e8ffc1
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux-t3.h
@@ -0,0 +1,321 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux-t3.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
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#ifndef __MACH_TEGRA_PINMUX_T3_H
19#define __MACH_TEGRA_PINMUX_T3_H
20
21#define TEGRA_PINMUX_HAS_IO_DIRECTION 1
22
23enum tegra_pingroup {
24 TEGRA_PINGROUP_ULPI_DATA0 = 0,
25 TEGRA_PINGROUP_ULPI_DATA1,
26 TEGRA_PINGROUP_ULPI_DATA2,
27 TEGRA_PINGROUP_ULPI_DATA3,
28 TEGRA_PINGROUP_ULPI_DATA4,
29 TEGRA_PINGROUP_ULPI_DATA5,
30 TEGRA_PINGROUP_ULPI_DATA6,
31 TEGRA_PINGROUP_ULPI_DATA7,
32 TEGRA_PINGROUP_ULPI_CLK,
33 TEGRA_PINGROUP_ULPI_DIR,
34 TEGRA_PINGROUP_ULPI_NXT,
35 TEGRA_PINGROUP_ULPI_STP,
36 TEGRA_PINGROUP_DAP3_FS,
37 TEGRA_PINGROUP_DAP3_DIN,
38 TEGRA_PINGROUP_DAP3_DOUT,
39 TEGRA_PINGROUP_DAP3_SCLK,
40 TEGRA_PINGROUP_GPIO_PV0,
41 TEGRA_PINGROUP_GPIO_PV1,
42 TEGRA_PINGROUP_SDMMC1_CLK,
43 TEGRA_PINGROUP_SDMMC1_CMD,
44 TEGRA_PINGROUP_SDMMC1_DAT3,
45 TEGRA_PINGROUP_SDMMC1_DAT2,
46 TEGRA_PINGROUP_SDMMC1_DAT1,
47 TEGRA_PINGROUP_SDMMC1_DAT0,
48 TEGRA_PINGROUP_GPIO_PV2,
49 TEGRA_PINGROUP_GPIO_PV3,
50 TEGRA_PINGROUP_CLK2_OUT,
51 TEGRA_PINGROUP_CLK2_REQ,
52 TEGRA_PINGROUP_LCD_PWR1,
53 TEGRA_PINGROUP_LCD_PWR2,
54 TEGRA_PINGROUP_LCD_SDIN,
55 TEGRA_PINGROUP_LCD_SDOUT,
56 TEGRA_PINGROUP_LCD_WR_N,
57 TEGRA_PINGROUP_LCD_CS0_N,
58 TEGRA_PINGROUP_LCD_DC0,
59 TEGRA_PINGROUP_LCD_SCK,
60 TEGRA_PINGROUP_LCD_PWR0,
61 TEGRA_PINGROUP_LCD_PCLK,
62 TEGRA_PINGROUP_LCD_DE,
63 TEGRA_PINGROUP_LCD_HSYNC,
64 TEGRA_PINGROUP_LCD_VSYNC,
65 TEGRA_PINGROUP_LCD_D0,
66 TEGRA_PINGROUP_LCD_D1,
67 TEGRA_PINGROUP_LCD_D2,
68 TEGRA_PINGROUP_LCD_D3,
69 TEGRA_PINGROUP_LCD_D4,
70 TEGRA_PINGROUP_LCD_D5,
71 TEGRA_PINGROUP_LCD_D6,
72 TEGRA_PINGROUP_LCD_D7,
73 TEGRA_PINGROUP_LCD_D8,
74 TEGRA_PINGROUP_LCD_D9,
75 TEGRA_PINGROUP_LCD_D10,
76 TEGRA_PINGROUP_LCD_D11,
77 TEGRA_PINGROUP_LCD_D12,
78 TEGRA_PINGROUP_LCD_D13,
79 TEGRA_PINGROUP_LCD_D14,
80 TEGRA_PINGROUP_LCD_D15,
81 TEGRA_PINGROUP_LCD_D16,
82 TEGRA_PINGROUP_LCD_D17,
83 TEGRA_PINGROUP_LCD_D18,
84 TEGRA_PINGROUP_LCD_D19,
85 TEGRA_PINGROUP_LCD_D20,
86 TEGRA_PINGROUP_LCD_D21,
87 TEGRA_PINGROUP_LCD_D22,
88 TEGRA_PINGROUP_LCD_D23,
89 TEGRA_PINGROUP_LCD_CS1_N,
90 TEGRA_PINGROUP_LCD_M1,
91 TEGRA_PINGROUP_LCD_DC1,
92 TEGRA_PINGROUP_HDMI_INT,
93 TEGRA_PINGROUP_DDC_SCL,
94 TEGRA_PINGROUP_DDC_SDA,
95 TEGRA_PINGROUP_CRT_HSYNC,
96 TEGRA_PINGROUP_CRT_VSYNC,
97 TEGRA_PINGROUP_VI_D0,
98 TEGRA_PINGROUP_VI_D1,
99 TEGRA_PINGROUP_VI_D2,
100 TEGRA_PINGROUP_VI_D3,
101 TEGRA_PINGROUP_VI_D4,
102 TEGRA_PINGROUP_VI_D5,
103 TEGRA_PINGROUP_VI_D6,
104 TEGRA_PINGROUP_VI_D7,
105 TEGRA_PINGROUP_VI_D8,
106 TEGRA_PINGROUP_VI_D9,
107 TEGRA_PINGROUP_VI_D10,
108 TEGRA_PINGROUP_VI_D11,
109 TEGRA_PINGROUP_VI_PCLK,
110 TEGRA_PINGROUP_VI_MCLK,
111 TEGRA_PINGROUP_VI_VSYNC,
112 TEGRA_PINGROUP_VI_HSYNC,
113 TEGRA_PINGROUP_UART2_RXD,
114 TEGRA_PINGROUP_UART2_TXD,
115 TEGRA_PINGROUP_UART2_RTS_N,
116 TEGRA_PINGROUP_UART2_CTS_N,
117 TEGRA_PINGROUP_UART3_TXD,
118 TEGRA_PINGROUP_UART3_RXD,
119 TEGRA_PINGROUP_UART3_CTS_N,
120 TEGRA_PINGROUP_UART3_RTS_N,
121 TEGRA_PINGROUP_GPIO_PU0,
122 TEGRA_PINGROUP_GPIO_PU1,
123 TEGRA_PINGROUP_GPIO_PU2,
124 TEGRA_PINGROUP_GPIO_PU3,
125 TEGRA_PINGROUP_GPIO_PU4,
126 TEGRA_PINGROUP_GPIO_PU5,
127 TEGRA_PINGROUP_GPIO_PU6,
128 TEGRA_PINGROUP_GEN1_I2C_SDA,
129 TEGRA_PINGROUP_GEN1_I2C_SCL,
130 TEGRA_PINGROUP_DAP4_FS,
131 TEGRA_PINGROUP_DAP4_DIN,
132 TEGRA_PINGROUP_DAP4_DOUT,
133 TEGRA_PINGROUP_DAP4_SCLK,
134 TEGRA_PINGROUP_CLK3_OUT,
135 TEGRA_PINGROUP_CLK3_REQ,
136 TEGRA_PINGROUP_GMI_WP_N,
137 TEGRA_PINGROUP_GMI_IORDY,
138 TEGRA_PINGROUP_GMI_WAIT,
139 TEGRA_PINGROUP_GMI_ADV_N,
140 TEGRA_PINGROUP_GMI_CLK,
141 TEGRA_PINGROUP_GMI_CS0_N,
142 TEGRA_PINGROUP_GMI_CS1_N,
143 TEGRA_PINGROUP_GMI_CS2_N,
144 TEGRA_PINGROUP_GMI_CS3_N,
145 TEGRA_PINGROUP_GMI_CS4_N,
146 TEGRA_PINGROUP_GMI_CS6_N,
147 TEGRA_PINGROUP_GMI_CS7_N,
148 TEGRA_PINGROUP_GMI_AD0,
149 TEGRA_PINGROUP_GMI_AD1,
150 TEGRA_PINGROUP_GMI_AD2,
151 TEGRA_PINGROUP_GMI_AD3,
152 TEGRA_PINGROUP_GMI_AD4,
153 TEGRA_PINGROUP_GMI_AD5,
154 TEGRA_PINGROUP_GMI_AD6,
155 TEGRA_PINGROUP_GMI_AD7,
156 TEGRA_PINGROUP_GMI_AD8,
157 TEGRA_PINGROUP_GMI_AD9,
158 TEGRA_PINGROUP_GMI_AD10,
159 TEGRA_PINGROUP_GMI_AD11,
160 TEGRA_PINGROUP_GMI_AD12,
161 TEGRA_PINGROUP_GMI_AD13,
162 TEGRA_PINGROUP_GMI_AD14,
163 TEGRA_PINGROUP_GMI_AD15,
164 TEGRA_PINGROUP_GMI_A16,
165 TEGRA_PINGROUP_GMI_A17,
166 TEGRA_PINGROUP_GMI_A18,
167 TEGRA_PINGROUP_GMI_A19,
168 TEGRA_PINGROUP_GMI_WR_N,
169 TEGRA_PINGROUP_GMI_OE_N,
170 TEGRA_PINGROUP_GMI_DQS,
171 TEGRA_PINGROUP_GMI_RST_N,
172 TEGRA_PINGROUP_GEN2_I2C_SCL,
173 TEGRA_PINGROUP_GEN2_I2C_SDA,
174 TEGRA_PINGROUP_SDMMC4_CLK,
175 TEGRA_PINGROUP_SDMMC4_CMD,
176 TEGRA_PINGROUP_SDMMC4_DAT0,
177 TEGRA_PINGROUP_SDMMC4_DAT1,
178 TEGRA_PINGROUP_SDMMC4_DAT2,
179 TEGRA_PINGROUP_SDMMC4_DAT3,
180 TEGRA_PINGROUP_SDMMC4_DAT4,
181 TEGRA_PINGROUP_SDMMC4_DAT5,
182 TEGRA_PINGROUP_SDMMC4_DAT6,
183 TEGRA_PINGROUP_SDMMC4_DAT7,
184 TEGRA_PINGROUP_SDMMC4_RST_N,
185 TEGRA_PINGROUP_CAM_MCLK,
186 TEGRA_PINGROUP_GPIO_PCC1,
187 TEGRA_PINGROUP_GPIO_PBB0,
188 TEGRA_PINGROUP_CAM_I2C_SCL,
189 TEGRA_PINGROUP_CAM_I2C_SDA,
190 TEGRA_PINGROUP_GPIO_PBB3,
191 TEGRA_PINGROUP_GPIO_PBB4,
192 TEGRA_PINGROUP_GPIO_PBB5,
193 TEGRA_PINGROUP_GPIO_PBB6,
194 TEGRA_PINGROUP_GPIO_PBB7,
195 TEGRA_PINGROUP_GPIO_PCC2,
196 TEGRA_PINGROUP_JTAG_RTCK,
197 TEGRA_PINGROUP_PWR_I2C_SCL,
198 TEGRA_PINGROUP_PWR_I2C_SDA,
199 TEGRA_PINGROUP_KB_ROW0,
200 TEGRA_PINGROUP_KB_ROW1,
201 TEGRA_PINGROUP_KB_ROW2,
202 TEGRA_PINGROUP_KB_ROW3,
203 TEGRA_PINGROUP_KB_ROW4,
204 TEGRA_PINGROUP_KB_ROW5,
205 TEGRA_PINGROUP_KB_ROW6,
206 TEGRA_PINGROUP_KB_ROW7,
207 TEGRA_PINGROUP_KB_ROW8,
208 TEGRA_PINGROUP_KB_ROW9,
209 TEGRA_PINGROUP_KB_ROW10,
210 TEGRA_PINGROUP_KB_ROW11,
211 TEGRA_PINGROUP_KB_ROW12,
212 TEGRA_PINGROUP_KB_ROW13,
213 TEGRA_PINGROUP_KB_ROW14,
214 TEGRA_PINGROUP_KB_ROW15,
215 TEGRA_PINGROUP_KB_COL0,
216 TEGRA_PINGROUP_KB_COL1,
217 TEGRA_PINGROUP_KB_COL2,
218 TEGRA_PINGROUP_KB_COL3,
219 TEGRA_PINGROUP_KB_COL4,
220 TEGRA_PINGROUP_KB_COL5,
221 TEGRA_PINGROUP_KB_COL6,
222 TEGRA_PINGROUP_KB_COL7,
223 TEGRA_PINGROUP_CLK_32K_OUT,
224 TEGRA_PINGROUP_SYS_CLK_REQ,
225 TEGRA_PINGROUP_CORE_PWR_REQ,
226 TEGRA_PINGROUP_CPU_PWR_REQ,
227 TEGRA_PINGROUP_PWR_INT_N,
228 TEGRA_PINGROUP_CLK_32K_IN,
229 TEGRA_PINGROUP_OWR,
230 TEGRA_PINGROUP_DAP1_FS,
231 TEGRA_PINGROUP_DAP1_DIN,
232 TEGRA_PINGROUP_DAP1_DOUT,
233 TEGRA_PINGROUP_DAP1_SCLK,
234 TEGRA_PINGROUP_CLK1_REQ,
235 TEGRA_PINGROUP_CLK1_OUT,
236 TEGRA_PINGROUP_SPDIF_IN,
237 TEGRA_PINGROUP_SPDIF_OUT,
238 TEGRA_PINGROUP_DAP2_FS,
239 TEGRA_PINGROUP_DAP2_DIN,
240 TEGRA_PINGROUP_DAP2_DOUT,
241 TEGRA_PINGROUP_DAP2_SCLK,
242 TEGRA_PINGROUP_SPI2_MOSI,
243 TEGRA_PINGROUP_SPI2_MISO,
244 TEGRA_PINGROUP_SPI2_CS0_N,
245 TEGRA_PINGROUP_SPI2_SCK,
246 TEGRA_PINGROUP_SPI1_MOSI,
247 TEGRA_PINGROUP_SPI1_SCK,
248 TEGRA_PINGROUP_SPI1_CS0_N,
249 TEGRA_PINGROUP_SPI1_MISO,
250 TEGRA_PINGROUP_SPI2_CS1_N,
251 TEGRA_PINGROUP_SPI2_CS2_N,
252 TEGRA_PINGROUP_SDMMC3_CLK,
253 TEGRA_PINGROUP_SDMMC3_CMD,
254 TEGRA_PINGROUP_SDMMC3_DAT0,
255 TEGRA_PINGROUP_SDMMC3_DAT1,
256 TEGRA_PINGROUP_SDMMC3_DAT2,
257 TEGRA_PINGROUP_SDMMC3_DAT3,
258 TEGRA_PINGROUP_SDMMC3_DAT4,
259 TEGRA_PINGROUP_SDMMC3_DAT5,
260 TEGRA_PINGROUP_SDMMC3_DAT6,
261 TEGRA_PINGROUP_SDMMC3_DAT7,
262 TEGRA_PINGROUP_PEX_L0_PRSNT_N,
263 TEGRA_PINGROUP_PEX_L0_RST_N,
264 TEGRA_PINGROUP_PEX_L0_CLKREQ_N,
265 TEGRA_PINGROUP_PEX_WAKE_N,
266 TEGRA_PINGROUP_PEX_L1_PRSNT_N,
267 TEGRA_PINGROUP_PEX_L1_RST_N,
268 TEGRA_PINGROUP_PEX_L1_CLKREQ_N,
269 TEGRA_PINGROUP_PEX_L2_PRSNT_N,
270 TEGRA_PINGROUP_PEX_L2_RST_N,
271 TEGRA_PINGROUP_PEX_L2_CLKREQ_N,
272 TEGRA_PINGROUP_HDMI_CEC,
273 TEGRA_MAX_PINGROUP,
274};
275
276enum tegra_drive_pingroup {
277 TEGRA_DRIVE_PINGROUP_AO1 = 0,
278 TEGRA_DRIVE_PINGROUP_AO2,
279 TEGRA_DRIVE_PINGROUP_AT1,
280 TEGRA_DRIVE_PINGROUP_AT2,
281 TEGRA_DRIVE_PINGROUP_AT3,
282 TEGRA_DRIVE_PINGROUP_AT4,
283 TEGRA_DRIVE_PINGROUP_AT5,
284 TEGRA_DRIVE_PINGROUP_CDEV1,
285 TEGRA_DRIVE_PINGROUP_CDEV2,
286 TEGRA_DRIVE_PINGROUP_CSUS,
287 TEGRA_DRIVE_PINGROUP_DAP1,
288 TEGRA_DRIVE_PINGROUP_DAP2,
289 TEGRA_DRIVE_PINGROUP_DAP3,
290 TEGRA_DRIVE_PINGROUP_DAP4,
291 TEGRA_DRIVE_PINGROUP_DBG,
292 TEGRA_DRIVE_PINGROUP_LCD1,
293 TEGRA_DRIVE_PINGROUP_LCD2,
294 TEGRA_DRIVE_PINGROUP_SDIO2,
295 TEGRA_DRIVE_PINGROUP_SDIO3,
296 TEGRA_DRIVE_PINGROUP_SPI,
297 TEGRA_DRIVE_PINGROUP_UAA,
298 TEGRA_DRIVE_PINGROUP_UAB,
299 TEGRA_DRIVE_PINGROUP_UART2,
300 TEGRA_DRIVE_PINGROUP_UART3,
301 TEGRA_DRIVE_PINGROUP_VI1,
302 TEGRA_DRIVE_PINGROUP_SDIO1,
303 TEGRA_DRIVE_PINGROUP_CRT,
304 TEGRA_DRIVE_PINGROUP_DDC,
305 TEGRA_DRIVE_PINGROUP_GMA,
306 TEGRA_DRIVE_PINGROUP_GMB,
307 TEGRA_DRIVE_PINGROUP_GMC,
308 TEGRA_DRIVE_PINGROUP_GMD,
309 TEGRA_DRIVE_PINGROUP_GME,
310 TEGRA_DRIVE_PINGROUP_GMF,
311 TEGRA_DRIVE_PINGROUP_GMG,
312 TEGRA_DRIVE_PINGROUP_GMH,
313 TEGRA_DRIVE_PINGROUP_OWR,
314 TEGRA_DRIVE_PINGROUP_UAD,
315 TEGRA_DRIVE_PINGROUP_GPV,
316 TEGRA_DRIVE_PINGROUP_DEV3,
317 TEGRA_DRIVE_PINGROUP_CEC,
318 TEGRA_MAX_DRIVE_PINGROUP,
319};
320
321#endif
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
new file mode 100644
index 00000000000..f485d0bb072
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -0,0 +1,375 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
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#ifndef __MACH_TEGRA_PINMUX_H
19#define __MACH_TEGRA_PINMUX_H
20
21#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
22#include "pinmux-t2.h"
23#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
24#include "pinmux-t3.h"
25#else
26#error "Undefined Tegra architecture"
27#endif
28
29#define TEGRA_MUX_LIST \
30 TEGRA_MUX(NONE) \
31 TEGRA_MUX(AHB_CLK) \
32 TEGRA_MUX(APB_CLK) \
33 TEGRA_MUX(AUDIO_SYNC) \
34 TEGRA_MUX(CRT) \
35 TEGRA_MUX(DAP1) \
36 TEGRA_MUX(DAP2) \
37 TEGRA_MUX(DAP3) \
38 TEGRA_MUX(DAP4) \
39 TEGRA_MUX(DAP5) \
40 TEGRA_MUX(DISPLAYA) \
41 TEGRA_MUX(DISPLAYB) \
42 TEGRA_MUX(EMC_TEST0_DLL) \
43 TEGRA_MUX(EMC_TEST1_DLL) \
44 TEGRA_MUX(GMI) \
45 TEGRA_MUX(GMI_INT) \
46 TEGRA_MUX(HDMI) \
47 TEGRA_MUX(I2C1) \
48 TEGRA_MUX(I2C2) \
49 TEGRA_MUX(I2C3) \
50 TEGRA_MUX(IDE) \
51 TEGRA_MUX(IRDA) \
52 TEGRA_MUX(KBC) \
53 TEGRA_MUX(MIO) \
54 TEGRA_MUX(MIPI_HS) \
55 TEGRA_MUX(NAND) \
56 TEGRA_MUX(OSC) \
57 TEGRA_MUX(OWR) \
58 TEGRA_MUX(PCIE) \
59 TEGRA_MUX(PLLA_OUT) \
60 TEGRA_MUX(PLLC_OUT1) \
61 TEGRA_MUX(PLLM_OUT1) \
62 TEGRA_MUX(PLLP_OUT2) \
63 TEGRA_MUX(PLLP_OUT3) \
64 TEGRA_MUX(PLLP_OUT4) \
65 TEGRA_MUX(PWM) \
66 TEGRA_MUX(PWR_INTR) \
67 TEGRA_MUX(PWR_ON) \
68 TEGRA_MUX(RTCK) \
69 TEGRA_MUX(SDIO1) \
70 TEGRA_MUX(SDIO2) \
71 TEGRA_MUX(SDIO3) \
72 TEGRA_MUX(SDIO4) \
73 TEGRA_MUX(SFLASH) \
74 TEGRA_MUX(SPDIF) \
75 TEGRA_MUX(SPI1) \
76 TEGRA_MUX(SPI2) \
77 TEGRA_MUX(SPI2_ALT) \
78 TEGRA_MUX(SPI3) \
79 TEGRA_MUX(SPI4) \
80 TEGRA_MUX(TRACE) \
81 TEGRA_MUX(TWC) \
82 TEGRA_MUX(UARTA) \
83 TEGRA_MUX(UARTB) \
84 TEGRA_MUX(UARTC) \
85 TEGRA_MUX(UARTD) \
86 TEGRA_MUX(UARTE) \
87 TEGRA_MUX(ULPI) \
88 TEGRA_MUX(VI) \
89 TEGRA_MUX(VI_SENSOR_CLK) \
90 TEGRA_MUX(XIO) \
91 /* End of Tegra2 MUX selectors */ \
92 TEGRA_MUX(BLINK) \
93 TEGRA_MUX(CEC) \
94 TEGRA_MUX(CLK12) \
95 TEGRA_MUX(DAP) \
96 TEGRA_MUX(DAPSDMMC2) \
97 TEGRA_MUX(DDR) \
98 TEGRA_MUX(DEV3) \
99 TEGRA_MUX(DTV) \
100 TEGRA_MUX(VI_ALT1) \
101 TEGRA_MUX(VI_ALT2) \
102 TEGRA_MUX(VI_ALT3) \
103 TEGRA_MUX(EMC_DLL) \
104 TEGRA_MUX(EXTPERIPH1) \
105 TEGRA_MUX(EXTPERIPH2) \
106 TEGRA_MUX(EXTPERIPH3) \
107 TEGRA_MUX(GMI_ALT) \
108 TEGRA_MUX(HDA) \
109 TEGRA_MUX(HSI) \
110 TEGRA_MUX(I2C4) \
111 TEGRA_MUX(I2C5) \
112 TEGRA_MUX(I2CPWR) \
113 TEGRA_MUX(I2S0) \
114 TEGRA_MUX(I2S1) \
115 TEGRA_MUX(I2S2) \
116 TEGRA_MUX(I2S3) \
117 TEGRA_MUX(I2S4) \
118 TEGRA_MUX(NAND_ALT) \
119 TEGRA_MUX(POPSDIO4) \
120 TEGRA_MUX(POPSDMMC4) \
121 TEGRA_MUX(PWM0) \
122 TEGRA_MUX(PWM1) \
123 TEGRA_MUX(PWM2) \
124 TEGRA_MUX(PWM3) \
125 TEGRA_MUX(SATA) \
126 TEGRA_MUX(SPI5) \
127 TEGRA_MUX(SPI6) \
128 TEGRA_MUX(SYSCLK) \
129 TEGRA_MUX(VGP1) \
130 TEGRA_MUX(VGP2) \
131 TEGRA_MUX(VGP3) \
132 TEGRA_MUX(VGP4) \
133 TEGRA_MUX(VGP5) \
134 TEGRA_MUX(VGP6) \
135 /* End of Tegra3 MUX selectors */
136
137enum tegra_mux_func {
138#define TEGRA_MUX(mux) TEGRA_MUX_##mux,
139 TEGRA_MUX_LIST
140#undef TEGRA_MUX
141 TEGRA_MUX_SAFE, /* "Safe" default mux selector */
142 TEGRA_MAX_MUX, /* Number of mux selectors */
143 TEGRA_MUX_TEGRA2_LAST = TEGRA_MUX_XIO,
144 TEGRA_MUX_TEGRA3_LAST = TEGRA_MUX_VGP6,
145
146 /* Mux selector aliases */
147 TEGRA_MUX_I2C = TEGRA_MUX_I2C1,
148 TEGRA_MUX_SDMMC1 = TEGRA_MUX_SDIO1,
149 TEGRA_MUX_SDMMC2 = TEGRA_MUX_SDIO2,
150 TEGRA_MUX_SDMMC3 = TEGRA_MUX_SDIO3,
151 TEGRA_MUX_SDMMC4 = TEGRA_MUX_SDIO4,
152
153 /* Special mux selector values */
154 TEGRA_MUX_INVALID = 0x4000,
155 TEGRA_MUX_RSVD = 0x8000,
156 TEGRA_MUX_RSVD0 = TEGRA_MUX_RSVD,
157 TEGRA_MUX_RSVD1 = 0x8001,
158 TEGRA_MUX_RSVD2 = 0x8002,
159 TEGRA_MUX_RSVD3 = 0x8003,
160 TEGRA_MUX_RSVD4 = 0x8004,
161};
162
163enum tegra_pullupdown {
164 TEGRA_PUPD_NORMAL = 0,
165 TEGRA_PUPD_PULL_DOWN,
166 TEGRA_PUPD_PULL_UP,
167};
168
169enum tegra_tristate {
170 TEGRA_TRI_NORMAL = 0,
171 TEGRA_TRI_TRISTATE = 1,
172};
173
174enum tegra_pin_io {
175 TEGRA_PIN_OUTPUT = 0,
176 TEGRA_PIN_INPUT = 1,
177};
178
179enum tegra_pin_lock {
180 TEGRA_PIN_LOCK_DEFAULT = 0,
181 TEGRA_PIN_LOCK_DISABLE,
182 TEGRA_PIN_LOCK_ENABLE,
183};
184
185enum tegra_pin_od {
186 TEGRA_PIN_OD_DEFAULT = 0,
187 TEGRA_PIN_OD_DISABLE,
188 TEGRA_PIN_OD_ENABLE,
189};
190
191enum tegra_pin_ioreset {
192 TEGRA_PIN_IO_RESET_DEFAULT = 0,
193 TEGRA_PIN_IO_RESET_DISABLE,
194 TEGRA_PIN_IO_RESET_ENABLE,
195};
196
197enum tegra_vddio {
198 TEGRA_VDDIO_BB = 0,
199 TEGRA_VDDIO_LCD,
200 TEGRA_VDDIO_VI,
201 TEGRA_VDDIO_UART,
202 TEGRA_VDDIO_DDR,
203 TEGRA_VDDIO_NAND,
204 TEGRA_VDDIO_SYS,
205 TEGRA_VDDIO_AUDIO,
206 TEGRA_VDDIO_SD,
207#ifndef CONFIG_ARCH_TEGRA_2x_SOC
208 TEGRA_VDDIO_CAM,
209 TEGRA_VDDIO_GMI,
210 TEGRA_VDDIO_PEXCTL,
211 TEGRA_VDDIO_SDMMC1,
212 TEGRA_VDDIO_SDMMC3,
213 TEGRA_VDDIO_SDMMC4,
214#endif
215};
216
217struct tegra_pingroup_config {
218 enum tegra_pingroup pingroup;
219 enum tegra_mux_func func;
220 enum tegra_pullupdown pupd;
221 enum tegra_tristate tristate;
222 enum tegra_pin_io io;
223 enum tegra_pin_lock lock;
224 enum tegra_pin_od od;
225 enum tegra_pin_ioreset ioreset;
226};
227
228enum tegra_slew {
229 TEGRA_SLEW_FASTEST = 0,
230 TEGRA_SLEW_FAST,
231 TEGRA_SLEW_SLOW,
232 TEGRA_SLEW_SLOWEST,
233 TEGRA_MAX_SLEW,
234};
235
236enum tegra_pull_strength {
237 TEGRA_PULL_0 = 0,
238 TEGRA_PULL_1,
239 TEGRA_PULL_2,
240 TEGRA_PULL_3,
241 TEGRA_PULL_4,
242 TEGRA_PULL_5,
243 TEGRA_PULL_6,
244 TEGRA_PULL_7,
245 TEGRA_PULL_8,
246 TEGRA_PULL_9,
247 TEGRA_PULL_10,
248 TEGRA_PULL_11,
249 TEGRA_PULL_12,
250 TEGRA_PULL_13,
251 TEGRA_PULL_14,
252 TEGRA_PULL_15,
253 TEGRA_PULL_16,
254 TEGRA_PULL_17,
255 TEGRA_PULL_18,
256 TEGRA_PULL_19,
257 TEGRA_PULL_20,
258 TEGRA_PULL_21,
259 TEGRA_PULL_22,
260 TEGRA_PULL_23,
261 TEGRA_PULL_24,
262 TEGRA_PULL_25,
263 TEGRA_PULL_26,
264 TEGRA_PULL_27,
265 TEGRA_PULL_28,
266 TEGRA_PULL_29,
267 TEGRA_PULL_30,
268 TEGRA_PULL_31,
269 TEGRA_PULL_32,
270 TEGRA_PULL_33,
271 TEGRA_PULL_34,
272 TEGRA_PULL_35,
273 TEGRA_PULL_36,
274 TEGRA_PULL_37,
275 TEGRA_PULL_38,
276 TEGRA_PULL_39,
277 TEGRA_PULL_40,
278 TEGRA_PULL_41,
279 TEGRA_PULL_42,
280 TEGRA_PULL_43,
281 TEGRA_PULL_44,
282 TEGRA_PULL_45,
283 TEGRA_PULL_46,
284 TEGRA_MAX_PULL,
285};
286
287enum tegra_drive {
288 TEGRA_DRIVE_DIV_8 = 0,
289 TEGRA_DRIVE_DIV_4,
290 TEGRA_DRIVE_DIV_2,
291 TEGRA_DRIVE_DIV_1,
292 TEGRA_MAX_DRIVE,
293};
294
295enum tegra_hsm {
296 TEGRA_HSM_DISABLE = 0,
297 TEGRA_HSM_ENABLE,
298};
299
300enum tegra_schmitt {
301 TEGRA_SCHMITT_DISABLE = 0,
302 TEGRA_SCHMITT_ENABLE,
303};
304
305struct tegra_drive_pingroup_config {
306 enum tegra_drive_pingroup pingroup;
307 enum tegra_hsm hsm;
308 enum tegra_schmitt schmitt;
309 enum tegra_drive drive;
310 enum tegra_pull_strength pull_down;
311 enum tegra_pull_strength pull_up;
312 enum tegra_slew slew_rising;
313 enum tegra_slew slew_falling;
314};
315
316struct tegra_drive_pingroup_desc {
317 const char *name;
318 s16 reg;
319 u8 drvup_offset;
320 u16 drvup_mask;
321 u8 drvdown_offset;
322 u16 drvdown_mask;
323 u8 slewrise_offset;
324 u16 slewrise_mask;
325 u8 slewfall_offset;
326 u16 slewfall_mask;
327};
328
329struct tegra_pingroup_desc {
330 const char *name;
331 int funcs[4];
332 int func_safe;
333 int vddio;
334 s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */
335 s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
336 s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
337 s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
338 s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
339 s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
340 s8 lock_bit; /* offser of the LOCK bit into mux register bit */
341 s8 od_bit; /* offset of the OD bit into mux register bit */
342 s8 ioreset_bit; /* offset of the IO_RESET bit into mux register bit */
343 s8 io_default;
344 int gpionr;
345};
346
347extern const struct tegra_pingroup_desc tegra_soc_pingroups[];
348extern const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[];
349extern const int gpio_to_pingroup[];
350
351int tegra_pinmux_get_func(enum tegra_pingroup pg);
352int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
353 enum tegra_tristate tristate);
354int tegra_pinmux_set_io(enum tegra_pingroup pg,
355 enum tegra_pin_io input);
356int tegra_pinmux_get_pingroup(int gpio_nr);
357int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
358 enum tegra_pullupdown pupd);
359
360void tegra_pinmux_config_table(const struct tegra_pingroup_config *config,
361 int len);
362
363void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
364 int len);
365void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
366 int len);
367void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
368 int len);
369void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
370 int len, enum tegra_tristate tristate);
371void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
372 int len, enum tegra_pullupdown pupd);
373
374void __init tegra_init_pinmux(void);
375#endif
diff --git a/arch/arm/mach-tegra/include/mach/sdhci.h b/arch/arm/mach-tegra/include/mach/sdhci.h
new file mode 100644
index 00000000000..b48a9288707
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/sdhci.h
@@ -0,0 +1,35 @@
1/*
2 * include/asm-arm/arch-tegra/include/mach/sdhci.h
3 *
4 * Copyright (C) 2009 Palm, Inc.
5 * Author: Yvonne Yip <y@palm.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#ifndef __ASM_ARM_ARCH_TEGRA_SDHCI_H
18#define __ASM_ARM_ARCH_TEGRA_SDHCI_H
19
20#include <linux/mmc/host.h>
21#include <asm/mach/mmc.h>
22
23struct tegra_sdhci_platform_data {
24 int cd_gpio;
25 int wp_gpio;
26 int power_gpio;
27 int is_8bit;
28 int pm_flags;
29 int pm_caps;
30 unsigned int max_clk_limit;
31 unsigned int tap_delay;
32 struct mmc_platform_data mmc_data;
33};
34
35#endif
diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h
new file mode 100644
index 00000000000..dad403a9cf0
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/smmu.h
@@ -0,0 +1,63 @@
1/*
2 * IOMMU API for SMMU in Tegra30
3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifndef MACH_SMMU_H
21#define MACH_SMMU_H
22
23enum smmu_hwgrp {
24 HWGRP_AFI,
25 HWGRP_AVPC,
26 HWGRP_DC,
27 HWGRP_DCB,
28 HWGRP_EPP,
29 HWGRP_G2,
30 HWGRP_HC,
31 HWGRP_HDA,
32 HWGRP_ISP,
33 HWGRP_MPE,
34 HWGRP_NV,
35 HWGRP_NV2,
36 HWGRP_PPCS,
37 HWGRP_SATA,
38 HWGRP_VDE,
39 HWGRP_VI,
40
41 HWGRP_COUNT,
42
43 HWGRP_END = ~0,
44};
45
46#define HWG_AFI (1 << HWGRP_AFI)
47#define HWG_AVPC (1 << HWGRP_AVPC)
48#define HWG_DC (1 << HWGRP_DC)
49#define HWG_DCB (1 << HWGRP_DCB)
50#define HWG_EPP (1 << HWGRP_EPP)
51#define HWG_G2 (1 << HWGRP_G2)
52#define HWG_HC (1 << HWGRP_HC)
53#define HWG_HDA (1 << HWGRP_HDA)
54#define HWG_ISP (1 << HWGRP_ISP)
55#define HWG_MPE (1 << HWGRP_MPE)
56#define HWG_NV (1 << HWGRP_NV)
57#define HWG_NV2 (1 << HWGRP_NV2)
58#define HWG_PPCS (1 << HWGRP_PPCS)
59#define HWG_SATA (1 << HWGRP_SATA)
60#define HWG_VDE (1 << HWGRP_VDE)
61#define HWG_VI (1 << HWGRP_VI)
62
63#endif /* MACH_SMMU_H */
diff --git a/arch/arm/mach-tegra/include/mach/spdif.h b/arch/arm/mach-tegra/include/mach/spdif.h
new file mode 100644
index 00000000000..96103fae91b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/spdif.h
@@ -0,0 +1,392 @@
1/*
2 * arch/arm/mach-tegra/include/mach/spdif.h
3 *
4 *
5 * Copyright (c) 2008-2009, NVIDIA Corporation.
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
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.
15 * See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
21 */
22
23
24#ifndef __ARCH_ARM_MACH_TEGRA_SPDIF_H
25#define __ARCH_ARM_MACH_TEGRA_SPDIF_H
26
27#include <linux/kernel.h>
28#include <linux/types.h>
29#include <linux/platform_device.h>
30
31/* Offsets from TEGRA_SPDIF_BASE */
32
33#define SPDIF_CTRL_0 0x0
34#define SPDIF_STATUS_0 0x4
35#define SPDIF_STROBE_CTRL_0 0x8
36#define SPDIF_DATA_FIFO_CSR_0 0x0C
37#define SPDIF_DATA_OUT_0 0x40
38#define SPDIF_DATA_IN_0 0x80
39#define SPDIF_CH_STA_RX_A_0 0x100
40#define SPDIF_CH_STA_RX_B_0 0x104
41#define SPDIF_CH_STA_RX_C_0 0x108
42#define SPDIF_CH_STA_RX_D_0 0x10C
43#define SPDIF_CH_STA_RX_E_0 0x110
44#define SPDIF_CH_STA_RX_F_0 0x114
45#define SPDIF_CH_STA_TX_A_0 0x140
46#define SPDIF_CH_STA_TX_B_0 0x144
47#define SPDIF_CH_STA_TX_C_0 0x148
48#define SPDIF_CH_STA_TX_D_0 0x14C
49#define SPDIF_CH_STA_TX_E_0 0x150
50#define SPDIF_CH_STA_TX_F_0 0x154
51#define SPDIF_USR_STA_RX_A_0 0x180
52#define SPDIF_USR_DAT_TX_A_0 0x1C0
53
54/*
55 * Register SPDIF_CTRL_0
56 */
57
58/*
59 * 1=start capturing from left channel,0=start
60 * capturing from right channel.
61 */
62#define SPDIF_CTRL_0_CAP_LC (1<<30)
63
64/* SPDIF receiver(RX): 1=enable, 0=disable. */
65#define SPDIF_CTRL_0_RX_EN (1<<29)
66
67/* SPDIF Transmitter(TX): 1=enable, 0=disable. */
68#define SPDIF_CTRL_0_TX_EN (1<<28)
69
70/* Transmit Channel status: 1=enable, 0=disable. */
71#define SPDIF_CTRL_0_TC_EN (1<<27)
72
73/* Transmit user Data: 1=enable, 0=disable. */
74#define SPDIF_CTRL_0_TU_EN (1<<26)
75
76/* Interrupt on transmit error: 1=enable, 0=disable. */
77#define SPDIF_CTRL_0_IE_TXE (1<<25)
78
79/* Interrupt on receive error: 1=enable, 0=disable. */
80#define SPDIF_CTRL_0_IE_RXE (1<<24)
81
82/* Interrupt on invalid preamble: 1=enable, 0=disable. */
83#define SPDIF_CTRL_0_IE_P (1<<23)
84
85/* Interrupt on "B" preamble: 1=enable, 0=disable. */
86#define SPDIF_CTRL_0_IE_B (1<<22)
87
88/*
89 * Interrupt when block of channel status received:
90 * 1=enable, 0=disable.
91 */
92#define SPDIF_CTRL_0_IE_C (1<<21)
93
94/*
95 * Interrupt when a valid information unit (IU) recieve:
96 * 1=enable, 0=disable.
97 */
98#define SPDIF_CTRL_0_IE_U (1<<20)
99
100/*
101 * Interrupt when RX user FIFO attn. level is reached:
102 * 1=enable, 0=disable.
103 */
104#define SPDIF_CTRL_0_QE_RU (1<<19)
105
106/*
107 * Interrupt when TX user FIFO attn. level is reached:
108 * 1=enable, 0=disable.
109 */
110#define SPDIF_CTRL_0_QE_TU (1<<18)
111
112/*
113 * Interrupt when RX data FIFO attn. level is reached:
114 * 1=enable, 0=disable.
115 */
116#define SPDIF_CTRL_0_QE_RX (1<<17)
117
118/*
119 * Interrupt when TX data FIFO attn. level is reached:
120 * 1=enable, 0=disable.
121 */
122#define SPDIF_CTRL_0_QE_TX (1<<16)
123
124/* Loopback test mode: 1=enable internal loopback, 0=Normal mode. */
125#define SPDIF_CTRL_0_LBK_EN (1<<15)
126
127/*
128 * Pack data mode:
129 * 1=Packeted left/right channel data into a single word,
130 * 0=Single data (16 bit needs to be padded to match the
131 * interface data bit size)
132 */
133#define SPDIF_CTRL_0_PACK (1<<14)
134
135/*
136 * 00=16bit data
137 * 01=20bit data
138 * 10=24bit data
139 * 11=raw data
140 */
141#define SPDIF_BIT_MODE_MODE16BIT (0)
142#define SPDIF_BIT_MODE_MODE20BIT (1)
143#define SPDIF_BIT_MODE_MODE24BIT (2)
144#define SPDIF_BIT_MODE_MODERAW (3)
145#define SPDIF_CTRL_0_BIT_MODE_SHIFT (12)
146
147#define SPDIF_CTRL_0_BIT_MODE_MASK \
148 ((0x3) << SPDIF_CTRL_0_BIT_MODE_SHIFT)
149#define SPDIF_CTRL_0_BIT_MODE_MODE16BIT \
150 (SPDIF_BIT_MODE_MODE16BIT << SPDIF_CTRL_0_BIT_MODE_SHIFT)
151#define SPDIF_CTRL_0_BIT_MODE_MODE20BIT \
152 (SPDIF_BIT_MODE_MODE20BIT << SPDIF_CTRL_0_BIT_MODE_SHIFT)
153#define SPDIF_CTRL_0_BIT_MODE_MODE24BIT \
154 (SPDIF_BIT_MODE_MODE24BIT << SPDIF_CTRL_0_BIT_MODE_SHIFT)
155#define SPDIF_CTRL_0_BIT_MODE_MODERAW \
156 (SPDIF_BIT_MODE_MODERAW << SPDIF_CTRL_0_BIT_MODE_SHIFT)
157
158
159/*
160 * SPDIF Status Register
161 * -------------------------
162 * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits.
163 * Software must write a 1 to the corresponding bit location
164 * to clear the status.
165 */
166
167/* Register SPDIF_STATUS_0 */
168
169/*
170 * Receiver(RX) shifter is busy receiving data. 1=busy, 0=not busy.
171 * This bit is asserted when the receiver first locked onto the
172 * preamble of the data stream after RX_EN is asserted. This bit is
173 * deasserted when either,
174 * (a) the end of a frame is reached after RX_EN is deeasserted, or
175 * (b) the SPDIF data stream becomes inactive.
176 */
177#define SPDIF_STATUS_0_RX_BSY (1<<29)
178
179
180/*
181 * Transmitter(TX) shifter is busy transmitting data.
182 * 1=busy, 0=not busy.
183 * This bit is asserted when TX_EN is asserted.
184 * This bit is deasserted when the end of a frame is reached after
185 * TX_EN is deasserted.
186 */
187#define SPDIF_STATUS_0_TX_BSY (1<<28)
188
189/*
190 * TX is busy shifting out channel status. 1=busy, 0=not busy.
191 * This bit is asserted when both TX_EN and TC_EN are asserted and
192 * data from CH_STA_TX_A register is loaded into the internal shifter.
193 * This bit is deasserted when either,
194 * (a) the end of a frame is reached after TX_EN is deasserted, or
195 * (b) CH_STA_TX_F register is loaded into the internal shifter.
196 */
197#define SPDIF_STATUS_0_TC_BSY (1<<27)
198
199/*
200 * TX User data FIFO busy. 1=busy, 0=not busy.
201 * This bit is asserted when TX_EN and TXU_EN are asserted and
202 * there's data in the TX user FIFO. This bit is deassert when either,
203 * (a) the end of a frame is reached after TX_EN is deasserted, or
204 * (b) there's no data left in the TX user FIFO.
205 */
206#define SPDIF_STATUS_0_TU_BSY (1<<26)
207
208/* Tx FIFO Underrun error status: 1=error, 0=no error */
209#define SPDIF_STATUS_0_TX_ERR (1<<25)
210
211/* Rx FIFO Overrun error status: 1=error, 0=no error */
212#define SPDIF_STATUS_0_RX_ERR (1<<24)
213
214/* Preamble status: 1=bad/missing preamble, 0=Preamble ok */
215#define SPDIF_STATUS_0_IS_P (1<<23)
216
217/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
218#define SPDIF_STATUS_0_IS_B (1<<22)
219
220/*
221 * RX channel block data receive status:
222 * 1=received entire block of channel status,
223 * 0=entire block not recieved yet.
224 */
225#define SPDIF_STATUS_0_IS_C (1<<21)
226
227/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
228#define SPDIF_STATUS_0_IS_U (1<<20)
229
230/*
231 * RX User FIFO Status:
232 * 1=attention level reached, 0=attention level not reached.
233 */
234#define SPDIF_STATUS_0_QS_RU (1<<19)
235
236/*
237 * TX User FIFO Status:
238 * 1=attention level reached, 0=attention level not reached.
239 */
240#define SPDIF_STATUS_0_QS_TU (1<<18)
241
242/*
243 * RX Data FIFO Status:
244 * 1=attention level reached, 0=attention level not reached.
245 */
246#define SPDIF_STATUS_0_QS_RX (1<<17)
247
248/*
249 * TX Data FIFO Status:
250 * 1=attention level reached, 0=attention level not reached.
251 */
252#define SPDIF_STATUS_0_QS_TX (1<<16)
253
254
255/* SPDIF FIFO Configuration and Status Register */
256
257/* Register SPDIF_DATA_FIFO_CSR_0 */
258
259#define SPDIF_FIFO_ATN_LVL_ONE_SLOT 0
260#define SPDIF_FIFO_ATN_LVL_FOUR_SLOTS 1
261#define SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS 2
262#define SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS 3
263
264
265/* Clear Receiver User FIFO (RX USR.FIFO) */
266#define SPDIF_DATA_FIFO_CSR_0_RU_CLR (1<<31)
267
268/*
269 * RX USR.FIFO Attention Level:
270 * 00=1-slot-full, 01=2-slots-full, 10=3-slots-full, 11=4-slots-full.
271 */
272
273#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU1 (0)
274#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU2 (1)
275#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU3 (2)
276#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU4 (3)
277
278#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIFT (29)
279#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_MASK \
280 (0x3 << SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIFT)
281#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU1_WORD_FULL \
282 (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU1 << \
283 SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF)
284#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU2_WORD_FULL \
285 (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU2 << \
286 SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF)
287#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU3_WORD_FULL \
288 (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU3 << \
289 SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF)
290#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU4_WORD_FULL \
291 (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU4 << \
292 SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF)
293
294/* Number of RX USR.FIFO levels with valid data. */
295#define SPDIF_DATA_FIFO_CSR_0_FULL_COUNT_SHIFT (24)
296#define SPDIF_DATA_FIFO_CSR_0_FULL_COUNT_MASK \
297 (0x1f << SPDIF_DATA_FIFO_CSR_0_FULL_COUNT_SHIFT)
298
299/* Clear Transmitter User FIFO (TX USR.FIFO) */
300#define SPDIF_DATA_FIFO_CSR_0_TU_CLR (1<<23)
301
302/*
303 * TxUSR.FIFO Attention Level:
304 * 11=4-slots-empty, 10=3-slots-empty, 01=2-slots-empty, 00=1-slot-empty.
305 */
306
307#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU1 (0)
308#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU2 (1)
309#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU3 (2)
310#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU4 (3)
311
312#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT (21)
313#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_MASK \
314 (0x3 << SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT)
315#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU1_WORD_EMPTY \
316 (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU1 << \
317 SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT)
318#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU2_WORD_EMPTY \
319 (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU2 << \
320 SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT)
321#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU3_WORD_EMPTY \
322 (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU3 << \
323 SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT)
324#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU4_WORD_EMPTY \
325 (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU4 << \
326 SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT)
327
328/* Number of Tx USR.FIFO levels that could be filled. */
329#define SPDIF_DATA_FIFO_CSR_0_TU_EMPTY_COUNT_SHIFT (16)
330#define SPDIF_DATA_FIFO_CSR_0_TU_EMPTY_COUNT_FIELD \
331 ((0x1f) << SPDIF_DATA_FIFO_CSR_0_TU_EMPTY_COUNT_SHIFT)
332
333/* Clear Receiver Data FIFO (RX DATA.FIFO). */
334#define SPDIF_DATA_FIFO_CSR_0_RX_CLR (1<<15)
335
336/*
337 * Rx FIFO Attention Level:
338 * 11=12-slots-full, 10=8-slots-full, 01=4-slots-full, 00=1-slot-full.
339 */
340#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT (13)
341#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_MASK \
342 (0x3 << SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT)
343#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX1_WORD_FULL \
344 (SPDIF_FIFO_ATN_LVL_ONE_SLOT << \
345 SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT)
346#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX4_WORD_FULL \
347 (SPDIF_FIFO_ATN_LVL_FOUR_SLOTS << \
348 SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT)
349#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX8_WORD_FULL \
350 (SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS << \
351 SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT)
352#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX12_WORD_FULL \
353 (SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS << \
354 SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT)
355
356
357/* Number of RX DATA.FIFO levels with valid data */
358#define SPDIF_DATA_FIFO_CSR_0_RX_DATA_FIFO_FULL_COUNT_SHIFT (8)
359#define SPDIF_DATA_FIFO_CSR_0_RX_DATA_FIFO_FULL_COUNT_FIELD \
360 ((0x1f) << SPDIF_DATA_FIFO_CSR_0_RX_DATA_FIFO_FULL_COUNT_SHIFT)
361
362/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
363#define SPDIF_DATA_FIFO_CSR_0_TX_CLR (1<<7)
364
365/*
366 * Tx FIFO Attention Level:
367 * 11=12-slots-empty, 10=8-slots-empty, 01=4-slots-empty, 00=1-slot-empty
368 */
369#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT (5)
370#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_MASK \
371 (0x3 << SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT)
372#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX1_WORD_FULL \
373 (SPDIF_FIFO_ATN_LVL_ONE_SLOT << \
374 SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT)
375#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX4_WORD_FULL \
376 (SPDIF_FIFO_ATN_LVL_FOUR_SLOTS << \
377 SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT)
378#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX8_WORD_FULL \
379 (SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS << \
380 SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT)
381#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX12_WORD_FULL \
382 (SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS << \
383 SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT)
384
385
386/* Number of Tx DATA.FIFO levels that could be filled. */
387#define SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_SHIFT (0)
388#define SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_MASK \
389 ((0x1f) << SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_SHIFT)
390
391
392#endif /* __ARCH_ARM_MACH_TEGRA_SPDIF_H */
diff --git a/arch/arm/mach-tegra/include/mach/spi.h b/arch/arm/mach-tegra/include/mach/spi.h
new file mode 100644
index 00000000000..171e4007b4b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/spi.h
@@ -0,0 +1,42 @@
1/*
2 * arch/arm/mach-tegra/include/mach/spi.h
3 *
4 * Copyright (c) 2010, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_TEGRA_SPI_H
22#define __MACH_TEGRA_SPI_H
23
24#include <linux/types.h>
25#include <linux/spi/spi.h>
26
27typedef int (*callback)(void *client_data);
28
29/**
30 * register_spi_slave_callback - registers notification callback provided by
31 * the client.
32 * This callback indicate that the controller is all set to receive/transfer
33 * data.
34 * @spi: struct spi_device - refer to linux/spi/spi.h
35 * @func: Callback function
36 * @client_data: Data to be passed in callback
37 * Context: can not sleep
38 */
39int spi_tegra_register_callback(struct spi_device *spi, callback func,
40 void *client_data);
41
42#endif
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
new file mode 100644
index 00000000000..7bc605e5dc8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/system.h
@@ -0,0 +1,34 @@
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 * Copyright (C) 2010-2011 NVIDIA Corporation
11 *
12 * This software is licensed under the terms of the GNU General Public
13 * License version 2, as published by the Free Software Foundation, and
14 * may be copied, distributed, and modified under those terms.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 */
22
23#ifndef __MACH_TEGRA_SYSTEM_H
24#define __MACH_TEGRA_SYSTEM_H
25
26#include <mach/iomap.h>
27
28extern void (*arch_reset)(char mode, const char *cmd);
29
30static inline void arch_idle(void)
31{
32}
33
34#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra-bb-power.h b/arch/arm/mach-tegra/include/mach/tegra-bb-power.h
new file mode 100644
index 00000000000..e0b7e3de326
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra-bb-power.h
@@ -0,0 +1,61 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra-bb-power.h
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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#define GPIO_INVALID UINT_MAX
18
19union tegra_bb_gpio_id {
20 struct {
21 int mdm_reset;
22 int mdm_on;
23 int ap2mdm_ack;
24 int mdm2ap_ack;
25 int ap2mdm_ack2;
26 int mdm2ap_ack2;
27 int rsvd1;
28 int rsvd2;
29 } generic;
30 struct {
31 int bb_rst;
32 int bb_on;
33 int ipc_bb_wake;
34 int ipc_ap_wake;
35 int ipc_hsic_active;
36 int ipc_hsic_sus_req;
37 int rsvd1;
38 int rsvd2;
39 } xmm;
40 struct {
41 int pwr_status;
42 int pwr_on;
43 int uart_awr;
44 int uart_cwr;
45 int usb_awr;
46 int usb_cwr;
47 int service;
48 int resout2;
49 } m7400;
50};
51
52typedef struct platform_device* (*ehci_register_cb)(void);
53typedef void (*ehci_unregister_cb)(struct platform_device *);
54
55struct tegra_bb_pdata {
56 union tegra_bb_gpio_id *id;
57 struct platform_device *device;
58 ehci_register_cb ehci_register;
59 ehci_unregister_cb ehci_unregister;
60 int bb_id;
61};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_aic326x_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_aic326x_pdata.h
new file mode 100644
index 00000000000..a47ef1982e4
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_aic326x_pdata.h
@@ -0,0 +1,39 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_aic326x_pdata.h
3 *
4 * Copyright 2011 NVIDIA, 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#ifndef __MACH_TEGRA_TLVAIC326X_H
17#define __MACH_TEGRA_TLVAIC326X_H
18
19#define HIFI_CODEC 0
20#define BASEBAND 1
21#define BT_SCO 2
22#define NUM_I2S_DEVICES 3
23
24struct baseband_config {
25 int rate;
26 int channels;
27};
28
29struct tegra_aic326x_platform_data {
30 int gpio_spkr_en;
31 int gpio_hp_det;
32 int gpio_hp_mute;
33 int gpio_int_mic_en;
34 int gpio_ext_mic_en;
35 int audio_port_id[NUM_I2S_DEVICES];
36 struct baseband_config baseband_param;
37};
38#endif
39
diff --git a/arch/arm/mach-tegra/include/mach/tegra_asoc_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_asoc_pdata.h
new file mode 100644
index 00000000000..34eb2f4fc37
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_asoc_pdata.h
@@ -0,0 +1,36 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_asoc_pdata.h
3 *
4 * Copyright 2012 NVIDIA, 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#define HIFI_CODEC 0
18#define BASEBAND 1
19#define BT_SCO 2
20#define NUM_I2S_DEVICES 3
21
22struct baseband_config {
23 int rate;
24 int channels;
25};
26
27struct tegra_asoc_platform_data {
28 int gpio_spkr_en;
29 int gpio_hp_det;
30 int gpio_hp_mute;
31 int gpio_int_mic_en;
32 int gpio_ext_mic_en;
33 unsigned int debounce_time_hp;
34 int audio_port_id[NUM_I2S_DEVICES];
35 struct baseband_config baseband_param;
36};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_dc_ext.h b/arch/arm/mach-tegra/include/mach/tegra_dc_ext.h
new file mode 100644
index 00000000000..521039283d8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_dc_ext.h
@@ -0,0 +1,77 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_dc_ext.h
3 *
4 * Copyright (C) 2011, NVIDIA Corporation
5 *
6 * Author: Robert Morell <rmorell@nvidia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 */
18
19#ifndef __MACH_TEGRA_DC_EXT_H
20#define __MACH_TEGRA_DC_EXT_H
21
22#include <linux/nvhost.h>
23
24struct tegra_dc_ext;
25
26#ifdef CONFIG_TEGRA_DC_EXTENSIONS
27int __init tegra_dc_ext_module_init(void);
28void __exit tegra_dc_ext_module_exit(void);
29
30struct tegra_dc_ext *tegra_dc_ext_register(struct nvhost_device *ndev,
31 struct tegra_dc *dc);
32void tegra_dc_ext_unregister(struct tegra_dc_ext *dc_ext);
33
34/* called by display controller on enable/disable */
35void tegra_dc_ext_enable(struct tegra_dc_ext *dc_ext);
36void tegra_dc_ext_disable(struct tegra_dc_ext *dc_ext);
37
38int tegra_dc_ext_process_hotplug(int output);
39
40#else /* CONFIG_TEGRA_DC_EXTENSIONS */
41
42static inline
43int tegra_dc_ext_module_init(void)
44{
45 return 0;
46}
47static inline
48void tegra_dc_ext_module_exit(void)
49{
50}
51
52static inline
53struct tegra_dc_ext *tegra_dc_ext_register(struct nvhost_device *ndev,
54 struct tegra_dc *dc)
55{
56 return NULL;
57}
58static inline
59void tegra_dc_ext_unregister(struct tegra_dc_ext *dc_ext)
60{
61}
62static inline
63void tegra_dc_ext_enable(struct tegra_dc_ext *dc_ext)
64{
65}
66static inline
67void tegra_dc_ext_disable(struct tegra_dc_ext *dc_ext)
68{
69}
70static inline
71int tegra_dc_ext_process_hotplug(int output)
72{
73 return 0;
74}
75#endif /* CONFIG_TEGRA_DC_EXTENSIONS */
76
77#endif /* __MACH_TEGRA_DC_EXT_H */
diff --git a/arch/arm/mach-tegra/include/mach/tegra_fb.h b/arch/arm/mach-tegra/include/mach/tegra_fb.h
new file mode 100644
index 00000000000..84ae8869b24
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_fb.h
@@ -0,0 +1,27 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_fb.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Author: Colin Cross <ccross@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18/* Platform data structure to be passed to the driver */
19struct tegra_fb_lcd_data {
20 int fb_xres;
21 int fb_yres;
22 /* Resolution of the output to the LCD. If different from the
23 framebuffer resolution, the Tegra display block will scale it */
24 int lcd_xres;
25 int lcd_yres;
26 int bits_per_pixel;
27};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h b/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h
new file mode 100644
index 00000000000..4d1a0b54f2a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h
@@ -0,0 +1,30 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.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_FIQ_DEBUGGER_H
18#define __MACH_TEGRA_FIQ_DEBUGGER_H
19
20#ifdef CONFIG_TEGRA_FIQ_DEBUGGER
21void tegra_serial_debug_init(unsigned int base, int irq,
22 struct clk *clk, int signal_irq, int wakeup_irq);
23#else
24static inline void tegra_serial_debug_init(unsigned int base, int irq,
25 struct clk *clk, int signal_irq, int wakeup_irq)
26{
27}
28#endif
29
30#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra_fuse.h b/arch/arm/mach-tegra/include/mach/tegra_fuse.h
new file mode 100644
index 00000000000..d264745c70c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_fuse.h
@@ -0,0 +1,27 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_fuse.h
3 *
4 * Tegra Public Fuse header file
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef _MACH_TEGRA_PUBLIC_FUSE_H_
20#define _MACH_TEGRA_PUBLIC_FUSE_H_
21
22int tegra_fuse_get_revision(u32 *rev);
23int tegra_fuse_get_tsensor_calibration_data(u32 *calib);
24int tegra_fuse_get_tsensor_spare_bits(u32 *spare_bits);
25
26#endif /* _MACH_TEGRA_PUBLIC_FUSE_H_*/
27
diff --git a/arch/arm/mach-tegra/include/mach/tegra_max98088_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_max98088_pdata.h
new file mode 100644
index 00000000000..eb59cf0962b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_max98088_pdata.h
@@ -0,0 +1,35 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_max98088_pdata.h
3 *
4 * Copyright 2011 NVIDIA, 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#define HIFI_CODEC 0
18#define BASEBAND 1
19#define BT_SCO 2
20#define NUM_I2S_DEVICES 3
21
22struct baseband_config {
23 int rate;
24 int channels;
25};
26
27struct tegra_max98088_platform_data {
28 int gpio_spkr_en;
29 int gpio_hp_det;
30 int gpio_hp_mute;
31 int gpio_int_mic_en;
32 int gpio_ext_mic_en;
33 int audio_port_id[NUM_I2S_DEVICES];
34 struct baseband_config baseband_param;
35};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_odm_fuses.h b/arch/arm/mach-tegra/include/mach/tegra_odm_fuses.h
new file mode 100644
index 00000000000..4ab8433dbbf
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_odm_fuses.h
@@ -0,0 +1,107 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_odm_fuses.h
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_TEGRA_ODM_FUSES_H
22#define __MACH_TEGRA_ODM_FUSES_H
23
24#define SBK_DEVKEY_STATUS_SZ sizeof(u32)
25
26/*
27 * fuse io parameters: params with sizes less than a byte are
28 * explicitly mentioned
29 */
30enum fuse_io_param {
31 DEVKEY,
32 JTAG_DIS, /* 1 bit long */
33 /*
34 * Programming the odm production fuse at the same
35 * time as the sbk or dev_key is not allowed as it is not possible to
36 * verify that the sbk or dev_key were programmed correctly.
37 */
38 ODM_PROD_MODE, /* 1 bit long */
39 SEC_BOOT_DEV_CFG,
40 SEC_BOOT_DEV_SEL, /* 3 bits long */
41 SBK,
42 SW_RSVD, /* 4 bits long */
43 IGNORE_DEV_SEL_STRAPS, /* 1 bit long */
44 ODM_RSVD,
45 SBK_DEVKEY_STATUS,
46 _PARAMS_U32 = 0x7FFFFFFF
47};
48
49#define MAX_PARAMS SBK_DEVKEY_STATUS
50
51/* the order of the members is pre-decided. please do not change */
52struct fuse_data {
53 u32 devkey;
54 u32 jtag_dis;
55 u32 odm_prod_mode;
56 u32 bootdev_cfg;
57 u32 bootdev_sel;
58 u32 sbk[4];
59 u32 sw_rsvd;
60 u32 ignore_devsel_straps;
61 u32 odm_rsvd[8];
62};
63
64/* secondary boot device options */
65enum {
66 SECBOOTDEV_SDMMC,
67 SECBOOTDEV_NOR,
68 SECBOOTDEV_SPI,
69 SECBOOTDEV_NAND,
70 SECBOOTDEV_LBANAND,
71 SECBOOTDEV_MUXONENAND,
72 _SECBOOTDEV_MAX,
73 _SECBOOTDEV_U32 = 0x7FFFFFFF
74};
75
76/*
77 * read the fuse settings
78 * @param: io_param_type - param type enum
79 * @param: size - read size in bytes
80 */
81int tegra_fuse_read(enum fuse_io_param io_param_type, u32 *data, int size);
82
83#define FLAGS_DEVKEY BIT(DEVKEY)
84#define FLAGS_JTAG_DIS BIT(JTAG_DIS)
85#define FLAGS_SBK_DEVKEY_STATUS BIT(SBK_DEVKEY_STATUS)
86#define FLAGS_ODM_PROD_MODE BIT(ODM_PROD_MODE)
87#define FLAGS_SEC_BOOT_DEV_CFG BIT(SEC_BOOT_DEV_CFG)
88#define FLAGS_SEC_BOOT_DEV_SEL BIT(SEC_BOOT_DEV_SEL)
89#define FLAGS_SBK BIT(SBK)
90#define FLAGS_SW_RSVD BIT(SW_RSVD)
91#define FLAGS_IGNORE_DEV_SEL_STRAPS BIT(IGNORE_DEV_SEL_STRAPS)
92#define FLAGS_ODMRSVD BIT(ODM_RSVD)
93
94/*
95 * Prior to invoking this routine, the caller is responsible for supplying
96 * valid fuse programming voltage.
97 *
98 * @param: pgm_data - entire data to be programmed
99 * @flags: program flags (e.g. FLAGS_DEVKEY)
100 */
101int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags);
102
103/* Disables the fuse programming until the next system reset */
104void tegra_fuse_program_disable(void);
105
106extern int (*tegra_fuse_regulator_en)(int);
107#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
new file mode 100644
index 00000000000..bfd61c46005
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
@@ -0,0 +1,45 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
3 *
4 * Copyright 2012 NVIDIA, 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_P1852_PDATA_H
18#define __MACH_TEGRA_P1852_PDATA_H
19
20#define NUM_AUDIO_CONTROLLERS 4
21
22/* data format supported */
23enum i2s_data_format {
24 format_i2s = 0x1,
25 format_dsp = 0x2,
26 format_rjm = 0x4,
27 format_ljm = 0x8,
28 format_tdm = 0x10
29};
30
31struct codec_info_s {
32 /* Name of the Codec Dai on the system */
33 char *codec_dai_name;
34 /* Name of the I2S controller dai its connected to */
35 char *cpu_dai_name;
36 char *codec_name; /* Name of the Codec Driver */
37 char *name; /* Name of the Codec-Dai-Link */
38 enum i2s_data_format i2s_format;
39 int master; /* Codec is Master or Slave */
40};
41
42struct tegra_p1852_platform_data {
43 struct codec_info_s codec_info[NUM_AUDIO_CONTROLLERS];
44};
45#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra_rt5640_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_rt5640_pdata.h
new file mode 100644
index 00000000000..87dcda8e61f
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_rt5640_pdata.h
@@ -0,0 +1,25 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_rt5640_pdata.h
3 *
4 * Copyright 2011 NVIDIA, 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
17struct tegra_rt5640_platform_data {
18 const char *codec_name;
19 const char *codec_dai_name;
20 int gpio_spkr_en;
21 int gpio_hp_det;
22 int gpio_hp_mute;
23 int gpio_int_mic_en;
24 int gpio_ext_mic_en;
25};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_smmu.h b/arch/arm/mach-tegra/include/mach/tegra_smmu.h
new file mode 100644
index 00000000000..c4401c45a48
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_smmu.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_smmu.h
3 *
4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
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#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
17struct tegra_smmu_window {
18 unsigned long start;
19 unsigned long end;
20};
21
22extern struct tegra_smmu_window *tegra_smmu_window(int wnum);
23extern int tegra_smmu_window_count(void);
24#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra_usb_modem_power.h b/arch/arm/mach-tegra/include/mach/tegra_usb_modem_power.h
new file mode 100644
index 00000000000..0ce7fa40eb2
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_usb_modem_power.h
@@ -0,0 +1,47 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_usb_modem_power.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef __MACH_TEGRA_USB_MODEM_POWER_H
22#define __MACH_TEGRA_USB_MODEM_POWER_H
23
24#include <linux/interrupt.h>
25
26/* modem capabilities */
27#define TEGRA_MODEM_AUTOSUSPEND 0x01
28#define TEGRA_MODEM_RECOVERY 0x02
29
30/* modem operations */
31struct tegra_modem_operations {
32 int (*init) (void); /* modem init */
33 void (*start) (void); /* modem start */
34 void (*stop) (void); /* modem stop */
35 void (*suspend) (void); /* send L3 hint during system suspend */
36 void (*resume) (void); /* send L3->0 hint during system resume */
37 void (*reset) (void); /* modem reset */
38};
39
40/* tegra usb modem power platform data */
41struct tegra_usb_modem_power_platform_data {
42 const struct tegra_modem_operations *ops;
43 unsigned int wake_gpio; /* remote wakeup gpio */
44 unsigned int flags; /* remote wakeup irq flags */
45};
46
47#endif /* __MACH_TEGRA_USB_MODEM_POWER_H */
diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8753_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_wm8753_pdata.h
new file mode 100644
index 00000000000..944e410b4ae
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_wm8753_pdata.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
3 *
4 * Copyright 2011 NVIDIA, 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
17struct tegra_wm8753_platform_data {
18 int gpio_spkr_en;
19 int gpio_hp_det;
20 int gpio_hp_mute;
21 int gpio_int_mic_en;
22 int gpio_ext_mic_en;
23 unsigned int debounce_time_hp;
24};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
new file mode 100644
index 00000000000..9d293344a7f
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
@@ -0,0 +1,23 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
3 *
4 * Copyright 2011 NVIDIA, 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
17struct tegra_wm8903_platform_data {
18 int gpio_spkr_en;
19 int gpio_hp_det;
20 int gpio_hp_mute;
21 int gpio_int_mic_en;
22 int gpio_ext_mic_en;
23};
diff --git a/arch/arm/mach-tegra/include/mach/thermal.h b/arch/arm/mach-tegra/include/mach/thermal.h
new file mode 100644
index 00000000000..ab7b34492d9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/thermal.h
@@ -0,0 +1,62 @@
1/*
2 * arch/arm/mach-tegra/thermal.h
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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_THERMAL_H
18#define __MACH_THERMAL_H
19
20/* All units in millicelsius */
21struct tegra_thermal_data {
22 long temp_throttle;
23 long temp_shutdown;
24 long temp_offset;
25#ifdef CONFIG_TEGRA_EDP_LIMITS
26 long edp_offset;
27 long hysteresis_edp;
28#endif
29#ifdef CONFIG_TEGRA_THERMAL_SYSFS
30 int tc1;
31 int tc2;
32 long passive_delay;
33#else
34 long hysteresis_throttle;
35#endif
36};
37
38struct tegra_thermal_device {
39 char *name;
40 void *data;
41 long offset;
42 int (*get_temp) (void *, long *);
43 int (*get_temp_low)(void *, long *);
44 int (*set_limits) (void *, long, long);
45 int (*set_alert)(void *, void (*)(void *), void *);
46 int (*set_shutdown_temp)(void *, long);
47};
48
49#ifndef CONFIG_ARCH_TEGRA_2x_SOC
50int tegra_thermal_init(struct tegra_thermal_data *data);
51int tegra_thermal_set_device(struct tegra_thermal_device *device);
52int tegra_thermal_exit(void);
53#else
54static inline int tegra_thermal_init(struct tegra_thermal_data *data)
55{ return 0; }
56static inline int tegra_thermal_set_device(struct tegra_thermal_device *dev)
57{ return 0; }
58static inline int tegra_thermal_exit(void)
59{ return 0; }
60#endif
61
62#endif /* __MACH_THERMAL_H */
diff --git a/arch/arm/mach-tegra/include/mach/tsensor.h b/arch/arm/mach-tegra/include/mach/tsensor.h
new file mode 100644
index 00000000000..190a38586c5
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tsensor.h
@@ -0,0 +1,48 @@
1/*
2 * arch/arm/mach-tegra/include/mach/tsensor.h
3 *
4 * Tegra tsensor header file
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __MACH_TEGRA_TSENSOR_H
20#define __MACH_TEGRA_TSENSOR_H
21
22#include <linux/types.h>
23
24#include <mach/edp.h>
25
26#define MAX_ZONES 16
27
28struct tegra_tsensor_data;
29
30struct tegra_tsensor_platform_data {
31 void (*probe_callback)(struct tegra_tsensor_data *);
32};
33
34int tsensor_thermal_get_temp(struct tegra_tsensor_data *data,
35 long *milli_temp);
36int tsensor_thermal_get_temp_low(struct tegra_tsensor_data *data,
37 long *milli_temp);
38int tsensor_thermal_set_limits(struct tegra_tsensor_data *data,
39 long lo_limit_milli,
40 long hi_limit_milli);
41int tsensor_thermal_set_alert(struct tegra_tsensor_data *data,
42 void (*alert_func)(void *),
43 void *alert_data);
44int tsensor_thermal_set_shutdown_temp(struct tegra_tsensor_data *data,
45 long shutdown_temp_milli);
46
47#endif /* __MACH_TEGRA_TSENSOR_H */
48
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
new file mode 100644
index 00000000000..b5bf001d613
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -0,0 +1,166 @@
1/*
2 * arch/arm/mach-tegra/include/mach/usb_phy.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
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#ifndef __MACH_USB_PHY_H
19#define __MACH_USB_PHY_H
20
21#include <linux/clk.h>
22#include <linux/regulator/consumer.h>
23#include <linux/usb/otg.h>
24#include <linux/platform_data/tegra_usb.h>
25
26struct tegra_utmip_config {
27 u8 hssync_start_delay;
28 u8 elastic_limit;
29 u8 idle_wait_delay;
30 u8 term_range_adj;
31 u8 xcvr_setup;
32 signed char xcvr_setup_offset;
33 u8 xcvr_use_fuses;
34 u8 xcvr_lsfslew;
35 u8 xcvr_lsrslew;
36};
37
38struct tegra_ulpi_trimmer {
39 u8 shadow_clk_delay; /* 0 ~ 31 */
40 u8 clock_out_delay; /* 0 ~ 31 */
41 u8 data_trimmer; /* 0 ~ 7 */
42 u8 stpdirnxt_trimmer; /* 0 ~ 7 */
43};
44
45struct tegra_ulpi_config {
46 int enable_gpio;
47 int reset_gpio;
48 const char *clk;
49 const struct tegra_ulpi_trimmer *trimmer;
50 int (*pre_phy_on)(void);
51 int (*post_phy_on)(void);
52 int (*pre_phy_off)(void);
53 int (*post_phy_off)(void);
54 void (*phy_restore_start)(void);
55 void (*phy_restore_end)(void);
56 int phy_restore_gpio; /* null phy restore ack from device */
57 int ulpi_dir_gpio; /* ulpi dir */
58 int ulpi_d0_gpio; /* usb linestate[0] */
59 int ulpi_d1_gpio; /* usb linestate[1] */
60};
61
62struct tegra_uhsic_config {
63 int enable_gpio;
64 int reset_gpio;
65 u8 sync_start_delay;
66 u8 idle_wait_delay;
67 u8 term_range_adj;
68 u8 elastic_underrun_limit;
69 u8 elastic_overrun_limit;
70 int (*postsuspend)(void);
71 int (*preresume)(void);
72 int (*usb_phy_ready)(void);
73 int (*post_phy_off)(void);
74};
75
76enum tegra_usb_phy_port_speed {
77 TEGRA_USB_PHY_PORT_SPEED_FULL = 0,
78 TEGRA_USB_PHY_PORT_SPEED_LOW,
79 TEGRA_USB_PHY_PORT_SPEED_HIGH,
80};
81
82enum tegra_usb_phy_mode {
83 TEGRA_USB_PHY_MODE_DEVICE,
84 TEGRA_USB_PHY_MODE_HOST,
85};
86
87struct usb_phy_plat_data {
88 int instance;
89 int vbus_irq;
90 int vbus_gpio;
91 char * vbus_reg_supply;
92};
93
94struct tegra_xtal_freq;
95
96struct tegra_usb_phy {
97 int instance;
98 const struct tegra_xtal_freq *freq;
99 void __iomem *regs;
100 void __iomem *pad_regs;
101 struct clk *clk;
102 struct clk *pll_u;
103 struct clk *pad_clk;
104 enum tegra_usb_phy_mode mode;
105 void *config;
106 struct regulator *reg_vdd;
107 struct regulator *reg_vbus;
108 enum tegra_usb_phy_type usb_phy_type;
109 bool regulator_on;
110 struct otg_transceiver *ulpi;
111 int initialized;
112 bool power_on;
113 bool remote_wakeup;
114 int hotplug;
115 unsigned int xcvr_setup_value;
116};
117
118typedef int (*tegra_phy_fp)(struct tegra_usb_phy *phy, bool is_dpd);
119typedef void (*tegra_phy_restore_start_fp)(struct tegra_usb_phy *phy,
120 enum tegra_usb_phy_port_speed);
121typedef void (*tegra_phy_restore_end_fp)(struct tegra_usb_phy *phy);
122
123struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
124 void *config, enum tegra_usb_phy_mode phy_mode,
125 enum tegra_usb_phy_type usb_phy_type);
126
127int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd);
128
129void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy);
130
131void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy);
132
133void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd);
134
135void tegra_usb_phy_postsuspend(struct tegra_usb_phy *phy, bool is_dpd);
136
137void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool is_dpd);
138
139void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd);
140
141void tegra_ehci_pre_reset(struct tegra_usb_phy *phy, bool is_dpd);
142
143void tegra_ehci_post_reset(struct tegra_usb_phy *phy, bool is_dpd);
144
145void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
146 enum tegra_usb_phy_port_speed port_speed);
147
148void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy);
149
150void tegra_usb_phy_close(struct tegra_usb_phy *phy);
151
152int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy);
153
154int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy);
155
156int tegra_usb_phy_bus_idle(struct tegra_usb_phy *phy);
157
158bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy);
159
160bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy);
161
162int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size);
163
164bool tegra_usb_phy_is_remotewake_detected(struct tegra_usb_phy *phy);
165
166#endif /* __MACH_USB_PHY_H */
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h
new file mode 100644
index 00000000000..db488e890b9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/vmalloc.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-tegra/include/mach/vmalloc.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_VMALLOC_H
22#define __MACH_TEGRA_VMALLOC_H
23
24#include <asm/sizes.h>
25
26#define VMALLOC_END 0xF8000000UL
27
28#endif
diff --git a/arch/arm/mach-tegra/include/mach/w1.h b/arch/arm/mach-tegra/include/mach/w1.h
new file mode 100644
index 00000000000..c96df7abdf9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/w1.h
@@ -0,0 +1,84 @@
1/*
2 * include/mach/w1.h
3 *
4 * Copyright (C) 2010 Motorola, Inc
5 * Author: Andrei Warkentin <andreiw@motorola.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#ifndef __ASM_ARM_ARCH_TEGRA_W1_H
18#define __ASM_ARM_ARCH_TEGRA_W1_H
19
20struct tegra_w1_timings {
21
22 /* tsu, trelease, trdv, tlow0, tlow1 and tslot are formed
23 into the value written into OWR_RST_PRESENCE_TCTL_0 register. */
24
25 /* Read data setup, Tsu = N owr clks, Range = tsu < 1,
26 Typical value = 0x1 */
27 uint32_t tsu;
28
29 /* Release 1-wire time, Trelease = N owr clks,
30 Range = 0 <= trelease < 45, Typical value = 0xf */
31 uint32_t trelease;
32
33 /* Read data valid time, Trdv = N+1 owr clks, Range = Exactly 15 */
34 uint32_t trdv;
35
36 /* Write zero time low, Tlow0 = N+1 owr clks,
37 Range = 60 <= tlow0 < tslot < 120, typical value = 0x3c. */
38 uint32_t tlow0;
39
40 /* Write one time low, or TLOWR both are same Tlow1 = N+1 owr clks,
41 Range = 1 <= tlow1 < 15 TlowR = N+1 owr clks,
42 Range = 1 <= tlowR < 15, Typical value = 0x1. */
43 uint32_t tlow1;
44
45 /* Active time slot for write or read data, Tslot = N+1 owr clks,
46 Range = 60 <= tslot < 120, Typical value = 0x77. */
47 uint32_t tslot;
48
49 /* tpdl, tpdh, trstl, trsth are formed in the the value written
50 into the OWR_RST_PRESENCE_TCTL_0 register. */
51
52 /* Tpdl = N owr clks, Range = 60 <= tpdl < 240,
53 Typical value = 0x78. */
54 uint32_t tpdl;
55
56 /* Tpdh = N+1 owr clks, Range = 15 <= tpdh < 60.
57 Typical value = 0x1e. */
58 uint32_t tpdh;
59
60 /* Trstl = N+1 owr clks, Range = 480 <= trstl < infinity,
61 Typical value = 0x1df. */
62 uint32_t trstl;
63
64 /* Trsth = N+1 owr clks, Range = 480 <= trsth < infinity,
65 Typical value = 0x1df. */
66 uint32_t trsth;
67
68 /* Read data sample clock. Should be <= to (tlow1 - 6) clks,
69 6 clks are used for deglitch. If deglitch bypassed it
70 is 3 clks, Typical value = 0x7. */
71 uint32_t rdsclk;
72
73 /* Presence sample clock. Should be <= to (tpdl - 6) clks,
74 6 clks are used for deglitch. If deglitch bypassed it is 3 clks,
75 Typical value = 0x50. */
76 uint32_t psclk;
77};
78
79struct tegra_w1_platform_data {
80 const char *clk_id;
81 struct tegra_w1_timings *timings;
82};
83
84#endif
diff --git a/arch/arm/mach-tegra/iovmm-gart.c b/arch/arm/mach-tegra/iovmm-gart.c
new file mode 100644
index 00000000000..ad1ce3a7afc
--- /dev/null
+++ b/arch/arm/mach-tegra/iovmm-gart.c
@@ -0,0 +1,354 @@
1/*
2 * arch/arm/mach-tegra/iovmm-gart.c
3 *
4 * Tegra I/O VMM implementation for GART devices in Tegra and Tegra 2 series
5 * systems-on-a-chip.
6 *
7 * Copyright (c) 2010-2012, NVIDIA Corporation.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/spinlock.h>
27#include <linux/slab.h>
28#include <linux/vmalloc.h>
29#include <linux/mm.h>
30#include <linux/io.h>
31
32#include <asm/cacheflush.h>
33
34#include <mach/iovmm.h>
35
36#define GART_CONFIG 0x24
37#define GART_ENTRY_ADDR 0x28
38#define GART_ENTRY_DATA 0x2c
39
40#define VMM_NAME "iovmm-gart"
41#define DRIVER_NAME "tegra_gart"
42
43#define GART_PAGE_SHIFT 12
44#define GART_PAGE_SIZE (1 << GART_PAGE_SHIFT)
45#define GART_PAGE_MASK (~(GART_PAGE_SIZE - 1))
46
47struct gart_device {
48 void __iomem *regs;
49 u32 *savedata;
50 u32 page_count; /* total remappable size */
51 tegra_iovmm_addr_t iovmm_base; /* offset to apply to vmm_area */
52 spinlock_t pte_lock;
53 struct tegra_iovmm_device iovmm;
54 struct tegra_iovmm_domain domain;
55 bool enable;
56};
57
58/*
59 * Any interaction between any block on PPSB and a block on APB or AHB
60 * must have these read-back to ensure the APB/AHB bus transaction is
61 * complete before initiating activity on the PPSB block.
62 */
63#define FLUSH_GART_REGS(gart) (void)readl((gart)->regs + GART_CONFIG)
64
65static inline void gart_set_pte(struct gart_device *gart,
66 tegra_iovmm_addr_t offs, u32 pte)
67{
68 writel(offs, gart->regs + GART_ENTRY_ADDR);
69 writel(pte, gart->regs + GART_ENTRY_DATA);
70}
71
72static int gart_map(struct tegra_iovmm_domain *, struct tegra_iovmm_area *);
73static void gart_unmap(struct tegra_iovmm_domain *,
74 struct tegra_iovmm_area *, bool);
75static void gart_map_pfn(struct tegra_iovmm_domain *,
76 struct tegra_iovmm_area *, tegra_iovmm_addr_t, unsigned long);
77static struct tegra_iovmm_domain *gart_alloc_domain(
78 struct tegra_iovmm_device *, struct tegra_iovmm_client *);
79
80static int gart_probe(struct platform_device *);
81static int gart_remove(struct platform_device *);
82static int gart_suspend(struct tegra_iovmm_device *dev);
83static void gart_resume(struct tegra_iovmm_device *dev);
84
85
86static struct tegra_iovmm_device_ops tegra_iovmm_gart_ops = {
87 .map = gart_map,
88 .unmap = gart_unmap,
89 .map_pfn = gart_map_pfn,
90 .alloc_domain = gart_alloc_domain,
91 .suspend = gart_suspend,
92 .resume = gart_resume,
93};
94
95static struct platform_driver tegra_iovmm_gart_drv = {
96 .probe = gart_probe,
97 .remove = gart_remove,
98 .driver = {
99 .name = DRIVER_NAME,
100 },
101};
102
103static int gart_suspend(struct tegra_iovmm_device *dev)
104{
105 struct gart_device *gart = container_of(dev, struct gart_device, iovmm);
106 unsigned int i;
107 unsigned long reg;
108
109 if (!gart)
110 return -ENODEV;
111
112 if (!gart->enable)
113 return 0;
114
115 spin_lock(&gart->pte_lock);
116 reg = gart->iovmm_base;
117 for (i = 0; i < gart->page_count; i++) {
118 writel(reg, gart->regs + GART_ENTRY_ADDR);
119 gart->savedata[i] = readl(gart->regs + GART_ENTRY_DATA);
120 reg += GART_PAGE_SIZE;
121 }
122 spin_unlock(&gart->pte_lock);
123 return 0;
124}
125
126static void do_gart_setup(struct gart_device *gart, const u32 *data)
127{
128 unsigned long reg;
129 unsigned int i;
130
131 reg = gart->iovmm_base;
132 for (i = 0; i < gart->page_count; i++) {
133 gart_set_pte(gart, reg, data ? data[i] : 0);
134 reg += GART_PAGE_SIZE;
135 }
136 writel(1, gart->regs + GART_CONFIG);
137 FLUSH_GART_REGS(gart);
138}
139
140static void gart_resume(struct tegra_iovmm_device *dev)
141{
142 struct gart_device *gart = container_of(dev, struct gart_device, iovmm);
143
144 if (!gart || !gart->enable || (gart->enable && !gart->savedata))
145 return;
146
147 spin_lock(&gart->pte_lock);
148 do_gart_setup(gart, gart->savedata);
149 spin_unlock(&gart->pte_lock);
150}
151
152static int gart_remove(struct platform_device *pdev)
153{
154 struct gart_device *gart = platform_get_drvdata(pdev);
155
156 if (!gart)
157 return 0;
158
159 if (gart->enable)
160 writel(0, gart->regs + GART_CONFIG);
161
162 gart->enable = 0;
163 platform_set_drvdata(pdev, NULL);
164 tegra_iovmm_unregister(&gart->iovmm);
165 if (gart->savedata)
166 vfree(gart->savedata);
167 if (gart->regs)
168 iounmap(gart->regs);
169 kfree(gart);
170 return 0;
171}
172
173static int gart_probe(struct platform_device *pdev)
174{
175 struct gart_device *gart;
176 struct resource *res, *res_remap;
177 void __iomem *gart_regs;
178 int e;
179
180 if (!pdev) {
181 pr_err(DRIVER_NAME ": platform_device required\n");
182 return -ENODEV;
183 }
184
185 if (PAGE_SHIFT != GART_PAGE_SHIFT) {
186 pr_err(DRIVER_NAME ": GART and CPU page size must match\n");
187 return -ENXIO;
188 }
189
190 /* the GART memory aperture is required */
191 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
192 res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1);
193
194 if (!res || !res_remap) {
195 pr_err(DRIVER_NAME ": GART memory aperture expected\n");
196 return -ENXIO;
197 }
198 gart = kzalloc(sizeof(*gart), GFP_KERNEL);
199 if (!gart) {
200 pr_err(DRIVER_NAME ": failed to allocate tegra_iovmm_device\n");
201 return -ENOMEM;
202 }
203
204 gart_regs = ioremap(res->start, res->end - res->start + 1);
205 if (!gart_regs) {
206 pr_err(DRIVER_NAME ": failed to remap GART registers\n");
207 e = -ENXIO;
208 goto fail;
209 }
210
211 gart->iovmm.name = VMM_NAME;
212 gart->iovmm.ops = &tegra_iovmm_gart_ops;
213 gart->iovmm.pgsize_bits = GART_PAGE_SHIFT;
214 spin_lock_init(&gart->pte_lock);
215
216 platform_set_drvdata(pdev, gart);
217
218 e = tegra_iovmm_register(&gart->iovmm);
219 if (e)
220 goto fail;
221
222 e = tegra_iovmm_domain_init(&gart->domain, &gart->iovmm,
223 (tegra_iovmm_addr_t)res_remap->start,
224 (tegra_iovmm_addr_t)res_remap->end+1);
225 if (e)
226 goto fail;
227
228 gart->regs = gart_regs;
229 gart->iovmm_base = (tegra_iovmm_addr_t)res_remap->start;
230 gart->page_count = resource_size(res_remap);
231 gart->page_count >>= GART_PAGE_SHIFT;
232
233 gart->savedata = vmalloc(sizeof(u32) * gart->page_count);
234 if (!gart->savedata) {
235 pr_err(DRIVER_NAME ": failed to allocate context save area\n");
236 e = -ENOMEM;
237 goto fail;
238 }
239
240 do_gart_setup(gart, NULL);
241 gart->enable = 1;
242
243 return 0;
244
245fail:
246 if (gart_regs)
247 iounmap(gart_regs);
248 if (gart && gart->savedata)
249 vfree(gart->savedata);
250 kfree(gart);
251 return e;
252}
253
254static int __devinit gart_init(void)
255{
256 return platform_driver_register(&tegra_iovmm_gart_drv);
257}
258
259static void __exit gart_exit(void)
260{
261 platform_driver_unregister(&tegra_iovmm_gart_drv);
262}
263
264#define GART_PTE(_pfn) (0x80000000ul | ((_pfn) << PAGE_SHIFT))
265
266
267static int gart_map(struct tegra_iovmm_domain *domain,
268 struct tegra_iovmm_area *iovma)
269{
270 struct gart_device *gart =
271 container_of(domain, struct gart_device, domain);
272 unsigned long gart_page, count;
273 unsigned int i;
274
275 gart_page = iovma->iovm_start;
276 count = iovma->iovm_length >> GART_PAGE_SHIFT;
277
278 for (i = 0; i < count; i++) {
279 unsigned long pfn;
280
281 pfn = iovma->ops->lock_makeresident(iovma, i<<PAGE_SHIFT);
282 if (!pfn_valid(pfn))
283 goto fail;
284
285 spin_lock(&gart->pte_lock);
286
287 gart_set_pte(gart, gart_page, GART_PTE(pfn));
288 FLUSH_GART_REGS(gart);
289 gart_page += GART_PAGE_SIZE;
290
291 spin_unlock(&gart->pte_lock);
292 }
293
294 return 0;
295
296fail:
297 spin_lock(&gart->pte_lock);
298 while (i--) {
299 iovma->ops->release(iovma, i << PAGE_SHIFT);
300 gart_page -= GART_PAGE_SIZE;
301 gart_set_pte(gart, gart_page, 0);
302 }
303 FLUSH_GART_REGS(gart);
304 spin_unlock(&gart->pte_lock);
305
306 return -ENOMEM;
307}
308
309static void gart_unmap(struct tegra_iovmm_domain *domain,
310 struct tegra_iovmm_area *iovma, bool decommit)
311{
312 struct gart_device *gart =
313 container_of(domain, struct gart_device, domain);
314 unsigned long gart_page, count;
315 unsigned int i;
316
317 count = iovma->iovm_length >> GART_PAGE_SHIFT;
318 gart_page = iovma->iovm_start;
319
320 spin_lock(&gart->pte_lock);
321 for (i = 0; i < count; i++) {
322 if (iovma->ops && iovma->ops->release)
323 iovma->ops->release(iovma, i << PAGE_SHIFT);
324
325 gart_set_pte(gart, gart_page, 0);
326 gart_page += GART_PAGE_SIZE;
327 }
328 FLUSH_GART_REGS(gart);
329 spin_unlock(&gart->pte_lock);
330}
331
332static void gart_map_pfn(struct tegra_iovmm_domain *domain,
333 struct tegra_iovmm_area *iovma, tegra_iovmm_addr_t offs,
334 unsigned long pfn)
335{
336 struct gart_device *gart =
337 container_of(domain, struct gart_device, domain);
338
339 BUG_ON(!pfn_valid(pfn));
340 spin_lock(&gart->pte_lock);
341 gart_set_pte(gart, offs, GART_PTE(pfn));
342 FLUSH_GART_REGS(gart);
343 spin_unlock(&gart->pte_lock);
344}
345
346static struct tegra_iovmm_domain *gart_alloc_domain(
347 struct tegra_iovmm_device *dev, struct tegra_iovmm_client *client)
348{
349 struct gart_device *gart = container_of(dev, struct gart_device, iovmm);
350 return &gart->domain;
351}
352
353subsys_initcall(gart_init);
354module_exit(gart_exit);
diff --git a/arch/arm/mach-tegra/iovmm-smmu.c b/arch/arm/mach-tegra/iovmm-smmu.c
new file mode 100644
index 00000000000..170afd15f1c
--- /dev/null
+++ b/arch/arm/mach-tegra/iovmm-smmu.c
@@ -0,0 +1,1350 @@
1/*
2 * arch/arm/mach-tegra/iovmm-smmu.c
3 *
4 * Tegra I/O VMM implementation for SMMU devices for Tegra 3 series
5 * systems-on-a-chip.
6 *
7 * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/spinlock.h>
27#include <linux/slab.h>
28#include <linux/vmalloc.h>
29#include <linux/mm.h>
30#include <linux/pagemap.h>
31#include <linux/sysfs.h>
32#include <linux/device.h>
33#include <linux/sched.h>
34#include <linux/io.h>
35
36#include <asm/page.h>
37#include <asm/cacheflush.h>
38
39#include <mach/iovmm.h>
40#include <mach/iomap.h>
41#include <mach/tegra_smmu.h>
42
43#ifndef CONFIG_ARCH_TEGRA_2x_SOC
44/*
45 * ALL-CAP macros copied from armc.h
46 */
47#define MC_SMMU_CONFIG_0 0x10
48#define MC_SMMU_CONFIG_0_SMMU_ENABLE_DISABLE 0
49#define MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE 1
50
51#define MC_SMMU_TLB_CONFIG_0 0x14
52#define MC_SMMU_TLB_CONFIG_0_TLB_STATS__MASK (1 << 31)
53#define MC_SMMU_TLB_CONFIG_0_TLB_STATS__ENABLE (1 << 31)
54#define MC_SMMU_TLB_CONFIG_0_TLB_HIT_UNDER_MISS__ENABLE (1 << 29)
55#define MC_SMMU_TLB_CONFIG_0_TLB_ACTIVE_LINES__VALUE 0x10
56#define MC_SMMU_TLB_CONFIG_0_RESET_VAL 0x20000010
57
58#define MC_SMMU_PTC_CONFIG_0 0x18
59#define MC_SMMU_PTC_CONFIG_0_PTC_STATS__MASK (1 << 31)
60#define MC_SMMU_PTC_CONFIG_0_PTC_STATS__ENABLE (1 << 31)
61#define MC_SMMU_PTC_CONFIG_0_PTC_CACHE__ENABLE (1 << 29)
62#define MC_SMMU_PTC_CONFIG_0_PTC_INDEX_MAP__PATTERN 0x3f
63#define MC_SMMU_PTC_CONFIG_0_RESET_VAL 0x2000003f
64
65#define MC_SMMU_PTB_ASID_0 0x1c
66#define MC_SMMU_PTB_ASID_0_CURRENT_ASID_SHIFT 0
67
68#define MC_SMMU_PTB_DATA_0 0x20
69#define MC_SMMU_PTB_DATA_0_RESET_VAL 0
70#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29
71#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30
72#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31
73
74#define MC_SMMU_TLB_FLUSH_0 0x30
75#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_ALL 0
76#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_SECTION 2
77#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_GROUP 3
78#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_SHIFT 29
79#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_DISABLE 0
80#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_ENABLE 1
81#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_SHIFT 31
82
83#define MC_SMMU_PTC_FLUSH_0 0x34
84#define MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_TYPE_ALL 0
85#define MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_TYPE_ADR 1
86#define MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_ADR_SHIFT 4
87
88#define MC_SMMU_ASID_SECURITY_0 0x38
89
90#define MC_SMMU_STATS_TLB_HIT_COUNT_0 0x1f0
91#define MC_SMMU_STATS_TLB_MISS_COUNT_0 0x1f4
92#define MC_SMMU_STATS_PTC_HIT_COUNT_0 0x1f8
93#define MC_SMMU_STATS_PTC_MISS_COUNT_0 0x1fc
94
95#define MC_SMMU_TRANSLATION_ENABLE_0_0 0x228
96#define MC_SMMU_TRANSLATION_ENABLE_1_0 0x22c
97#define MC_SMMU_TRANSLATION_ENABLE_2_0 0x230
98
99#define MC_SMMU_AFI_ASID_0 0x238 /* PCIE */
100#define MC_SMMU_AVPC_ASID_0 0x23c /* AVP */
101#define MC_SMMU_DC_ASID_0 0x240 /* Display controller */
102#define MC_SMMU_DCB_ASID_0 0x244 /* Display controller B */
103#define MC_SMMU_EPP_ASID_0 0x248 /* Encoder pre-processor */
104#define MC_SMMU_G2_ASID_0 0x24c /* 2D engine */
105#define MC_SMMU_HC_ASID_0 0x250 /* Host1x */
106#define MC_SMMU_HDA_ASID_0 0x254 /* High-def audio */
107#define MC_SMMU_ISP_ASID_0 0x258 /* Image signal processor */
108#define MC_SMMU_MPE_ASID_0 0x264 /* MPEG encoder */
109#define MC_SMMU_NV_ASID_0 0x268 /* (3D) */
110#define MC_SMMU_NV2_ASID_0 0x26c /* (3D) */
111#define MC_SMMU_PPCS_ASID_0 0x270 /* AHB */
112#define MC_SMMU_SATA_ASID_0 0x278 /* SATA */
113#define MC_SMMU_VDE_ASID_0 0x27c /* Video decoder */
114#define MC_SMMU_VI_ASID_0 0x280 /* Video input */
115
116#define SMMU_PDE_NEXT_SHIFT 28
117
118/* Copied from arahb_arbc.h */
119#define AHB_ARBITRATION_XBAR_CTRL_0 0xe0
120#define AHB_ARBITRATION_XBAR_CTRL_0_SMMU_INIT_DONE_DONE 1
121#define AHB_ARBITRATION_XBAR_CTRL_0_SMMU_INIT_DONE_SHIFT 17
122
123#endif
124
125#define MC_SMMU_NUM_ASIDS 4
126#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_SECTION__MASK 0xffc00000
127#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */
128#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_GROUP__MASK 0xffffc000
129#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_GROUP__SHIFT 12 /* right shift */
130#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA(iova, which) \
131 ((((iova) & MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_##which##__MASK) >> \
132 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_##which##__SHIFT) | \
133 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_##which)
134#define MC_SMMU_PTB_ASID_0_CURRENT_ASID(n) \
135 ((n) << MC_SMMU_PTB_ASID_0_CURRENT_ASID_SHIFT)
136#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_disable \
137 (MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_DISABLE << \
138 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_SHIFT)
139#define MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH__ENABLE \
140 (MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_ENABLE << \
141 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_SHIFT)
142
143#define VMM_NAME "iovmm-smmu"
144#define DRIVER_NAME "tegra_smmu"
145
146#define SMMU_PAGE_SHIFT 12
147#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
148
149#define SMMU_PDIR_COUNT 1024
150#define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT)
151#define SMMU_PTBL_COUNT 1024
152#define SMMU_PTBL_SIZE (sizeof(unsigned long) * SMMU_PTBL_COUNT)
153#define SMMU_PDIR_SHIFT 12
154#define SMMU_PDE_SHIFT 12
155#define SMMU_PTE_SHIFT 12
156#define SMMU_PFN_MASK 0x000fffff
157
158#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
159#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
160#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
161
162#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
163#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
164#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
165#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
166#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
167
168#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
169
170#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
171#define _PDE_ATTR_N (_PDE_ATTR | _PDE_NEXT)
172#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
173
174#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
175#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
176
177#define SMMU_MK_PDIR(page, attr) \
178 ((page_to_phys(page) >> SMMU_PDIR_SHIFT) | (attr))
179#define SMMU_MK_PDE(page, attr) \
180 (unsigned long)((page_to_phys(page) >> SMMU_PDE_SHIFT) | (attr))
181#define SMMU_EX_PTBL_PAGE(pde) \
182 pfn_to_page((unsigned long)(pde) & SMMU_PFN_MASK)
183#define SMMU_PFN_TO_PTE(pfn, attr) (unsigned long)((pfn) | (attr))
184
185#define SMMU_ASID_ENABLE(asid) ((asid) | (1 << 31))
186#define SMMU_ASID_DISABLE 0
187#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0))
188
189/* Keep this as a "natural" enumeration (no assignments) */
190enum smmu_hwclient {
191 HWC_AFI,
192 HWC_AVPC,
193 HWC_DC,
194 HWC_DCB,
195 HWC_EPP,
196 HWC_G2,
197 HWC_HC,
198 HWC_HDA,
199 HWC_ISP,
200 HWC_MPE,
201 HWC_NV,
202 HWC_NV2,
203 HWC_PPCS,
204 HWC_SATA,
205 HWC_VDE,
206 HWC_VI,
207
208 HWC_COUNT
209};
210
211struct smmu_hwc_state {
212 unsigned long reg;
213 unsigned long enable_disable;
214};
215
216/* Hardware client mapping initializer */
217#define HWC_INIT(client) \
218 [HWC_##client] = {MC_SMMU_##client##_ASID_0, SMMU_ASID_DISABLE},
219
220static const struct smmu_hwc_state smmu_hwc_state_init[] = {
221 HWC_INIT(AFI)
222 HWC_INIT(AVPC)
223 HWC_INIT(DC)
224 HWC_INIT(DCB)
225 HWC_INIT(EPP)
226 HWC_INIT(G2)
227 HWC_INIT(HC)
228 HWC_INIT(HDA)
229 HWC_INIT(ISP)
230 HWC_INIT(MPE)
231 HWC_INIT(NV)
232 HWC_INIT(NV2)
233 HWC_INIT(PPCS)
234 HWC_INIT(SATA)
235 HWC_INIT(VDE)
236 HWC_INIT(VI)
237};
238
239
240struct domain_hwc_map {
241 const char *dev_name;
242 const enum smmu_hwclient *hwcs;
243 const unsigned int nr_hwcs;
244};
245
246/* Enable all hardware clients for SMMU translation */
247static const enum smmu_hwclient nvmap_hwcs[] = {
248 HWC_AFI,
249 HWC_AVPC,
250 HWC_DC,
251 HWC_DCB,
252 HWC_EPP,
253 HWC_G2,
254 HWC_HC,
255 HWC_HDA,
256 HWC_ISP,
257 HWC_MPE,
258 HWC_NV,
259 HWC_NV2,
260 HWC_PPCS,
261 HWC_SATA,
262 HWC_VDE,
263 HWC_VI
264};
265
266static const struct domain_hwc_map smmu_hwc_map[] = {
267 {
268 .dev_name = "nvmap",
269 .hwcs = nvmap_hwcs,
270 .nr_hwcs = ARRAY_SIZE(nvmap_hwcs),
271 },
272};
273
274/*
275 * Per address space
276 */
277struct smmu_as {
278 struct smmu_device *smmu; /* back pointer to container */
279 unsigned int asid;
280 const struct domain_hwc_map *hwclients;
281 struct mutex lock; /* for pagetable */
282 struct tegra_iovmm_domain domain;
283 struct page *pdir_page;
284 unsigned long pdir_attr;
285 unsigned long pde_attr;
286 unsigned long pte_attr;
287 unsigned int *pte_count;
288 struct device sysfs_dev;
289 int sysfs_use_count;
290};
291
292/*
293 * Per SMMU device
294 */
295struct smmu_device {
296 void __iomem *regs, *regs_ahbarb;
297 tegra_iovmm_addr_t iovmm_base; /* remappable base address */
298 unsigned long page_count; /* total remappable size */
299 spinlock_t lock;
300 char *name;
301 struct tegra_iovmm_device iovmm_dev;
302 int num_ases;
303 struct smmu_as *as; /* Run-time allocated array */
304 struct smmu_hwc_state hwc_state[HWC_COUNT];
305 struct device sysfs_dev;
306 int sysfs_use_count;
307 bool enable;
308 struct page *avp_vector_page; /* dummy page shared by all AS's */
309
310 /*
311 * Register image savers for suspend/resume
312 */
313 unsigned long translation_enable_0_0;
314 unsigned long translation_enable_1_0;
315 unsigned long translation_enable_2_0;
316 unsigned long asid_security_0;
317
318 unsigned long lowest_asid; /* Variables for hardware testing */
319 unsigned long debug_asid;
320 unsigned long signature_pid; /* For debugging aid */
321};
322
323#define VA_PAGE_TO_PA(va, page) \
324 (page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK))
325
326#define FLUSH_CPU_DCACHE(va, page, size) \
327 do { \
328 unsigned long _pa_ = VA_PAGE_TO_PA(va, page); \
329 __cpuc_flush_dcache_area((void *)(va), (size_t)(size)); \
330 outer_flush_range(_pa_, _pa_+(size_t)(size)); \
331 } while (0)
332
333/*
334 * Any interaction between any block on PPSB and a block on APB or AHB
335 * must have these read-back to ensure the APB/AHB bus transaction is
336 * complete before initiating activity on the PPSB block.
337 */
338#define FLUSH_SMMU_REGS(smmu) (void)readl((smmu)->regs + MC_SMMU_CONFIG_0)
339
340/*
341 * Flush all TLB entries and all PTC entries
342 * Caller must lock smmu
343 */
344static void smmu_flush_regs(struct smmu_device *smmu, int enable)
345{
346 writel(MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_TYPE_ALL,
347 smmu->regs + MC_SMMU_PTC_FLUSH_0);
348 FLUSH_SMMU_REGS(smmu);
349 writel(MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_ALL |
350 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_disable,
351 smmu->regs + MC_SMMU_TLB_FLUSH_0);
352
353 if (enable)
354 writel(MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE,
355 smmu->regs + MC_SMMU_CONFIG_0);
356 FLUSH_SMMU_REGS(smmu);
357}
358
359static void smmu_setup_regs(struct smmu_device *smmu)
360{
361 int i;
362
363 if (smmu->as) {
364 int asid;
365
366 /* Set/restore page directory for each AS */
367 for (asid = 0; asid < smmu->num_ases; asid++) {
368 struct smmu_as *as = &smmu->as[asid];
369
370 writel(MC_SMMU_PTB_ASID_0_CURRENT_ASID(as->asid),
371 as->smmu->regs + MC_SMMU_PTB_ASID_0);
372 writel(as->pdir_page
373 ? SMMU_MK_PDIR(as->pdir_page, as->pdir_attr)
374 : MC_SMMU_PTB_DATA_0_RESET_VAL,
375 as->smmu->regs + MC_SMMU_PTB_DATA_0);
376 }
377 }
378
379 /* Set/restore ASID for each hardware client */
380 for (i = 0; i < HWC_COUNT; i++) {
381 struct smmu_hwc_state *hwcst = &smmu->hwc_state[i];
382 writel(hwcst->enable_disable, smmu->regs + hwcst->reg);
383 }
384
385 writel(smmu->translation_enable_0_0,
386 smmu->regs + MC_SMMU_TRANSLATION_ENABLE_0_0);
387 writel(smmu->translation_enable_1_0,
388 smmu->regs + MC_SMMU_TRANSLATION_ENABLE_1_0);
389 writel(smmu->translation_enable_2_0,
390 smmu->regs + MC_SMMU_TRANSLATION_ENABLE_2_0);
391 writel(smmu->asid_security_0,
392 smmu->regs + MC_SMMU_ASID_SECURITY_0);
393 writel(MC_SMMU_TLB_CONFIG_0_RESET_VAL,
394 smmu->regs + MC_SMMU_TLB_CONFIG_0);
395 writel(MC_SMMU_PTC_CONFIG_0_RESET_VAL,
396 smmu->regs + MC_SMMU_PTC_CONFIG_0);
397
398 smmu_flush_regs(smmu, 1);
399 writel(
400 readl(smmu->regs_ahbarb + AHB_ARBITRATION_XBAR_CTRL_0) |
401 (AHB_ARBITRATION_XBAR_CTRL_0_SMMU_INIT_DONE_DONE <<
402 AHB_ARBITRATION_XBAR_CTRL_0_SMMU_INIT_DONE_SHIFT),
403 smmu->regs_ahbarb + AHB_ARBITRATION_XBAR_CTRL_0);
404}
405
406static int smmu_suspend(struct tegra_iovmm_device *dev)
407{
408 struct smmu_device *smmu =
409 container_of(dev, struct smmu_device, iovmm_dev);
410
411 smmu->translation_enable_0_0 =
412 readl(smmu->regs + MC_SMMU_TRANSLATION_ENABLE_0_0);
413 smmu->translation_enable_1_0 =
414 readl(smmu->regs + MC_SMMU_TRANSLATION_ENABLE_1_0);
415 smmu->translation_enable_2_0 =
416 readl(smmu->regs + MC_SMMU_TRANSLATION_ENABLE_2_0);
417 smmu->asid_security_0 =
418 readl(smmu->regs + MC_SMMU_ASID_SECURITY_0);
419 return 0;
420}
421
422static void smmu_resume(struct tegra_iovmm_device *dev)
423{
424 struct smmu_device *smmu =
425 container_of(dev, struct smmu_device, iovmm_dev);
426
427 if (!smmu->enable)
428 return;
429
430 spin_lock(&smmu->lock);
431 smmu_setup_regs(smmu);
432 spin_unlock(&smmu->lock);
433}
434
435static void flush_ptc_and_tlb(struct smmu_device *smmu,
436 struct smmu_as *as, unsigned long iova,
437 unsigned long *pte, struct page *ptpage, int is_pde)
438{
439 unsigned long tlb_flush_va = is_pde
440 ? MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA(iova, SECTION)
441 : MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA(iova, GROUP);
442
443 writel(MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_TYPE_ADR |
444 VA_PAGE_TO_PA(pte, ptpage),
445 smmu->regs + MC_SMMU_PTC_FLUSH_0);
446 FLUSH_SMMU_REGS(smmu);
447 writel(tlb_flush_va |
448 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH__ENABLE |
449 (as->asid << MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_SHIFT),
450 smmu->regs + MC_SMMU_TLB_FLUSH_0);
451 FLUSH_SMMU_REGS(smmu);
452}
453
454static void free_ptbl(struct smmu_as *as, unsigned long iova)
455{
456 unsigned long pdn = SMMU_ADDR_TO_PDN(iova);
457 unsigned long *pdir = (unsigned long *)kmap(as->pdir_page);
458
459 if (pdir[pdn] != _PDE_VACANT(pdn)) {
460 pr_debug("%s:%d pdn=%lx\n", __func__, __LINE__, pdn);
461
462 ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn]));
463 __free_page(SMMU_EX_PTBL_PAGE(pdir[pdn]));
464 pdir[pdn] = _PDE_VACANT(pdn);
465 FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]);
466 flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn],
467 as->pdir_page, 1);
468 }
469 kunmap(as->pdir_page);
470}
471
472static void free_pdir(struct smmu_as *as)
473{
474 if (as->pdir_page) {
475 unsigned addr = as->smmu->iovmm_base;
476 int count = as->smmu->page_count;
477
478 while (count-- > 0) {
479 free_ptbl(as, addr);
480 addr += SMMU_PAGE_SIZE * SMMU_PTBL_COUNT;
481 }
482 ClearPageReserved(as->pdir_page);
483 __free_page(as->pdir_page);
484 as->pdir_page = NULL;
485 kfree(as->pte_count);
486 as->pte_count = NULL;
487 }
488}
489
490static int smmu_remove(struct platform_device *pdev)
491{
492 struct smmu_device *smmu = platform_get_drvdata(pdev);
493
494 if (!smmu)
495 return 0;
496
497 if (smmu->enable) {
498 writel(MC_SMMU_CONFIG_0_SMMU_ENABLE_DISABLE,
499 smmu->regs + MC_SMMU_CONFIG_0);
500 smmu->enable = 0;
501 }
502 platform_set_drvdata(pdev, NULL);
503
504 if (smmu->as) {
505 int asid;
506
507 for (asid = 0; asid < smmu->num_ases; asid++)
508 free_pdir(&smmu->as[asid]);
509 kfree(smmu->as);
510 }
511
512 if (smmu->avp_vector_page)
513 __free_page(smmu->avp_vector_page);
514 if (smmu->regs)
515 iounmap(smmu->regs);
516 if (smmu->regs_ahbarb)
517 iounmap(smmu->regs_ahbarb);
518 tegra_iovmm_unregister(&smmu->iovmm_dev);
519 kfree(smmu);
520 return 0;
521}
522
523/*
524 * Maps PTBL for given iova and returns the PTE address
525 * Caller must unmap the mapped PTBL returned in *ptbl_page_p
526 */
527static unsigned long *locate_pte(struct smmu_as *as,
528 unsigned long iova, bool allocate,
529 struct page **ptbl_page_p,
530 unsigned int **pte_counter)
531{
532 unsigned long ptn = SMMU_ADDR_TO_PFN(iova);
533 unsigned long pdn = SMMU_ADDR_TO_PDN(iova);
534 unsigned long *pdir = kmap(as->pdir_page);
535 unsigned long *ptbl;
536
537 if (pdir[pdn] != _PDE_VACANT(pdn)) {
538 /* Mapped entry table already exists */
539 *ptbl_page_p = SMMU_EX_PTBL_PAGE(pdir[pdn]);
540 ptbl = kmap(*ptbl_page_p);
541 } else if (!allocate) {
542 kunmap(as->pdir_page);
543 return NULL;
544 } else {
545 /* Vacant - allocate a new page table */
546 pr_debug("%s:%d new PTBL pdn=%lx\n", __func__, __LINE__, pdn);
547
548 *ptbl_page_p = alloc_page(GFP_KERNEL | __GFP_DMA);
549 if (!*ptbl_page_p) {
550 kunmap(as->pdir_page);
551 pr_err(DRIVER_NAME
552 ": failed to allocate tegra_iovmm_device page table\n");
553 return NULL;
554 }
555 SetPageReserved(*ptbl_page_p);
556 ptbl = (unsigned long *)kmap(*ptbl_page_p);
557 {
558 int pn;
559 unsigned long addr = SMMU_PDN_TO_ADDR(pdn);
560 for (pn = 0; pn < SMMU_PTBL_COUNT;
561 pn++, addr += SMMU_PAGE_SIZE) {
562 ptbl[pn] = _PTE_VACANT(addr);
563 }
564 }
565 FLUSH_CPU_DCACHE(ptbl, *ptbl_page_p, SMMU_PTBL_SIZE);
566 pdir[pdn] = SMMU_MK_PDE(*ptbl_page_p,
567 as->pde_attr | _PDE_NEXT);
568 FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]);
569 flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn],
570 as->pdir_page, 1);
571 }
572 *pte_counter = &as->pte_count[pdn];
573
574 kunmap(as->pdir_page);
575 return &ptbl[ptn % SMMU_PTBL_COUNT];
576}
577
578static void put_signature(struct smmu_as *as,
579 unsigned long addr, unsigned long pfn)
580{
581 if (as->smmu->signature_pid == current->pid) {
582 struct page *page = pfn_to_page(pfn);
583 unsigned long *vaddr = kmap(page);
584 if (vaddr) {
585 vaddr[0] = addr;
586 vaddr[1] = pfn << PAGE_SHIFT;
587 FLUSH_CPU_DCACHE(vaddr, page, sizeof(vaddr[0]) * 2);
588 kunmap(page);
589 }
590 }
591}
592
593static int smmu_map(struct tegra_iovmm_domain *domain,
594 struct tegra_iovmm_area *iovma)
595{
596 struct smmu_as *as = container_of(domain, struct smmu_as, domain);
597 unsigned long addr = iovma->iovm_start;
598 unsigned long pcount = iovma->iovm_length >> SMMU_PAGE_SHIFT;
599 int i;
600
601 pr_debug("%s:%d iova=%lx asid=%d\n", __func__, __LINE__,
602 addr, as - as->smmu->as);
603
604 for (i = 0; i < pcount; i++) {
605 unsigned long pfn;
606 unsigned long *pte;
607 unsigned int *pte_counter;
608 struct page *ptpage;
609
610 pfn = iovma->ops->lock_makeresident(iovma, i << PAGE_SHIFT);
611 if (!pfn_valid(pfn))
612 goto fail;
613
614 mutex_lock(&as->lock);
615
616 pte = locate_pte(as, addr, true, &ptpage, &pte_counter);
617 if (!pte)
618 goto fail2;
619
620 pr_debug("%s:%d iova=%lx pfn=%lx asid=%d\n",
621 __func__, __LINE__, addr, pfn, as - as->smmu->as);
622
623 if (*pte == _PTE_VACANT(addr))
624 (*pte_counter)++;
625 *pte = SMMU_PFN_TO_PTE(pfn, as->pte_attr);
626 if (unlikely((*pte == _PTE_VACANT(addr))))
627 (*pte_counter)--;
628 FLUSH_CPU_DCACHE(pte, ptpage, sizeof *pte);
629 flush_ptc_and_tlb(as->smmu, as, addr, pte, ptpage, 0);
630 kunmap(ptpage);
631 mutex_unlock(&as->lock);
632 put_signature(as, addr, pfn);
633 addr += SMMU_PAGE_SIZE;
634 }
635 return 0;
636
637fail:
638 mutex_lock(&as->lock);
639fail2:
640
641 while (i-- > 0) {
642 unsigned long *pte;
643 unsigned int *pte_counter;
644 struct page *page;
645
646 iovma->ops->release(iovma, i<<PAGE_SHIFT);
647 addr -= SMMU_PAGE_SIZE;
648 pte = locate_pte(as, addr, false, &page, &pte_counter);
649 if (pte) {
650 if (*pte != _PTE_VACANT(addr)) {
651 *pte = _PTE_VACANT(addr);
652 FLUSH_CPU_DCACHE(pte, page, sizeof *pte);
653 flush_ptc_and_tlb(as->smmu, as, addr, pte,
654 page, 0);
655 kunmap(page);
656 if (!--(*pte_counter))
657 free_ptbl(as, addr);
658 } else {
659 kunmap(page);
660 }
661 }
662 }
663 mutex_unlock(&as->lock);
664 return -ENOMEM;
665}
666
667static void smmu_unmap(struct tegra_iovmm_domain *domain,
668 struct tegra_iovmm_area *iovma, bool decommit)
669{
670 struct smmu_as *as = container_of(domain, struct smmu_as, domain);
671 unsigned long addr = iovma->iovm_start;
672 unsigned int pcount = iovma->iovm_length >> SMMU_PAGE_SHIFT;
673 unsigned int i, *pte_counter;
674
675 pr_debug("%s:%d iova=%lx asid=%d\n", __func__, __LINE__,
676 addr, as - as->smmu->as);
677
678 mutex_lock(&as->lock);
679 for (i = 0; i < pcount; i++) {
680 unsigned long *pte;
681 struct page *page;
682
683 if (iovma->ops && iovma->ops->release)
684 iovma->ops->release(iovma, i << PAGE_SHIFT);
685
686 pte = locate_pte(as, addr, false, &page, &pte_counter);
687 if (pte) {
688 if (*pte != _PTE_VACANT(addr)) {
689 *pte = _PTE_VACANT(addr);
690 FLUSH_CPU_DCACHE(pte, page, sizeof *pte);
691 flush_ptc_and_tlb(as->smmu, as, addr, pte,
692 page, 0);
693 kunmap(page);
694 if (!--(*pte_counter) && decommit) {
695 free_ptbl(as, addr);
696 smmu_flush_regs(as->smmu, 0);
697 }
698 }
699 }
700 addr += SMMU_PAGE_SIZE;
701 }
702 mutex_unlock(&as->lock);
703}
704
705static void smmu_map_pfn(struct tegra_iovmm_domain *domain,
706 struct tegra_iovmm_area *iovma, tegra_iovmm_addr_t addr,
707 unsigned long pfn)
708{
709 struct smmu_as *as = container_of(domain, struct smmu_as, domain);
710 struct smmu_device *smmu = as->smmu;
711 unsigned long *pte;
712 unsigned int *pte_counter;
713 struct page *ptpage;
714
715 pr_debug("%s:%d iova=%lx pfn=%lx asid=%d\n", __func__, __LINE__,
716 (unsigned long)addr, pfn, as - as->smmu->as);
717
718 BUG_ON(!pfn_valid(pfn));
719 mutex_lock(&as->lock);
720 pte = locate_pte(as, addr, true, &ptpage, &pte_counter);
721 if (pte) {
722 if (*pte == _PTE_VACANT(addr))
723 (*pte_counter)++;
724 *pte = SMMU_PFN_TO_PTE(pfn, as->pte_attr);
725 if (unlikely((*pte == _PTE_VACANT(addr))))
726 (*pte_counter)--;
727 FLUSH_CPU_DCACHE(pte, ptpage, sizeof *pte);
728 flush_ptc_and_tlb(smmu, as, addr, pte, ptpage, 0);
729 kunmap(ptpage);
730 put_signature(as, addr, pfn);
731 }
732 mutex_unlock(&as->lock);
733}
734
735/*
736 * Caller must lock/unlock as
737 */
738static int alloc_pdir(struct smmu_as *as)
739{
740 unsigned long *pdir;
741 int pdn;
742
743 if (as->pdir_page)
744 return 0;
745
746 as->pte_count = kzalloc(sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT,
747 GFP_KERNEL);
748 if (!as->pte_count) {
749 pr_err(DRIVER_NAME
750 ": failed to allocate tegra_iovmm_device PTE cunters\n");
751 return -ENOMEM;
752 }
753 as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
754 if (!as->pdir_page) {
755 pr_err(DRIVER_NAME
756 ": failed to allocate tegra_iovmm_device page directory\n");
757 kfree(as->pte_count);
758 as->pte_count = NULL;
759 return -ENOMEM;
760 }
761 SetPageReserved(as->pdir_page);
762 pdir = kmap(as->pdir_page);
763
764 for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
765 pdir[pdn] = _PDE_VACANT(pdn);
766 FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE);
767 writel(MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_TYPE_ADR |
768 VA_PAGE_TO_PA(pdir, as->pdir_page),
769 as->smmu->regs + MC_SMMU_PTC_FLUSH_0);
770 FLUSH_SMMU_REGS(as->smmu);
771 writel(MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_ALL |
772 MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH__ENABLE |
773 (as->asid << MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_SHIFT),
774 as->smmu->regs + MC_SMMU_TLB_FLUSH_0);
775 FLUSH_SMMU_REGS(as->smmu);
776 kunmap(as->pdir_page);
777
778 return 0;
779}
780
781static void _sysfs_create(struct smmu_as *as, struct device *sysfs_parent);
782
783/*
784 * Allocate resources for an AS
785 * TODO: split into "alloc" and "lock"
786 */
787static struct tegra_iovmm_domain *smmu_alloc_domain(
788 struct tegra_iovmm_device *dev, struct tegra_iovmm_client *client)
789{
790 struct smmu_device *smmu =
791 container_of(dev, struct smmu_device, iovmm_dev);
792 struct smmu_as *as = NULL;
793 const struct domain_hwc_map *map = NULL;
794 int asid, i;
795
796 /* Look for a free AS */
797 for (asid = smmu->lowest_asid; asid < smmu->num_ases; asid++) {
798 mutex_lock(&smmu->as[asid].lock);
799 if (!smmu->as[asid].hwclients) {
800 as = &smmu->as[asid];
801 break;
802 }
803 mutex_unlock(&smmu->as[asid].lock);
804 }
805
806 if (!as) {
807 pr_err(DRIVER_NAME ": no free AS\n");
808 return NULL;
809 }
810
811 if (alloc_pdir(as) < 0)
812 goto bad3;
813
814 /* Look for a matching hardware client group */
815 for (i = 0; ARRAY_SIZE(smmu_hwc_map); i++) {
816 if (!strcmp(smmu_hwc_map[i].dev_name, client->misc_dev->name)) {
817 map = &smmu_hwc_map[i];
818 break;
819 }
820 }
821
822 if (!map) {
823 pr_err(DRIVER_NAME ": no SMMU resource for %s (%s)\n",
824 client->name, client->misc_dev->name);
825 goto bad2;
826 }
827
828 spin_lock(&smmu->lock);
829 /* Update PDIR register */
830 writel(MC_SMMU_PTB_ASID_0_CURRENT_ASID(as->asid),
831 as->smmu->regs + MC_SMMU_PTB_ASID_0);
832 writel(SMMU_MK_PDIR(as->pdir_page, as->pdir_attr),
833 as->smmu->regs + MC_SMMU_PTB_DATA_0);
834 FLUSH_SMMU_REGS(smmu);
835
836 /* Put each hardware client in the group into the address space */
837 for (i = 0; i < map->nr_hwcs; i++) {
838 struct smmu_hwc_state *hwcst = &smmu->hwc_state[map->hwcs[i]];
839
840 /* Is the hardware client busy? */
841 if (hwcst->enable_disable != SMMU_ASID_DISABLE &&
842 hwcst->enable_disable != SMMU_ASID_ENABLE(as->asid)) {
843 pr_err(DRIVER_NAME
844 ": HW 0x%lx busy for ASID %ld (client!=%s)\n",
845 hwcst->reg,
846 SMMU_ASID_ASID(hwcst->enable_disable),
847 client->name);
848 goto bad;
849 }
850 hwcst->enable_disable = SMMU_ASID_ENABLE(as->asid);
851 writel(hwcst->enable_disable, smmu->regs + hwcst->reg);
852 }
853 FLUSH_SMMU_REGS(smmu);
854 spin_unlock(&smmu->lock);
855 as->hwclients = map;
856 _sysfs_create(as, client->misc_dev->this_device);
857 mutex_unlock(&as->lock);
858
859 /* Reserve "page zero" for AVP vectors using a common dummy page */
860 smmu_map_pfn(&as->domain, NULL, 0,
861 page_to_phys(as->smmu->avp_vector_page) >> SMMU_PAGE_SHIFT);
862 return &as->domain;
863
864bad:
865 /* Reset hardware clients that have been enabled */
866 while (--i >= 0) {
867 struct smmu_hwc_state *hwcst = &smmu->hwc_state[map->hwcs[i]];
868
869 hwcst->enable_disable = SMMU_ASID_DISABLE;
870 writel(hwcst->enable_disable, smmu->regs + hwcst->reg);
871 }
872 FLUSH_SMMU_REGS(smmu);
873 spin_unlock(&as->smmu->lock);
874bad2:
875 free_pdir(as);
876bad3:
877 mutex_unlock(&as->lock);
878 return NULL;
879
880}
881
882/*
883 * Release resources for an AS
884 * TODO: split into "unlock" and "free"
885 */
886static void smmu_free_domain(
887 struct tegra_iovmm_domain *domain, struct tegra_iovmm_client *client)
888{
889 struct smmu_as *as = container_of(domain, struct smmu_as, domain);
890 struct smmu_device *smmu = as->smmu;
891 const struct domain_hwc_map *map = NULL;
892 int i;
893
894 mutex_lock(&as->lock);
895 map = as->hwclients;
896
897 spin_lock(&smmu->lock);
898 for (i = 0; i < map->nr_hwcs; i++) {
899 struct smmu_hwc_state *hwcst = &smmu->hwc_state[map->hwcs[i]];
900
901 hwcst->enable_disable = SMMU_ASID_DISABLE;
902 writel(SMMU_ASID_DISABLE, smmu->regs + hwcst->reg);
903 }
904 FLUSH_SMMU_REGS(smmu);
905 spin_unlock(&smmu->lock);
906
907 as->hwclients = NULL;
908 if (as->pdir_page) {
909 spin_lock(&smmu->lock);
910 writel(MC_SMMU_PTB_ASID_0_CURRENT_ASID(as->asid),
911 smmu->regs + MC_SMMU_PTB_ASID_0);
912 writel(MC_SMMU_PTB_DATA_0_RESET_VAL,
913 smmu->regs + MC_SMMU_PTB_DATA_0);
914 FLUSH_SMMU_REGS(smmu);
915 spin_unlock(&smmu->lock);
916
917 free_pdir(as);
918 }
919 mutex_unlock(&as->lock);
920}
921
922static struct tegra_iovmm_device_ops tegra_iovmm_smmu_ops = {
923 .map = smmu_map,
924 .unmap = smmu_unmap,
925 .map_pfn = smmu_map_pfn,
926 .alloc_domain = smmu_alloc_domain,
927 .free_domain = smmu_free_domain,
928 .suspend = smmu_suspend,
929 .resume = smmu_resume,
930};
931
932static int smmu_probe(struct platform_device *pdev)
933{
934 struct smmu_device *smmu;
935 struct resource *regs, *regs2;
936 struct tegra_smmu_window *window;
937 int e, asid;
938
939 BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT);
940 BUILD_BUG_ON(ARRAY_SIZE(smmu_hwc_state_init) != HWC_COUNT);
941
942 regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mc");
943 regs2 = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahbarb");
944 window = tegra_smmu_window(0);
945
946 if (!regs || !regs2 || !window) {
947 pr_err(DRIVER_NAME ": No SMMU resources\n");
948 return -ENODEV;
949 }
950
951 smmu = kzalloc(sizeof(*smmu), GFP_KERNEL);
952 if (!smmu) {
953 pr_err(DRIVER_NAME ": failed to allocate smmu_device\n");
954 return -ENOMEM;
955 }
956
957 smmu->num_ases = MC_SMMU_NUM_ASIDS;
958 smmu->iovmm_base = (tegra_iovmm_addr_t)window->start;
959 smmu->page_count = (window->end + 1 - window->start) >> SMMU_PAGE_SHIFT;
960 smmu->regs = ioremap(regs->start, regs->end + 1 - regs->start);
961 smmu->regs_ahbarb =
962 ioremap(regs2->start, regs2->end + 1 - regs2->start);
963 if (!smmu->regs || !smmu->regs_ahbarb) {
964 pr_err(DRIVER_NAME ": failed to remap SMMU registers\n");
965 e = -ENXIO;
966 goto fail;
967 }
968
969 smmu->translation_enable_0_0 = ~0;
970 smmu->translation_enable_1_0 = ~0;
971 smmu->translation_enable_2_0 = ~0;
972 smmu->asid_security_0 = 0;
973
974 memcpy(smmu->hwc_state, smmu_hwc_state_init, sizeof(smmu->hwc_state));
975
976 smmu->iovmm_dev.name = VMM_NAME;
977 smmu->iovmm_dev.ops = &tegra_iovmm_smmu_ops;
978 smmu->iovmm_dev.pgsize_bits = SMMU_PAGE_SHIFT;
979
980 e = tegra_iovmm_register(&smmu->iovmm_dev);
981 if (e)
982 goto fail;
983
984 smmu->as = kzalloc(sizeof(smmu->as[0]) * smmu->num_ases, GFP_KERNEL);
985 if (!smmu->as) {
986 pr_err(DRIVER_NAME ": failed to allocate smmu_as\n");
987 e = -ENOMEM;
988 goto fail;
989 }
990
991 /* Initialize address space structure array */
992 for (asid = 0; asid < smmu->num_ases; asid++) {
993 struct smmu_as *as = &smmu->as[asid];
994
995 as->smmu = smmu;
996 as->asid = asid;
997 as->pdir_attr = _PDIR_ATTR;
998 as->pde_attr = _PDE_ATTR;
999 as->pte_attr = _PTE_ATTR;
1000
1001 mutex_init(&as->lock);
1002
1003 e = tegra_iovmm_domain_init(&as->domain, &smmu->iovmm_dev,
1004 smmu->iovmm_base,
1005 smmu->iovmm_base +
1006 (smmu->page_count << SMMU_PAGE_SHIFT));
1007 if (e)
1008 goto fail;
1009 }
1010 spin_lock_init(&smmu->lock);
1011 smmu_setup_regs(smmu);
1012 smmu->enable = 1;
1013 platform_set_drvdata(pdev, smmu);
1014
1015 smmu->avp_vector_page = alloc_page(GFP_KERNEL);
1016 if (!smmu->avp_vector_page)
1017 goto fail;
1018 return 0;
1019
1020fail:
1021 if (smmu->avp_vector_page)
1022 __free_page(smmu->avp_vector_page);
1023 if (smmu->regs)
1024 iounmap(smmu->regs);
1025 if (smmu->regs_ahbarb)
1026 iounmap(smmu->regs_ahbarb);
1027 if (smmu && smmu->as) {
1028 for (asid = 0; asid < smmu->num_ases; asid++) {
1029 if (smmu->as[asid].pdir_page) {
1030 ClearPageReserved(smmu->as[asid].pdir_page);
1031 __free_page(smmu->as[asid].pdir_page);
1032 }
1033 }
1034 kfree(smmu->as);
1035 }
1036 kfree(smmu);
1037 return e;
1038}
1039
1040static struct platform_driver tegra_iovmm_smmu_drv = {
1041 .probe = smmu_probe,
1042 .remove = smmu_remove,
1043 .driver = {
1044 .name = DRIVER_NAME,
1045 },
1046};
1047
1048static int __devinit smmu_init(void)
1049{
1050 return platform_driver_register(&tegra_iovmm_smmu_drv);
1051}
1052
1053static void __exit smmu_exit(void)
1054{
1055 platform_driver_unregister(&tegra_iovmm_smmu_drv);
1056}
1057
1058subsys_initcall(smmu_init);
1059module_exit(smmu_exit);
1060
1061/*
1062 * SMMU-global sysfs interface for debugging
1063 */
1064static ssize_t _sysfs_show_reg(struct device *d,
1065 struct device_attribute *da, char *buf);
1066static ssize_t _sysfs_store_reg(struct device *d,
1067 struct device_attribute *da, const char *buf,
1068 size_t count);
1069
1070#define _NAME_MAP(_name) { \
1071 .name = __stringify(_name), \
1072 .offset = _name##_0, \
1073 .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR, \
1074 _sysfs_show_reg, _sysfs_store_reg) \
1075}
1076
1077static
1078struct _reg_name_map {
1079 const char *name;
1080 unsigned offset;
1081 struct device_attribute dev_attr;
1082} _smmu_reg_name_map[] = {
1083 _NAME_MAP(MC_SMMU_CONFIG),
1084 _NAME_MAP(MC_SMMU_TLB_CONFIG),
1085 _NAME_MAP(MC_SMMU_PTC_CONFIG),
1086 _NAME_MAP(MC_SMMU_PTB_ASID),
1087 _NAME_MAP(MC_SMMU_PTB_DATA),
1088 _NAME_MAP(MC_SMMU_TLB_FLUSH),
1089 _NAME_MAP(MC_SMMU_PTC_FLUSH),
1090 _NAME_MAP(MC_SMMU_ASID_SECURITY),
1091 _NAME_MAP(MC_SMMU_STATS_TLB_HIT_COUNT),
1092 _NAME_MAP(MC_SMMU_STATS_TLB_MISS_COUNT),
1093 _NAME_MAP(MC_SMMU_STATS_PTC_HIT_COUNT),
1094 _NAME_MAP(MC_SMMU_STATS_PTC_MISS_COUNT),
1095 _NAME_MAP(MC_SMMU_TRANSLATION_ENABLE_0),
1096 _NAME_MAP(MC_SMMU_TRANSLATION_ENABLE_1),
1097 _NAME_MAP(MC_SMMU_TRANSLATION_ENABLE_2),
1098 _NAME_MAP(MC_SMMU_AFI_ASID),
1099 _NAME_MAP(MC_SMMU_AVPC_ASID),
1100 _NAME_MAP(MC_SMMU_DC_ASID),
1101 _NAME_MAP(MC_SMMU_DCB_ASID),
1102 _NAME_MAP(MC_SMMU_EPP_ASID),
1103 _NAME_MAP(MC_SMMU_G2_ASID),
1104 _NAME_MAP(MC_SMMU_HC_ASID),
1105 _NAME_MAP(MC_SMMU_HDA_ASID),
1106 _NAME_MAP(MC_SMMU_ISP_ASID),
1107 _NAME_MAP(MC_SMMU_MPE_ASID),
1108 _NAME_MAP(MC_SMMU_NV_ASID),
1109 _NAME_MAP(MC_SMMU_NV2_ASID),
1110 _NAME_MAP(MC_SMMU_PPCS_ASID),
1111 _NAME_MAP(MC_SMMU_SATA_ASID),
1112 _NAME_MAP(MC_SMMU_VDE_ASID),
1113 _NAME_MAP(MC_SMMU_VI_ASID),
1114};
1115
1116static ssize_t lookup_reg(struct device_attribute *da)
1117{
1118 int i;
1119 for (i = 0; i < ARRAY_SIZE(_smmu_reg_name_map); i++) {
1120 if (!strcmp(_smmu_reg_name_map[i].name, da->attr.name))
1121 return _smmu_reg_name_map[i].offset;
1122 }
1123 return -ENODEV;
1124}
1125
1126static ssize_t _sysfs_show_reg(struct device *d,
1127 struct device_attribute *da, char *buf)
1128{
1129 struct smmu_device *smmu =
1130 container_of(d, struct smmu_device, sysfs_dev);
1131 ssize_t offset = lookup_reg(da);
1132
1133 if (offset < 0)
1134 return offset;
1135 return sprintf(buf, "%08lx\n",
1136 (unsigned long)readl(smmu->regs + offset));
1137}
1138
1139static ssize_t _sysfs_store_reg(struct device *d,
1140 struct device_attribute *da,
1141 const char *buf, size_t count)
1142{
1143 struct smmu_device *smmu =
1144 container_of(d, struct smmu_device, sysfs_dev);
1145 ssize_t offset = lookup_reg(da);
1146 u32 value;
1147 int err;
1148
1149 if (offset < 0)
1150 return offset;
1151
1152 err = kstrtou32(buf, 16, &value);
1153 if (err)
1154 return err;
1155
1156#ifdef CONFIG_TEGRA_IOVMM_SMMU_SYSFS
1157 writel(value, smmu->regs + offset);
1158#else
1159 /* Allow writing to reg only for TLB/PTC stats enabling/disabling */
1160 {
1161 unsigned long mask = 0;
1162 switch (offset) {
1163 case MC_SMMU_TLB_CONFIG_0:
1164 mask = MC_SMMU_TLB_CONFIG_0_TLB_STATS__MASK;
1165 break;
1166 case MC_SMMU_PTC_CONFIG_0:
1167 mask = MC_SMMU_PTC_CONFIG_0_PTC_STATS__MASK;
1168 break;
1169 default:
1170 break;
1171 }
1172
1173 if (mask) {
1174 unsigned long currval = readl(smmu->regs + offset);
1175 currval &= ~mask;
1176 value &= mask;
1177 value |= currval;
1178 writel(value, smmu->regs + offset);
1179 }
1180 }
1181#endif
1182 return count;
1183}
1184
1185static ssize_t _sysfs_show_smmu(struct device *d,
1186 struct device_attribute *da, char *buf)
1187{
1188 struct smmu_device *smmu =
1189 container_of(d, struct smmu_device, sysfs_dev);
1190 ssize_t rv = 0;
1191
1192 rv += sprintf(buf + rv , " regs: %p\n", smmu->regs);
1193 rv += sprintf(buf + rv , "iovmm_base: %p\n", (void *)smmu->iovmm_base);
1194 rv += sprintf(buf + rv , "page_count: %lx\n", smmu->page_count);
1195 rv += sprintf(buf + rv , " num_ases: %d\n", smmu->num_ases);
1196 rv += sprintf(buf + rv , " as: %p\n", smmu->as);
1197 rv += sprintf(buf + rv , " enable: %s\n",
1198 smmu->enable ? "yes" : "no");
1199 return rv;
1200}
1201
1202static struct device_attribute _attr_show_smmu
1203 = __ATTR(show_smmu, S_IRUGO, _sysfs_show_smmu, NULL);
1204
1205#define _SYSFS_SHOW_VALUE(name, field, fmt) \
1206static ssize_t _sysfs_show_##name(struct device *d, \
1207 struct device_attribute *da, char *buf) \
1208{ \
1209 struct smmu_device *smmu = \
1210 container_of(d, struct smmu_device, sysfs_dev); \
1211 ssize_t rv = 0; \
1212 rv += sprintf(buf + rv, fmt "\n", smmu->field); \
1213 return rv; \
1214}
1215
1216static void (*_sysfs_null_callback)(struct smmu_device *, unsigned long *) =
1217 NULL;
1218
1219#define _SYSFS_SET_VALUE_DO(name, field, base, ceil, callback) \
1220static ssize_t _sysfs_set_##name(struct device *d, \
1221 struct device_attribute *da, const char *buf, size_t count) \
1222{ \
1223 int err; \
1224 u32 value; \
1225 struct smmu_device *smmu = \
1226 container_of(d, struct smmu_device, sysfs_dev); \
1227 err = kstrtou32(buf, base, &value); \
1228 if (err) \
1229 return err; \
1230 if (0 <= value && value < ceil) { \
1231 smmu->field = value; \
1232 if (callback) \
1233 callback(smmu, &smmu->field); \
1234 } \
1235 return count; \
1236}
1237#ifdef CONFIG_TEGRA_IOVMM_SMMU_SYSFS
1238#define _SYSFS_SET_VALUE _SYSFS_SET_VALUE_DO
1239#else
1240#define _SYSFS_SET_VALUE(name, field, base, ceil, callback) \
1241static ssize_t _sysfs_set_##name(struct device *d, \
1242 struct device_attribute *da, const char *buf, size_t count) \
1243{ \
1244 return count; \
1245}
1246#endif
1247
1248_SYSFS_SHOW_VALUE(lowest_asid, lowest_asid, "%lu")
1249_SYSFS_SET_VALUE(lowest_asid, lowest_asid, 10,
1250 MC_SMMU_NUM_ASIDS, _sysfs_null_callback)
1251_SYSFS_SHOW_VALUE(debug_asid, debug_asid, "%lu")
1252_SYSFS_SET_VALUE(debug_asid, debug_asid, 10,
1253 MC_SMMU_NUM_ASIDS, _sysfs_null_callback)
1254_SYSFS_SHOW_VALUE(signature_pid, signature_pid, "%lu")
1255_SYSFS_SET_VALUE_DO(signature_pid, signature_pid, 10, PID_MAX_LIMIT + 1,
1256 _sysfs_null_callback)
1257
1258#ifdef CONFIG_TEGRA_IOVMM_SMMU_SYSFS
1259static void _sysfs_mask_attr(struct smmu_device *smmu, unsigned long *field)
1260{
1261 *field &= _MASK_ATTR;
1262}
1263
1264static void _sysfs_mask_pdir_attr(struct smmu_device *smmu,
1265 unsigned long *field)
1266{
1267 unsigned long pdir;
1268
1269 _sysfs_mask_attr(smmu, field);
1270 writel(MC_SMMU_PTB_ASID_0_CURRENT_ASID(smmu->debug_asid),
1271 smmu->regs + MC_SMMU_PTB_ASID_0);
1272 pdir = readl(smmu->regs + MC_SMMU_PTB_DATA_0);
1273 pdir &= ~_MASK_ATTR;
1274 pdir |= *field;
1275 writel(pdir, smmu->regs + MC_SMMU_PTB_DATA_0);
1276 FLUSH_SMMU_REGS(smmu);
1277}
1278
1279static void (*_sysfs_mask_attr_callback)(struct smmu_device *,
1280 unsigned long *field) = &_sysfs_mask_attr;
1281static void (*_sysfs_mask_pdir_attr_callback)(struct smmu_device *,
1282 unsigned long *field) = &_sysfs_mask_pdir_attr;
1283#endif
1284
1285_SYSFS_SHOW_VALUE(pdir_attr, as[smmu->debug_asid].pdir_attr, "%lx")
1286_SYSFS_SET_VALUE(pdir_attr, as[smmu->debug_asid].pdir_attr, 16,
1287 _PDIR_ATTR + 1, _sysfs_mask_pdir_attr_callback)
1288_SYSFS_SHOW_VALUE(pde_attr, as[smmu->debug_asid].pde_attr, "%lx")
1289_SYSFS_SET_VALUE(pde_attr, as[smmu->debug_asid].pde_attr, 16,
1290 _PDE_ATTR + 1, _sysfs_mask_attr_callback)
1291_SYSFS_SHOW_VALUE(pte_attr, as[smmu->debug_asid].pte_attr, "%lx")
1292_SYSFS_SET_VALUE(pte_attr, as[smmu->debug_asid].pte_attr, 16,
1293 _PTE_ATTR + 1, _sysfs_mask_attr_callback)
1294
1295static struct device_attribute _attr_values[] = {
1296 __ATTR(lowest_asid, S_IRUGO | S_IWUSR,
1297 _sysfs_show_lowest_asid, _sysfs_set_lowest_asid),
1298 __ATTR(debug_asid, S_IRUGO | S_IWUSR,
1299 _sysfs_show_debug_asid, _sysfs_set_debug_asid),
1300 __ATTR(signature_pid, S_IRUGO | S_IWUSR,
1301 _sysfs_show_signature_pid, _sysfs_set_signature_pid),
1302
1303 __ATTR(pdir_attr, S_IRUGO | S_IWUSR,
1304 _sysfs_show_pdir_attr, _sysfs_set_pdir_attr),
1305 __ATTR(pde_attr, S_IRUGO | S_IWUSR,
1306 _sysfs_show_pde_attr, _sysfs_set_pde_attr),
1307 __ATTR(pte_attr, S_IRUGO | S_IWUSR,
1308 _sysfs_show_pte_attr, _sysfs_set_pte_attr),
1309};
1310
1311static struct attribute *_smmu_attrs[
1312 ARRAY_SIZE(_smmu_reg_name_map) + ARRAY_SIZE(_attr_values) + 3];
1313static struct attribute_group _smmu_attr_group = {
1314 .attrs = _smmu_attrs
1315};
1316
1317static void _sysfs_smmu(struct smmu_device *smmu, struct device *parent)
1318{
1319 int i, j;
1320
1321 if (smmu->sysfs_use_count++ > 0)
1322 return;
1323 for (i = 0; i < ARRAY_SIZE(_smmu_reg_name_map); i++)
1324 _smmu_attrs[i] = &_smmu_reg_name_map[i].dev_attr.attr;
1325 for (j = 0; j < ARRAY_SIZE(_attr_values); j++)
1326 _smmu_attrs[i++] = &_attr_values[j].attr;
1327 _smmu_attrs[i++] = &_attr_show_smmu.attr;
1328 _smmu_attrs[i] = NULL;
1329
1330 dev_set_name(&smmu->sysfs_dev, "smmu");
1331 smmu->sysfs_dev.parent = parent;
1332 smmu->sysfs_dev.driver = NULL;
1333 smmu->sysfs_dev.release = NULL;
1334 if (device_register(&smmu->sysfs_dev)) {
1335 pr_err("%s: failed to register smmu_sysfs_dev\n", __func__);
1336 smmu->sysfs_use_count--;
1337 return;
1338 }
1339 if (sysfs_create_group(&smmu->sysfs_dev.kobj, &_smmu_attr_group)) {
1340 pr_err("%s: failed to create group for smmu_sysfs_dev\n",
1341 __func__);
1342 smmu->sysfs_use_count--;
1343 return;
1344 }
1345}
1346
1347static void _sysfs_create(struct smmu_as *as, struct device *parent)
1348{
1349 _sysfs_smmu(as->smmu, parent);
1350}
diff --git a/arch/arm/mach-tegra/iovmm.c b/arch/arm/mach-tegra/iovmm.c
new file mode 100644
index 00000000000..6112128cb74
--- /dev/null
+++ b/arch/arm/mach-tegra/iovmm.c
@@ -0,0 +1,943 @@
1/*
2 * arch/arm/mach-tegra/iovmm.c
3 *
4 * Tegra I/O VM manager
5 *
6 * Copyright (c) 2010-2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/spinlock.h>
25#include <linux/proc_fs.h>
26#include <linux/sched.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include <linux/syscore_ops.h>
30
31#include <mach/iovmm.h>
32
33/*
34 * after the best-fit block is located, the remaining pages not needed
35 * for the allocation will be split into a new free block if the
36 * number of remaining pages is >= MIN_SPLIT_PAGE.
37 */
38#define MIN_SPLIT_PAGE 4
39#define MIN_SPLIT_BYTES(_d) (MIN_SPLIT_PAGE << (_d)->dev->pgsize_bits)
40#define NO_SPLIT(m) ((m) < MIN_SPLIT_BYTES(domain))
41#define DO_SPLIT(m) ((m) >= MIN_SPLIT_BYTES(domain))
42
43#define iovmm_start(_b) ((_b)->vm_area.iovm_start)
44#define iovmm_length(_b) ((_b)->vm_area.iovm_length)
45#define iovmm_end(_b) (iovmm_start(_b) + iovmm_length(_b))
46
47/* flags for the block */
48#define BK_FREE 0 /* indicates free mappings */
49#define BK_MAP_DIRTY 1 /* used by demand-loaded mappings */
50
51/* flags for the client */
52#define CL_LOCKED 0
53
54/* flags for the domain */
55#define DM_MAP_DIRTY 0
56
57struct tegra_iovmm_block {
58 struct tegra_iovmm_area vm_area;
59 tegra_iovmm_addr_t start;
60 size_t length;
61 atomic_t ref;
62 unsigned long flags;
63 unsigned long poison;
64 struct rb_node free_node;
65 struct rb_node all_node;
66};
67
68struct iovmm_share_group {
69 const char *name;
70 struct tegra_iovmm_domain *domain;
71 struct list_head client_list;
72 struct list_head group_list;
73 spinlock_t lock; /* for client_list */
74};
75
76static LIST_HEAD(iovmm_devices);
77static LIST_HEAD(iovmm_groups);
78static DEFINE_MUTEX(iovmm_group_list_lock);
79static struct kmem_cache *iovmm_cache;
80
81#define SIMALIGN(b, a) (((b)->start % (a)) ? ((a) - ((b)->start % (a))) : 0)
82
83size_t tegra_iovmm_get_max_free(struct tegra_iovmm_client *client)
84{
85 struct rb_node *n;
86 struct tegra_iovmm_block *b;
87 struct tegra_iovmm_domain *domain = client->domain;
88 tegra_iovmm_addr_t max_free = 0;
89
90 spin_lock(&domain->block_lock);
91 n = rb_first(&domain->all_blocks);
92 while (n) {
93 b = rb_entry(n, struct tegra_iovmm_block, all_node);
94 n = rb_next(n);
95 if (test_bit(BK_FREE, &b->flags)) {
96 max_free = max_t(tegra_iovmm_addr_t,
97 max_free, iovmm_length(b));
98 }
99 }
100 spin_unlock(&domain->block_lock);
101 return max_free;
102}
103
104
105static void tegra_iovmm_block_stats(struct tegra_iovmm_domain *domain,
106 unsigned int *num_blocks, unsigned int *num_free,
107 tegra_iovmm_addr_t *total, size_t *total_free, size_t *max_free)
108{
109 struct rb_node *n;
110 struct tegra_iovmm_block *b;
111
112 *num_blocks = 0;
113 *num_free = 0;
114 *total = 0;
115 *total_free = 0;
116 *max_free = 0;
117
118 spin_lock(&domain->block_lock);
119 n = rb_first(&domain->all_blocks);
120 while (n) {
121 b = rb_entry(n, struct tegra_iovmm_block, all_node);
122 n = rb_next(n);
123 (*num_blocks)++;
124 *total += b->length;
125 if (test_bit(BK_FREE, &b->flags)) {
126 (*num_free)++;
127 *total_free += b->length;
128 *max_free = max_t(size_t, *max_free, b->length);
129 }
130 }
131 spin_unlock(&domain->block_lock);
132}
133
134static int tegra_iovmm_read_proc(char *page, char **start, off_t off,
135 int count, int *eof, void *data)
136{
137 struct iovmm_share_group *grp;
138 size_t max_free, total_free, total;
139 unsigned int num, num_free;
140
141 int len = 0;
142
143 mutex_lock(&iovmm_group_list_lock);
144 len += snprintf(page + len, count - len, "\ngroups\n");
145 if (list_empty(&iovmm_groups))
146 len += snprintf(page + len, count - len, "\t<empty>\n");
147 else {
148 list_for_each_entry(grp, &iovmm_groups, group_list) {
149 len += snprintf(page + len, count - len,
150 "\t%s (device: %s)\n",
151 grp->name ? grp->name : "<unnamed>",
152 grp->domain->dev->name);
153 tegra_iovmm_block_stats(grp->domain, &num,
154 &num_free, &total, &total_free, &max_free);
155 total >>= 10;
156 total_free >>= 10;
157 max_free >>= 10;
158 len += snprintf(page + len, count - len,
159 "\t\tsize: %uKiB free: %uKiB "
160 "largest: %uKiB (%u free / %u total blocks)\n",
161 total, total_free, max_free, num_free, num);
162 }
163 }
164 mutex_unlock(&iovmm_group_list_lock);
165
166 *eof = 1;
167 return len;
168}
169
170static void iovmm_block_put(struct tegra_iovmm_block *b)
171{
172 BUG_ON(b->poison);
173 BUG_ON(atomic_read(&b->ref) == 0);
174 if (!atomic_dec_return(&b->ref)) {
175 b->poison = 0xa5a5a5a5;
176 kmem_cache_free(iovmm_cache, b);
177 }
178}
179
180static void iovmm_free_block(struct tegra_iovmm_domain *domain,
181 struct tegra_iovmm_block *block)
182{
183 struct tegra_iovmm_block *pred = NULL; /* address-order predecessor */
184 struct tegra_iovmm_block *succ = NULL; /* address-order successor */
185 struct rb_node **p;
186 struct rb_node *parent = NULL, *temp;
187 int pred_free = 0, succ_free = 0;
188
189 iovmm_block_put(block);
190
191 spin_lock(&domain->block_lock);
192 temp = rb_prev(&block->all_node);
193 if (temp)
194 pred = rb_entry(temp, struct tegra_iovmm_block, all_node);
195 temp = rb_next(&block->all_node);
196 if (temp)
197 succ = rb_entry(temp, struct tegra_iovmm_block, all_node);
198
199 if (pred)
200 pred_free = test_bit(BK_FREE, &pred->flags);
201 if (succ)
202 succ_free = test_bit(BK_FREE, &succ->flags);
203
204 if (pred_free && succ_free) {
205 pred->length += block->length;
206 pred->length += succ->length;
207 rb_erase(&block->all_node, &domain->all_blocks);
208 rb_erase(&succ->all_node, &domain->all_blocks);
209 rb_erase(&succ->free_node, &domain->free_blocks);
210 rb_erase(&pred->free_node, &domain->free_blocks);
211 iovmm_block_put(block);
212 iovmm_block_put(succ);
213 block = pred;
214 } else if (pred_free) {
215 pred->length += block->length;
216 rb_erase(&block->all_node, &domain->all_blocks);
217 rb_erase(&pred->free_node, &domain->free_blocks);
218 iovmm_block_put(block);
219 block = pred;
220 } else if (succ_free) {
221 block->length += succ->length;
222 rb_erase(&succ->all_node, &domain->all_blocks);
223 rb_erase(&succ->free_node, &domain->free_blocks);
224 iovmm_block_put(succ);
225 }
226
227 p = &domain->free_blocks.rb_node;
228 while (*p) {
229 struct tegra_iovmm_block *b;
230 parent = *p;
231 b = rb_entry(parent, struct tegra_iovmm_block, free_node);
232 if (block->length >= b->length)
233 p = &parent->rb_right;
234 else
235 p = &parent->rb_left;
236 }
237 rb_link_node(&block->free_node, parent, p);
238 rb_insert_color(&block->free_node, &domain->free_blocks);
239 set_bit(BK_FREE, &block->flags);
240 spin_unlock(&domain->block_lock);
241}
242
243/*
244 * if the best-fit block is larger than the requested size, a remainder
245 * block will be created and inserted into the free list in its place.
246 * since all free blocks are stored in two trees the new block needs to be
247 * linked into both.
248 */
249static struct tegra_iovmm_block *iovmm_split_free_block(
250 struct tegra_iovmm_domain *domain,
251 struct tegra_iovmm_block *block, unsigned long size)
252{
253 struct rb_node **p;
254 struct rb_node *parent = NULL;
255 struct tegra_iovmm_block *rem;
256 struct tegra_iovmm_block *b;
257
258 rem = kmem_cache_zalloc(iovmm_cache, GFP_KERNEL);
259 if (!rem)
260 return NULL;
261
262 spin_lock(&domain->block_lock);
263 p = &domain->free_blocks.rb_node;
264
265 rem->start = block->start + size;
266 rem->length = block->length - size;
267 atomic_set(&rem->ref, 1);
268 block->length = size;
269
270 while (*p) {
271 parent = *p;
272 b = rb_entry(parent, struct tegra_iovmm_block, free_node);
273 if (rem->length >= b->length)
274 p = &parent->rb_right;
275 else
276 p = &parent->rb_left;
277 }
278 set_bit(BK_FREE, &rem->flags);
279 rb_link_node(&rem->free_node, parent, p);
280 rb_insert_color(&rem->free_node, &domain->free_blocks);
281
282 p = &domain->all_blocks.rb_node;
283 parent = NULL;
284 while (*p) {
285 parent = *p;
286 b = rb_entry(parent, struct tegra_iovmm_block, all_node);
287 if (rem->start >= b->start)
288 p = &parent->rb_right;
289 else
290 p = &parent->rb_left;
291 }
292 rb_link_node(&rem->all_node, parent, p);
293 rb_insert_color(&rem->all_node, &domain->all_blocks);
294
295 return rem;
296}
297
298static int iovmm_block_splitting;
299static struct tegra_iovmm_block *iovmm_alloc_block(
300 struct tegra_iovmm_domain *domain, size_t size, size_t align)
301{
302 struct rb_node *n;
303 struct tegra_iovmm_block *b, *best;
304 size_t simalign;
305 unsigned long page_size = 1 << domain->dev->pgsize_bits;
306
307 BUG_ON(!size);
308
309 size = round_up(size, page_size);
310 align = round_up(align, page_size);
311 for (;;) {
312 spin_lock(&domain->block_lock);
313 if (!iovmm_block_splitting)
314 break;
315 spin_unlock(&domain->block_lock);
316 schedule();
317 }
318 n = domain->free_blocks.rb_node;
319 best = NULL;
320 while (n) {
321 tegra_iovmm_addr_t aligned_start, block_ceil;
322
323 b = rb_entry(n, struct tegra_iovmm_block, free_node);
324 simalign = SIMALIGN(b, align);
325 aligned_start = b->start + simalign;
326 block_ceil = b->start + b->length;
327
328 if (block_ceil >= aligned_start + size) {
329 /* Block has enough size */
330 best = b;
331 if (NO_SPLIT(simalign) &&
332 NO_SPLIT(block_ceil - (aligned_start + size)))
333 break;
334 n = n->rb_left;
335 } else {
336 n = n->rb_right;
337 }
338 }
339 if (!best) {
340 spin_unlock(&domain->block_lock);
341 return NULL;
342 }
343
344 simalign = SIMALIGN(best, align);
345 if (DO_SPLIT(simalign)) {
346 iovmm_block_splitting = 1;
347 spin_unlock(&domain->block_lock);
348
349 /* Split off misalignment */
350 b = best;
351 best = iovmm_split_free_block(domain, b, simalign);
352 if (best)
353 simalign = 0;
354 else
355 best = b;
356 }
357
358 /* Unfree designed block */
359 rb_erase(&best->free_node, &domain->free_blocks);
360 clear_bit(BK_FREE, &best->flags);
361 atomic_inc(&best->ref);
362
363 iovmm_start(best) = best->start + simalign;
364 iovmm_length(best) = size;
365
366 if (DO_SPLIT((best->start + best->length) - iovmm_end(best))) {
367 iovmm_block_splitting = 1;
368 spin_unlock(&domain->block_lock);
369
370 /* Split off excess */
371 (void)iovmm_split_free_block(domain, best, size + simalign);
372 }
373
374 iovmm_block_splitting = 0;
375 spin_unlock(&domain->block_lock);
376
377 return best;
378}
379
380static struct tegra_iovmm_block *iovmm_allocate_vm(
381 struct tegra_iovmm_domain *domain, size_t size,
382 size_t align, unsigned long iovm_start)
383{
384 struct rb_node *n;
385 struct tegra_iovmm_block *b, *best;
386 unsigned long page_size = 1 << domain->dev->pgsize_bits;
387
388 BUG_ON(iovm_start % align);
389 BUG_ON(!size);
390
391 size = round_up(size, page_size);
392 for (;;) {
393 spin_lock(&domain->block_lock);
394 if (!iovmm_block_splitting)
395 break;
396 spin_unlock(&domain->block_lock);
397 schedule();
398 }
399
400 n = rb_first(&domain->free_blocks);
401 best = NULL;
402 while (n) {
403 b = rb_entry(n, struct tegra_iovmm_block, free_node);
404 if ((b->start <= iovm_start) &&
405 (b->start + b->length) >= (iovm_start + size)) {
406 best = b;
407 break;
408 }
409 n = rb_next(n);
410 }
411
412 if (!best)
413 goto fail;
414
415 /* split the mem before iovm_start. */
416 if (DO_SPLIT(iovm_start - best->start)) {
417 iovmm_block_splitting = 1;
418 spin_unlock(&domain->block_lock);
419 best = iovmm_split_free_block(domain, best,
420 (iovm_start - best->start));
421 }
422 if (!best)
423 goto fail;
424
425 /* remove the desired block from free list. */
426 rb_erase(&best->free_node, &domain->free_blocks);
427 clear_bit(BK_FREE, &best->flags);
428 atomic_inc(&best->ref);
429
430 iovmm_start(best) = iovm_start;
431 iovmm_length(best) = size;
432
433 BUG_ON(best->start > iovmm_start(best));
434 BUG_ON((best->start + best->length) < iovmm_end(best));
435 /* split the mem after iovm_start+size. */
436 if (DO_SPLIT(best->start + best->length - iovmm_end(best))) {
437 iovmm_block_splitting = 1;
438 spin_unlock(&domain->block_lock);
439 (void)iovmm_split_free_block(domain, best,
440 (iovmm_start(best) - best->start + size));
441 }
442fail:
443 iovmm_block_splitting = 0;
444 spin_unlock(&domain->block_lock);
445 return best;
446}
447
448int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain,
449 struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start,
450 tegra_iovmm_addr_t end)
451{
452 struct tegra_iovmm_block *b;
453 unsigned long page_size = 1 << dev->pgsize_bits;
454
455 b = kmem_cache_zalloc(iovmm_cache, GFP_KERNEL);
456 if (!b)
457 return -ENOMEM;
458
459 domain->dev = dev;
460
461 atomic_set(&domain->clients, 0);
462 atomic_set(&domain->locks, 0);
463 atomic_set(&b->ref, 1);
464 spin_lock_init(&domain->block_lock);
465 init_rwsem(&domain->map_lock);
466 init_waitqueue_head(&domain->delay_lock);
467
468 b->start = round_up(start, page_size);
469 b->length = round_down(end, page_size) - b->start;
470
471 set_bit(BK_FREE, &b->flags);
472 rb_link_node(&b->free_node, NULL, &domain->free_blocks.rb_node);
473 rb_insert_color(&b->free_node, &domain->free_blocks);
474 rb_link_node(&b->all_node, NULL, &domain->all_blocks.rb_node);
475 rb_insert_color(&b->all_node, &domain->all_blocks);
476
477 return 0;
478}
479
480/*
481 * If iovm_start != 0, tries to allocate specified iova block if it is
482 * free. if it is not free, it fails.
483 */
484struct tegra_iovmm_area *tegra_iovmm_create_vm(
485 struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops,
486 size_t size, size_t align, pgprot_t pgprot, unsigned long iovm_start)
487{
488 struct tegra_iovmm_block *b;
489 struct tegra_iovmm_domain *domain;
490
491 if (!client)
492 return NULL;
493
494 domain = client->domain;
495
496 if (iovm_start)
497 b = iovmm_allocate_vm(domain, size, align, iovm_start);
498 else
499 b = iovmm_alloc_block(domain, size, align);
500 if (!b)
501 return NULL;
502
503 b->vm_area.domain = domain;
504 b->vm_area.pgprot = pgprot;
505 b->vm_area.ops = ops;
506
507 down_read(&b->vm_area.domain->map_lock);
508 if (ops && !test_bit(CL_LOCKED, &client->flags)) {
509 set_bit(BK_MAP_DIRTY, &b->flags);
510 set_bit(DM_MAP_DIRTY, &client->domain->flags);
511 } else if (ops) {
512 if (domain->dev->ops->map(domain, &b->vm_area))
513 pr_err("%s failed to map locked domain\n", __func__);
514 }
515 up_read(&b->vm_area.domain->map_lock);
516
517 return &b->vm_area;
518}
519
520void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *vm,
521 tegra_iovmm_addr_t vaddr, unsigned long pfn)
522{
523 struct tegra_iovmm_domain *domain = vm->domain;
524
525 BUG_ON(vaddr & ((1 << domain->dev->pgsize_bits) - 1));
526 BUG_ON(vaddr >= vm->iovm_start + vm->iovm_length);
527 BUG_ON(vaddr < vm->iovm_start);
528 BUG_ON(vm->ops);
529
530 domain->dev->ops->map_pfn(domain, vm, vaddr, pfn);
531}
532
533void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm)
534{
535 struct tegra_iovmm_block *b;
536 struct tegra_iovmm_domain *domain;
537
538 b = container_of(vm, struct tegra_iovmm_block, vm_area);
539 domain = vm->domain;
540 /*
541 * if the vm area mapping was deferred, don't unmap it since
542 * the memory for the page tables it uses may not be allocated
543 */
544 down_read(&domain->map_lock);
545 if (!test_and_clear_bit(BK_MAP_DIRTY, &b->flags))
546 domain->dev->ops->unmap(domain, vm, false);
547 up_read(&domain->map_lock);
548}
549
550void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm)
551{
552 struct tegra_iovmm_block *b;
553 struct tegra_iovmm_domain *domain;
554
555 b = container_of(vm, struct tegra_iovmm_block, vm_area);
556 domain = vm->domain;
557 if (!vm->ops)
558 return;
559
560 down_read(&domain->map_lock);
561 if (vm->ops) {
562 if (atomic_read(&domain->locks))
563 domain->dev->ops->map(domain, vm);
564 else {
565 set_bit(BK_MAP_DIRTY, &b->flags);
566 set_bit(DM_MAP_DIRTY, &domain->flags);
567 }
568 }
569 up_read(&domain->map_lock);
570}
571
572void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm)
573{
574 struct tegra_iovmm_block *b;
575 struct tegra_iovmm_domain *domain;
576
577 if (!vm)
578 return;
579
580 b = container_of(vm, struct tegra_iovmm_block, vm_area);
581 domain = vm->domain;
582 down_read(&domain->map_lock);
583 if (!test_and_clear_bit(BK_MAP_DIRTY, &b->flags))
584 domain->dev->ops->unmap(domain, vm, true);
585 iovmm_free_block(domain, b);
586 up_read(&domain->map_lock);
587}
588
589struct tegra_iovmm_area *tegra_iovmm_area_get(struct tegra_iovmm_area *vm)
590{
591 struct tegra_iovmm_block *b;
592
593 BUG_ON(!vm);
594 b = container_of(vm, struct tegra_iovmm_block, vm_area);
595
596 atomic_inc(&b->ref);
597 return &b->vm_area;
598}
599
600void tegra_iovmm_area_put(struct tegra_iovmm_area *vm)
601{
602 struct tegra_iovmm_block *b;
603 BUG_ON(!vm);
604 b = container_of(vm, struct tegra_iovmm_block, vm_area);
605 iovmm_block_put(b);
606}
607
608struct tegra_iovmm_area *tegra_iovmm_find_area_get(
609 struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr)
610{
611 struct rb_node *n;
612 struct tegra_iovmm_block *b = NULL;
613
614 if (!client)
615 return NULL;
616
617 spin_lock(&client->domain->block_lock);
618 n = client->domain->all_blocks.rb_node;
619
620 while (n) {
621 b = rb_entry(n, struct tegra_iovmm_block, all_node);
622 if (iovmm_start(b) <= addr && addr <= iovmm_end(b)) {
623 if (test_bit(BK_FREE, &b->flags))
624 b = NULL;
625 break;
626 }
627 if (addr > iovmm_start(b))
628 n = n->rb_right;
629 else
630 n = n->rb_left;
631 b = NULL;
632 }
633 if (b)
634 atomic_inc(&b->ref);
635 spin_unlock(&client->domain->block_lock);
636 if (!b)
637 return NULL;
638 return &b->vm_area;
639}
640
641static int _iovmm_client_lock(struct tegra_iovmm_client *client)
642{
643 struct tegra_iovmm_device *dev;
644 struct tegra_iovmm_domain *domain;
645 int v;
646
647 if (unlikely(!client))
648 return -ENODEV;
649
650 if (unlikely(test_bit(CL_LOCKED, &client->flags))) {
651 pr_err("attempting to relock client %s\n", client->name);
652 return 0;
653 }
654
655 domain = client->domain;
656 dev = domain->dev;
657 down_write(&domain->map_lock);
658 v = atomic_inc_return(&domain->locks);
659 /*
660 * if the device doesn't export the lock_domain function, the
661 * device must guarantee that any valid domain will be locked.
662 */
663 if (v == 1 && dev->ops->lock_domain) {
664 if (dev->ops->lock_domain(domain, client)) {
665 atomic_dec(&domain->locks);
666 up_write(&domain->map_lock);
667 return -EAGAIN;
668 }
669 }
670 if (test_and_clear_bit(DM_MAP_DIRTY, &domain->flags)) {
671 struct rb_node *n;
672 struct tegra_iovmm_block *b;
673
674 spin_lock(&domain->block_lock);
675 n = rb_first(&domain->all_blocks);
676 while (n) {
677 b = rb_entry(n, struct tegra_iovmm_block, all_node);
678 n = rb_next(n);
679 if (test_bit(BK_FREE, &b->flags))
680 continue;
681
682 if (test_and_clear_bit(BK_MAP_DIRTY, &b->flags)) {
683 if (!b->vm_area.ops) {
684 pr_err("%s: "
685 "vm_area ops must exist for lazy maps\n",
686 __func__);
687 continue;
688 }
689 dev->ops->map(domain, &b->vm_area);
690 }
691 }
692 }
693 set_bit(CL_LOCKED, &client->flags);
694 up_write(&domain->map_lock);
695 return 0;
696}
697
698int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client)
699{
700 return _iovmm_client_lock(client);
701}
702
703int tegra_iovmm_client_lock(struct tegra_iovmm_client *client)
704{
705 int ret;
706
707 if (!client)
708 return -ENODEV;
709
710 ret = wait_event_interruptible(client->domain->delay_lock,
711 _iovmm_client_lock(client) != -EAGAIN);
712
713 if (ret == -ERESTARTSYS)
714 return -EINTR;
715
716 return ret;
717}
718
719void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client)
720{
721 struct tegra_iovmm_device *dev;
722 struct tegra_iovmm_domain *domain;
723 int do_wake = 0;
724
725 if (!client)
726 return;
727
728 if (!test_and_clear_bit(CL_LOCKED, &client->flags)) {
729 pr_err("unlocking unlocked client %s\n", client->name);
730 return;
731 }
732
733 domain = client->domain;
734 dev = domain->dev;
735 down_write(&domain->map_lock);
736 if (!atomic_dec_return(&domain->locks)) {
737 if (dev->ops->unlock_domain)
738 dev->ops->unlock_domain(domain, client);
739 do_wake = 1;
740 }
741 up_write(&domain->map_lock);
742 if (do_wake)
743 wake_up(&domain->delay_lock);
744}
745
746size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client)
747{
748 struct tegra_iovmm_domain *domain;
749 struct rb_node *n;
750 struct tegra_iovmm_block *b;
751 size_t size = 0;
752
753 if (!client)
754 return 0;
755
756 domain = client->domain;
757
758 spin_lock(&domain->block_lock);
759 n = rb_first(&domain->all_blocks);
760 while (n) {
761 b = rb_entry(n, struct tegra_iovmm_block, all_node);
762 n = rb_next(n);
763 size += b->length;
764 }
765 spin_unlock(&domain->block_lock);
766
767 return size;
768}
769
770void tegra_iovmm_free_client(struct tegra_iovmm_client *client)
771{
772 struct tegra_iovmm_device *dev;
773 struct tegra_iovmm_domain *domain;
774
775 if (!client)
776 return;
777
778 BUG_ON(!client->domain || !client->domain->dev);
779
780 domain = client->domain;
781 dev = domain->dev;
782
783 if (test_and_clear_bit(CL_LOCKED, &client->flags)) {
784 pr_err("freeing locked client %s\n", client->name);
785 if (!atomic_dec_return(&domain->locks)) {
786 down_write(&domain->map_lock);
787 if (dev->ops->unlock_domain)
788 dev->ops->unlock_domain(domain, client);
789 up_write(&domain->map_lock);
790 wake_up(&domain->delay_lock);
791 }
792 }
793 mutex_lock(&iovmm_group_list_lock);
794 if (!atomic_dec_return(&domain->clients))
795 if (dev->ops->free_domain)
796 dev->ops->free_domain(domain, client);
797 list_del(&client->list);
798 if (list_empty(&client->group->client_list)) {
799 list_del(&client->group->group_list);
800 kfree(client->group->name);
801 kfree(client->group);
802 }
803 kfree(client->name);
804 kfree(client);
805 mutex_unlock(&iovmm_group_list_lock);
806}
807
808struct tegra_iovmm_client *tegra_iovmm_alloc_client(const char *name,
809 const char *share_group, struct miscdevice *misc_dev)
810{
811 struct tegra_iovmm_client *c = kzalloc(sizeof(*c), GFP_KERNEL);
812 struct iovmm_share_group *grp = NULL;
813 struct tegra_iovmm_device *dev;
814
815 if (!c)
816 return NULL;
817 c->name = kstrdup(name, GFP_KERNEL);
818 if (!c->name)
819 goto fail;
820 c->misc_dev = misc_dev;
821
822 mutex_lock(&iovmm_group_list_lock);
823 if (share_group) {
824 list_for_each_entry(grp, &iovmm_groups, group_list) {
825 if (grp->name && !strcmp(grp->name, share_group))
826 break;
827 }
828 }
829 if (!grp || strcmp(grp->name, share_group)) {
830 grp = kzalloc(sizeof(*grp), GFP_KERNEL);
831 if (!grp)
832 goto fail_lock;
833 grp->name =
834 share_group ? kstrdup(share_group, GFP_KERNEL) : NULL;
835 if (share_group && !grp->name) {
836 kfree(grp);
837 goto fail_lock;
838 }
839 list_for_each_entry(dev, &iovmm_devices, list) {
840 grp->domain = dev->ops->alloc_domain(dev, c);
841 if (grp->domain)
842 break;
843 }
844 if (!grp->domain) {
845 pr_err("%s: alloc_domain failed for %s\n",
846 __func__, c->name);
847 dump_stack();
848 kfree(grp->name);
849 kfree(grp);
850 grp = NULL;
851 goto fail_lock;
852 }
853 spin_lock_init(&grp->lock);
854 INIT_LIST_HEAD(&grp->client_list);
855 list_add_tail(&grp->group_list, &iovmm_groups);
856 }
857
858 atomic_inc(&grp->domain->clients);
859 c->group = grp;
860 c->domain = grp->domain;
861 spin_lock(&grp->lock);
862 list_add_tail(&c->list, &grp->client_list);
863 spin_unlock(&grp->lock);
864 mutex_unlock(&iovmm_group_list_lock);
865 return c;
866
867fail_lock:
868 mutex_unlock(&iovmm_group_list_lock);
869fail:
870 if (c)
871 kfree(c->name);
872 kfree(c);
873 return NULL;
874}
875
876int tegra_iovmm_register(struct tegra_iovmm_device *dev)
877{
878 BUG_ON(!dev);
879 mutex_lock(&iovmm_group_list_lock);
880 if (list_empty(&iovmm_devices)) {
881 iovmm_cache = KMEM_CACHE(tegra_iovmm_block, 0);
882 if (!iovmm_cache) {
883 pr_err("%s: failed to make kmem cache\n", __func__);
884 mutex_unlock(&iovmm_group_list_lock);
885 return -ENOMEM;
886 }
887 create_proc_read_entry("iovmminfo", S_IRUGO, NULL,
888 tegra_iovmm_read_proc, NULL);
889 }
890 list_add_tail(&dev->list, &iovmm_devices);
891 mutex_unlock(&iovmm_group_list_lock);
892 pr_info("%s: added %s\n", __func__, dev->name);
893 return 0;
894}
895
896int tegra_iovmm_unregister(struct tegra_iovmm_device *dev)
897{
898 mutex_lock(&iovmm_group_list_lock);
899 list_del(&dev->list);
900 mutex_unlock(&iovmm_group_list_lock);
901 return 0;
902}
903
904static int tegra_iovmm_suspend(void)
905{
906 int rc = 0;
907 struct tegra_iovmm_device *dev;
908
909 list_for_each_entry(dev, &iovmm_devices, list) {
910 if (!dev->ops->suspend)
911 continue;
912
913 rc = dev->ops->suspend(dev);
914 if (rc) {
915 pr_err("%s: %s suspend returned %d\n",
916 __func__, dev->name, rc);
917 return rc;
918 }
919 }
920 return 0;
921}
922
923static void tegra_iovmm_resume(void)
924{
925 struct tegra_iovmm_device *dev;
926
927 list_for_each_entry(dev, &iovmm_devices, list) {
928 if (dev->ops->resume)
929 dev->ops->resume(dev);
930 }
931}
932
933static struct syscore_ops tegra_iovmm_syscore_ops = {
934 .suspend = tegra_iovmm_suspend,
935 .resume = tegra_iovmm_resume,
936};
937
938static __init int tegra_iovmm_syscore_init(void)
939{
940 register_syscore_ops(&tegra_iovmm_syscore_ops);
941 return 0;
942}
943subsys_initcall(tegra_iovmm_syscore_init);
diff --git a/arch/arm/mach-tegra/kfuse.c b/arch/arm/mach-tegra/kfuse.c
new file mode 100644
index 00000000000..9e4b482e469
--- /dev/null
+++ b/arch/arm/mach-tegra/kfuse.c
@@ -0,0 +1,114 @@
1/*
2 * arch/arm/mach-tegra/kfuse.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/* The kfuse block stores downstream and upstream HDCP keys for use by HDMI
18 * module.
19 */
20
21#include <linux/kernel.h>
22#include <linux/io.h>
23#include <linux/err.h>
24#include <linux/string.h>
25#include <linux/delay.h>
26#include <linux/clk.h>
27
28#include <mach/iomap.h>
29#include <mach/kfuse.h>
30
31#include "clock.h"
32#include "apbio.h"
33
34static struct clk *kfuse_clk = NULL;
35
36/* register definition */
37#define KFUSE_STATE 0x80
38#define KFUSE_STATE_DONE (1u << 16)
39#define KFUSE_STATE_CRCPASS (1u << 17)
40#define KFUSE_KEYADDR 0x88
41#define KFUSE_KEYADDR_AUTOINC (1u << 16)
42#define KFUSE_KEYS 0x8c
43
44static inline u32 tegra_kfuse_readl(unsigned long offset)
45{
46 return tegra_apb_readl(TEGRA_KFUSE_BASE + offset);
47}
48
49static inline void tegra_kfuse_writel(u32 value, unsigned long offset)
50{
51 tegra_apb_writel(value, TEGRA_KFUSE_BASE + offset);
52}
53
54static int wait_for_done(void)
55{
56 u32 reg;
57 int retries = 50;
58 do {
59 reg = tegra_kfuse_readl(KFUSE_STATE);
60 if (reg & KFUSE_STATE_DONE)
61 return 0;
62 msleep(10);
63 } while(--retries);
64 return -ETIMEDOUT;
65}
66
67/* read up to KFUSE_DATA_SZ bytes into dest.
68 * always starts at the first kfuse.
69 */
70int tegra_kfuse_read(void *dest, size_t len)
71{
72 int err;
73 u32 v;
74 unsigned cnt;
75
76 if (len > KFUSE_DATA_SZ)
77 return -EINVAL;
78
79 if (kfuse_clk == NULL) {
80 kfuse_clk = tegra_get_clock_by_name("kfuse");
81 if (IS_ERR_OR_NULL(kfuse_clk)) {
82 pr_err("kfuse: can't get kfuse clock\n");
83 return -EINVAL;
84 }
85 }
86
87 err = clk_enable(kfuse_clk);
88 if (err)
89 return err;
90
91 tegra_kfuse_writel(KFUSE_KEYADDR_AUTOINC, KFUSE_KEYADDR);
92
93 err = wait_for_done();
94 if (err) {
95 pr_err("kfuse: read timeout\n");
96 clk_disable(kfuse_clk);
97 return err;
98 }
99
100 if ((tegra_kfuse_readl(KFUSE_STATE) & KFUSE_STATE_CRCPASS) == 0) {
101 pr_err("kfuse: crc failed\n");
102 clk_disable(kfuse_clk);
103 return -EIO;
104 }
105
106 for (cnt = 0; cnt < len; cnt += 4) {
107 v = tegra_kfuse_readl(KFUSE_KEYS);
108 memcpy(dest + cnt, &v, sizeof v);
109 }
110
111 clk_disable(kfuse_clk);
112
113 return 0;
114}
diff --git a/arch/arm/mach-tegra/latency_allowance.c b/arch/arm/mach-tegra/latency_allowance.c
new file mode 100644
index 00000000000..7698ba39f4c
--- /dev/null
+++ b/arch/arm/mach-tegra/latency_allowance.c
@@ -0,0 +1,598 @@
1/*
2 * arch/arm/mach-tegra/latency_allowance.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
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/types.h>
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/debugfs.h>
21#include <linux/seq_file.h>
22#include <linux/err.h>
23#include <linux/spinlock_types.h>
24#include <linux/spinlock.h>
25#include <linux/stringify.h>
26#include <asm/bug.h>
27#include <asm/io.h>
28#include <asm/string.h>
29#include <mach/iomap.h>
30#include <mach/io.h>
31#include <mach/latency_allowance.h>
32
33#define MC_ARB_OVERRIDE 0xe8
34#define GLOBAL_LATENCY_SCALING_ENABLE_BIT 7
35
36#define MC_LA_AFI_0 0x2e0
37#define MC_LA_AVPC_ARM7_0 0x2e4
38#define MC_LA_DC_0 0x2e8
39#define MC_LA_DC_1 0x2ec
40#define MC_LA_DC_2 0x2f0
41#define MC_LA_DCB_0 0x2f4
42#define MC_LA_DCB_1 0x2f8
43#define MC_LA_DCB_2 0x2fc
44#define MC_LA_EPP_0 0x300
45#define MC_LA_EPP_1 0x304
46#define MC_LA_G2_0 0x308
47#define MC_LA_G2_1 0x30c
48#define MC_LA_HC_0 0x310
49#define MC_LA_HC_1 0x314
50#define MC_LA_HDA_0 0x318
51#define MC_LA_ISP_0 0x31C
52#define MC_LA_MPCORE_0 0x320
53#define MC_LA_MPCORELP_0 0x324
54#define MC_LA_MPE_0 0x328
55#define MC_LA_MPE_1 0x32c
56#define MC_LA_MPE_2 0x330
57#define MC_LA_NV_0 0x334
58#define MC_LA_NV_1 0x338
59#define MC_LA_NV2_0 0x33c
60#define MC_LA_NV2_1 0x340
61#define MC_LA_PPCS_0 0x344
62#define MC_LA_PPCS_1 0x348
63#define MC_LA_PTC_0 0x34c
64#define MC_LA_SATA_0 0x350
65#define MC_LA_VDE_0 0x354
66#define MC_LA_VDE_1 0x358
67#define MC_LA_VDE_2 0x35c
68#define MC_LA_VDE_3 0x360
69#define MC_LA_VI_0 0x364
70#define MC_LA_VI_1 0x368
71#define MC_LA_VI_2 0x36c
72
73#define DS_DISP_MCCIF_DISPLAY0A_HYST (0x481 * 4)
74#define DS_DISP_MCCIF_DISPLAY0B_HYST (0x482 * 4)
75#define DS_DISP_MCCIF_DISPLAY0C_HYST (0x483 * 4)
76#define DS_DISP_MCCIF_DISPLAY1B_HYST (0x484 * 4)
77
78#define DS_DISP_MCCIF_DISPLAY0AB_HYST (0x481 * 4)
79#define DS_DISP_MCCIF_DISPLAY0BB_HYST (0x482 * 4)
80#define DS_DISP_MCCIF_DISPLAY0CB_HYST (0x483 * 4)
81#define DS_DISP_MCCIF_DISPLAY1BB_HYST (0x484 * 4)
82
83#define VI_MCCIF_VIWSB_HYST (0x9a * 4)
84#define VI_MCCIF_VIWU_HYST (0x9b * 4)
85#define VI_MCCIF_VIWV_HYST (0x9c * 4)
86#define VI_MCCIF_VIWY_HYST (0x9d * 4)
87
88#define VI_TIMEOUT_WOCAL_VI (0x70 * 4)
89#define VI_RESERVE_3 (0x97 * 4)
90#define VI_RESERVE_4 (0x98 * 4)
91
92/* maximum valid value for latency allowance */
93#define MC_LA_MAX_VALUE 255
94
95#define ENABLE_LA_DEBUG 0
96#define TEST_LA_CODE 0
97
98#define la_debug(fmt, ...) \
99 if (ENABLE_LA_DEBUG) { \
100 printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__); \
101 }
102
103static struct dentry *latency_debug_dir;
104
105struct la_client_info {
106 unsigned int fifo_size_in_atoms;
107 unsigned int expiration_in_ns; /* worst case expiration value */
108 unsigned long reg_addr;
109 unsigned long mask;
110 unsigned long shift;
111 enum tegra_la_id id;
112 char *name;
113 bool scaling_supported;
114};
115
116static DEFINE_SPINLOCK(safety_lock);
117
118static const int ns_per_tick = 30;
119/* fifo atom size in bytes for non-fdc clients*/
120static const int normal_atom_size = 16;
121/* fifo atom size in bytes for fdc clients*/
122static const int fdc_atom_size = 32;
123
124#define MC_RA(r) \
125 ((u32)IO_ADDRESS(TEGRA_MC_BASE) + (MC_##r))
126#define RA(r) \
127 ((u32)IO_ADDRESS(TEGRA_MC_BASE) + (MC_LA_##r))
128
129#define MASK(x) \
130 ((0xFFFFFFFFUL >> (31 - (1 ? x) + (0 ? x))) << (0 ? x))
131#define SHIFT(x) \
132 (0 ? x)
133#define ID(id) \
134 TEGRA_LA_##id
135
136#define LA_INFO(f, e, a, r, id, ss) \
137{f, e, RA(a), MASK(r), SHIFT(r), ID(id), __stringify(id), ss}
138
139/*
140 * The rule for getting the fifo_size_in_atoms is:
141 * 1.If REORDER_DEPTH exists, use it(default is overridden).
142 * 2.Else if (write_client) use RFIFO_DEPTH.
143 * 3.Else (read client) use RDFIFO_DEPTH.
144 * Refer to project.h file.
145 */
146struct la_client_info la_info[] = {
147 LA_INFO(32, 150, AFI_0, 7 : 0, AFIR, false),
148 LA_INFO(32, 150, AFI_0, 23 : 16, AFIW, false),
149 LA_INFO(2, 150, AVPC_ARM7_0, 7 : 0, AVPC_ARM7R, false),
150 LA_INFO(2, 150, AVPC_ARM7_0, 23 : 16, AVPC_ARM7W, false),
151 LA_INFO(128, 1050, DC_0, 7 : 0, DISPLAY_0A, true),
152 LA_INFO(64, 1050, DC_0, 23 : 16, DISPLAY_0B, true),
153 LA_INFO(128, 1050, DC_1, 7 : 0, DISPLAY_0C, true),
154 LA_INFO(64, 1050, DC_1, 23 : 16, DISPLAY_1B, true),
155 LA_INFO(2, 1050, DC_2, 7 : 0, DISPLAY_HC, false),
156 LA_INFO(128, 1050, DCB_0, 7 : 0, DISPLAY_0AB, true),
157 LA_INFO(64, 1050, DCB_0, 23 : 16, DISPLAY_0BB, true),
158 LA_INFO(128, 1050, DCB_1, 7 : 0, DISPLAY_0CB, true),
159 LA_INFO(64, 1050, DCB_1, 23 : 16, DISPLAY_1BB, true),
160 LA_INFO(2, 1050, DCB_2, 7 : 0, DISPLAY_HCB, false),
161 LA_INFO(8, 150, EPP_0, 7 : 0, EPPUP, false),
162 LA_INFO(64, 150, EPP_0, 23 : 16, EPPU, false),
163 LA_INFO(64, 150, EPP_1, 7 : 0, EPPV, false),
164 LA_INFO(64, 150, EPP_1, 23 : 16, EPPY, false),
165 LA_INFO(64, 150, G2_0, 7 : 0, G2PR, false),
166 LA_INFO(64, 150, G2_0, 23 : 16, G2SR, false),
167 LA_INFO(48, 150, G2_1, 7 : 0, G2DR, false),
168 LA_INFO(128, 150, G2_1, 23 : 16, G2DW, false),
169 LA_INFO(16, 150, HC_0, 7 : 0, HOST1X_DMAR, false),
170 LA_INFO(8, 150, HC_0, 23 : 16, HOST1XR, false),
171 LA_INFO(32, 150, HC_1, 7 : 0, HOST1XW, false),
172 LA_INFO(16, 150, HDA_0, 7 : 0, HDAR, false),
173 LA_INFO(16, 150, HDA_0, 23 : 16, HDAW, false),
174 LA_INFO(64, 150, ISP_0, 7 : 0, ISPW, false),
175 LA_INFO(14, 150, MPCORE_0, 7 : 0, MPCORER, false),
176 LA_INFO(24, 150, MPCORE_0, 23 : 16, MPCOREW, false),
177 LA_INFO(14, 150, MPCORELP_0, 7 : 0, MPCORE_LPR, false),
178 LA_INFO(24, 150, MPCORELP_0, 23 : 16, MPCORE_LPW, false),
179 LA_INFO(8, 150, MPE_0, 7 : 0, MPE_UNIFBR, false),
180 LA_INFO(2, 150, MPE_0, 23 : 16, MPE_IPRED, false),
181 LA_INFO(64, 150, MPE_1, 7 : 0, MPE_AMEMRD, false),
182 LA_INFO(8, 150, MPE_1, 23 : 16, MPE_CSRD, false),
183 LA_INFO(8, 150, MPE_2, 7 : 0, MPE_UNIFBW, false),
184 LA_INFO(8, 150, MPE_2, 23 : 16, MPE_CSWR, false),
185 LA_INFO(48, 150, NV_0, 7 : 0, FDCDRD, false),
186 LA_INFO(64, 150, NV_0, 23 : 16, IDXSRD, false),
187 LA_INFO(64, 150, NV_1, 7 : 0, TEXSRD, false),
188 LA_INFO(48, 150, NV_1, 23 : 16, FDCDWR, false),
189 LA_INFO(48, 150, NV2_0, 7 : 0, FDCDRD2, false),
190 LA_INFO(64, 150, NV2_0, 23 : 16, IDXSRD2, false),
191 LA_INFO(64, 150, NV2_1, 7 : 0, TEXSRD2, false),
192 LA_INFO(48, 150, NV2_1, 23 : 16, FDCDWR2, false),
193 LA_INFO(2, 150, PPCS_0, 7 : 0, PPCS_AHBDMAR, false),
194 LA_INFO(8, 150, PPCS_0, 23 : 16, PPCS_AHBSLVR, false),
195 LA_INFO(2, 150, PPCS_1, 7 : 0, PPCS_AHBDMAW, false),
196 LA_INFO(4, 150, PPCS_1, 23 : 16, PPCS_AHBSLVW, false),
197 LA_INFO(2, 150, PTC_0, 7 : 0, PTCR, false),
198 LA_INFO(32, 150, SATA_0, 7 : 0, SATAR, false),
199 LA_INFO(32, 150, SATA_0, 23 : 16, SATAW, false),
200 LA_INFO(8, 150, VDE_0, 7 : 0, VDE_BSEVR, false),
201 LA_INFO(4, 150, VDE_0, 23 : 16, VDE_MBER, false),
202 LA_INFO(16, 150, VDE_1, 7 : 0, VDE_MCER, false),
203 LA_INFO(16, 150, VDE_1, 23 : 16, VDE_TPER, false),
204 LA_INFO(4, 150, VDE_2, 7 : 0, VDE_BSEVW, false),
205 LA_INFO(16, 150, VDE_2, 23 : 16, VDE_DBGW, false),
206 LA_INFO(2, 150, VDE_3, 7 : 0, VDE_MBEW, false),
207 LA_INFO(16, 150, VDE_3, 23 : 16, VDE_TPMW, false),
208 LA_INFO(8, 1050, VI_0, 7 : 0, VI_RUV, false),
209 LA_INFO(64, 1050, VI_0, 23 : 16, VI_WSB, true),
210 LA_INFO(64, 1050, VI_1, 7 : 0, VI_WU, true),
211 LA_INFO(64, 1050, VI_1, 23 : 16, VI_WV, true),
212 LA_INFO(64, 1050, VI_2, 7 : 0, VI_WY, true),
213
214/* end of list. */
215 LA_INFO(0, 0, AFI_0, 0 : 0, MAX_ID, false)
216};
217
218struct la_scaling_info {
219 unsigned int threshold_low;
220 unsigned int threshold_mid;
221 unsigned int threshold_high;
222 int scaling_ref_count;
223 int actual_la_to_set;
224 int la_set;
225};
226
227struct la_scaling_reg_info {
228 enum tegra_la_id id;
229 unsigned int tl_reg_addr;
230 unsigned int tl_mask;
231 unsigned int tl_shift;
232 unsigned int tm_reg_addr;
233 unsigned int tm_mask;
234 unsigned int tm_shift;
235 unsigned int th_reg_addr;
236 unsigned int th_mask;
237 unsigned int th_shift;
238};
239
240#define DISP1_RA(r) \
241 ((u32)IO_ADDRESS(TEGRA_DISPLAY_BASE) + DS_DISP_MCCIF_##r##_HYST)
242#define DISP2_RA(r) \
243 ((u32)IO_ADDRESS(TEGRA_DISPLAY2_BASE) + DS_DISP_MCCIF_##r##_HYST)
244
245#define DISP_SCALING_REG_INFO(id, r, ra) \
246 { \
247 ID(id), \
248 ra(r), MASK(15 : 8), SHIFT(15 : 8), \
249 ra(r), MASK(23 : 16), SHIFT(15 : 8), \
250 ra(r), MASK(7 : 0), SHIFT(15 : 8) \
251 }
252
253struct la_scaling_reg_info disp_info[] = {
254 DISP_SCALING_REG_INFO(DISPLAY_0A, DISPLAY0A, DISP1_RA),
255 DISP_SCALING_REG_INFO(DISPLAY_0B, DISPLAY0B, DISP1_RA),
256 DISP_SCALING_REG_INFO(DISPLAY_0C, DISPLAY0C, DISP1_RA),
257 DISP_SCALING_REG_INFO(DISPLAY_1B, DISPLAY1B, DISP1_RA),
258 DISP_SCALING_REG_INFO(MAX_ID, DISPLAY1B, DISP1_RA), /*dummy entry*/
259 DISP_SCALING_REG_INFO(DISPLAY_0AB, DISPLAY0AB, DISP2_RA),
260 DISP_SCALING_REG_INFO(DISPLAY_0BB, DISPLAY0BB, DISP2_RA),
261 DISP_SCALING_REG_INFO(DISPLAY_0CB, DISPLAY0CB, DISP2_RA),
262 DISP_SCALING_REG_INFO(DISPLAY_1BB, DISPLAY1BB, DISP2_RA),
263};
264
265#define VI_TH_RA(r) \
266 ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_MCCIF_##r##_HYST)
267#define VI_TM_RA(r) \
268 ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_TIMEOUT_WOCAL_VI)
269#define VI_TL_RA(r) \
270 ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_RESERVE_##r)
271
272struct la_scaling_reg_info vi_info[] = {
273 {
274 ID(VI_WSB),
275 VI_TL_RA(4), MASK(7 : 0), SHIFT(7 : 0),
276 VI_TM_RA(0), MASK(7 : 0), SHIFT(7 : 0),
277 VI_TH_RA(VIWSB), MASK(7 : 0), SHIFT(7 : 0)
278 },
279 {
280 ID(VI_WU),
281 VI_TL_RA(3), MASK(15 : 8), SHIFT(15 : 8),
282 VI_TM_RA(0), MASK(15 : 8), SHIFT(15 : 8),
283 VI_TH_RA(VIWU), MASK(7 : 0), SHIFT(7 : 0)
284 },
285 {
286 ID(VI_WV),
287 VI_TL_RA(3), MASK(7 : 0), SHIFT(7 : 0),
288 VI_TM_RA(0), MASK(23 : 16), SHIFT(23 : 16),
289 VI_TH_RA(VIWV), MASK(7 : 0), SHIFT(7 : 0)
290 },
291 {
292 ID(VI_WY),
293 VI_TL_RA(4), MASK(15 : 8), SHIFT(15 : 8),
294 VI_TM_RA(0), MASK(31 : 24), SHIFT(31 : 24),
295 VI_TH_RA(VIWY), MASK(7 : 0), SHIFT(7 : 0)
296 }
297};
298
299static struct la_scaling_info scaling_info[TEGRA_LA_MAX_ID];
300static int la_scaling_enable_count;
301
302#define VALIDATE_ID(id) \
303 do { \
304 if (id >= TEGRA_LA_MAX_ID) \
305 return -EINVAL; \
306 BUG_ON(la_info[id].id != id); \
307 } while (0)
308
309#define VALIDATE_BW(bw_in_mbps) \
310 do { \
311 if (bw_in_mbps >= 4096) \
312 return -EINVAL; \
313 } while (0)
314
315#define VALIDATE_THRESHOLDS(tl, tm, th) \
316 do { \
317 if (tl > 100 || tm > 100 || th > 100) \
318 return -EINVAL; \
319 } while (0)
320
321static void set_thresholds(struct la_scaling_reg_info *info,
322 enum tegra_la_id id)
323{
324 unsigned long reg_read;
325 unsigned long reg_write;
326 unsigned int thresh_low;
327 unsigned int thresh_mid;
328 unsigned int thresh_high;
329 int la_set;
330
331 reg_read = readl(la_info[id].reg_addr);
332 la_set = (reg_read & la_info[id].mask) >> la_info[id].shift;
333 /* la should be set before enabling scaling. */
334 BUG_ON(la_set != scaling_info[id].la_set);
335
336 thresh_low = (scaling_info[id].threshold_low * la_set) / 100;
337 thresh_mid = (scaling_info[id].threshold_mid * la_set) / 100;
338 thresh_high = (scaling_info[id].threshold_high * la_set) / 100;
339 la_debug("%s: la_set=%d, thresh_low=%d(%d%%), thresh_mid=%d(%d%%),"
340 " thresh_high=%d(%d%%) ", __func__, la_set,
341 thresh_low, scaling_info[id].threshold_low,
342 thresh_mid, scaling_info[id].threshold_mid,
343 thresh_high, scaling_info[id].threshold_high);
344
345 reg_read = readl(info->tl_reg_addr);
346 reg_write = (reg_read & ~info->tl_mask) |
347 (thresh_low << info->tl_shift);
348 writel(reg_write, info->tl_reg_addr);
349 la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
350 (u32)info->tl_reg_addr, (u32)reg_read, (u32)reg_write);
351
352 reg_read = readl(info->tm_reg_addr);
353 reg_write = (reg_read & ~info->tm_mask) |
354 (thresh_mid << info->tm_shift);
355 writel(reg_write, info->tm_reg_addr);
356 la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
357 (u32)info->tm_reg_addr, (u32)reg_read, (u32)reg_write);
358
359 reg_read = readl(info->th_reg_addr);
360 reg_write = (reg_read & ~info->th_mask) |
361 (thresh_high << info->th_shift);
362 writel(reg_write, info->th_reg_addr);
363 la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
364 (u32)info->th_reg_addr, (u32)reg_read, (u32)reg_write);
365}
366
367static void set_disp_latency_thresholds(enum tegra_la_id id)
368{
369 set_thresholds(&disp_info[id - ID(DISPLAY_0A)], id);
370}
371
372static void set_vi_latency_thresholds(enum tegra_la_id id)
373{
374 set_thresholds(&vi_info[id - ID(VI_WSB)], id);
375}
376
377/* Sets latency allowance based on clients memory bandwitdh requirement.
378 * Bandwidth passed is in mega bytes per second.
379 */
380int tegra_set_latency_allowance(enum tegra_la_id id,
381 unsigned int bandwidth_in_mbps)
382{
383 int ideal_la;
384 int la_to_set;
385 unsigned long reg_read;
386 unsigned long reg_write;
387 int bytes_per_atom = normal_atom_size;
388 struct la_client_info *ci;
389
390 VALIDATE_ID(id);
391 VALIDATE_BW(bandwidth_in_mbps);
392 if (id == ID(FDCDRD) || id == ID(FDCDWR) ||
393 id == ID(FDCDRD2) || id == ID(FDCDWR2))
394 bytes_per_atom = fdc_atom_size;
395
396 ci = &la_info[id];
397
398 if (bandwidth_in_mbps == 0) {
399 la_to_set = MC_LA_MAX_VALUE;
400 } else {
401 ideal_la = (ci->fifo_size_in_atoms * bytes_per_atom * 1000) /
402 (bandwidth_in_mbps * ns_per_tick);
403 la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
404 }
405
406 la_debug("\n%s:id=%d,bw=%dmbps, la_to_set=%d",
407 __func__, id, bandwidth_in_mbps, la_to_set);
408 la_to_set = (la_to_set < 0) ? 0 : la_to_set;
409 la_to_set = (la_to_set > MC_LA_MAX_VALUE) ? MC_LA_MAX_VALUE : la_to_set;
410 scaling_info[id].actual_la_to_set = la_to_set;
411
412 /* until display can use latency allowance scaling, use a more
413 * aggressive LA setting. Bug 862709 */
414 if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
415 la_to_set /= 3;
416
417 spin_lock(&safety_lock);
418 reg_read = readl(ci->reg_addr);
419 reg_write = (reg_read & ~ci->mask) |
420 (la_to_set << ci->shift);
421 writel(reg_write, ci->reg_addr);
422 scaling_info[id].la_set = la_to_set;
423 la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
424 (u32)ci->reg_addr, (u32)reg_read, (u32)reg_write);
425 spin_unlock(&safety_lock);
426 return 0;
427}
428
429/* Thresholds for scaling are specified in % of fifo freeness.
430 * If threshold_low is specified as 20%, it means when the fifo free
431 * between 0 to 20%, use la as programmed_la.
432 * If threshold_mid is specified as 50%, it means when the fifo free
433 * between 20 to 50%, use la as programmed_la/2 .
434 * If threshold_high is specified as 80%, it means when the fifo free
435 * between 50 to 80%, use la as programmed_la/4.
436 * When the fifo is free between 80 to 100%, use la as 0(highest priority).
437 */
438int tegra_enable_latency_scaling(enum tegra_la_id id,
439 unsigned int threshold_low,
440 unsigned int threshold_mid,
441 unsigned int threshold_high)
442{
443 unsigned long reg;
444 unsigned long scaling_enable_reg = MC_RA(ARB_OVERRIDE);
445
446 VALIDATE_ID(id);
447 VALIDATE_THRESHOLDS(threshold_low, threshold_mid, threshold_high);
448
449 if (la_info[id].scaling_supported == false)
450 goto exit;
451
452 spin_lock(&safety_lock);
453
454 la_debug("\n%s: id=%d, tl=%d, tm=%d, th=%d", __func__,
455 id, threshold_low, threshold_mid, threshold_high);
456 scaling_info[id].threshold_low = threshold_low;
457 scaling_info[id].threshold_mid = threshold_mid;
458 scaling_info[id].threshold_high = threshold_high;
459 scaling_info[id].scaling_ref_count++;
460
461 if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_1BB))
462 set_disp_latency_thresholds(id);
463 else if (id >= ID(VI_WSB) && id <= ID(VI_WY))
464 set_vi_latency_thresholds(id);
465 if (!la_scaling_enable_count++) {
466 reg = readl(scaling_enable_reg);
467 reg |= (1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT);
468 writel(reg, scaling_enable_reg);
469 la_debug("enabled scaling.");
470 }
471 spin_unlock(&safety_lock);
472exit:
473 return 0;
474}
475
476void tegra_disable_latency_scaling(enum tegra_la_id id)
477{
478 unsigned long reg;
479 unsigned long scaling_enable_reg = MC_RA(ARB_OVERRIDE);
480
481 if (id >= TEGRA_LA_MAX_ID)
482 return;
483 BUG_ON(la_info[id].id != id);
484
485 if (la_info[id].scaling_supported == false)
486 return;
487 spin_lock(&safety_lock);
488 la_debug("\n%s: id=%d", __func__, id);
489 scaling_info[id].scaling_ref_count--;
490 BUG_ON(scaling_info[id].scaling_ref_count < 0);
491
492 if (!--la_scaling_enable_count) {
493 reg = readl(scaling_enable_reg);
494 reg = reg & ~(1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT);
495 writel(reg, scaling_enable_reg);
496 la_debug("disabled scaling.");
497 }
498 spin_unlock(&safety_lock);
499}
500
501static int la_regs_show(struct seq_file *s, void *unused)
502{
503 unsigned i;
504 unsigned long la;
505
506 /* iterate the list, but don't print MAX_ID */
507 for (i = 0; i < ARRAY_SIZE(la_info) - 1; i++) {
508 la = (readl(la_info[i].reg_addr) & la_info[i].mask)
509 >> la_info[i].shift;
510 seq_printf(s, "%-16s: %4lu\n", la_info[i].name, la);
511 }
512
513 return 0;
514}
515
516static int dbg_la_regs_open(struct inode *inode, struct file *file)
517{
518 return single_open(file, la_regs_show, inode->i_private);
519}
520
521static const struct file_operations regs_fops = {
522 .open = dbg_la_regs_open,
523 .read = seq_read,
524 .llseek = seq_lseek,
525 .release = single_release,
526};
527
528static int __init tegra_latency_allowance_debugfs_init(void)
529{
530 if (latency_debug_dir)
531 return 0;
532
533 latency_debug_dir = debugfs_create_dir("tegra_latency", NULL);
534
535 debugfs_create_file("la_info", S_IRUGO, latency_debug_dir, NULL,
536 &regs_fops);
537
538 return 0;
539}
540
541late_initcall(tegra_latency_allowance_debugfs_init);
542
543static int __init tegra_latency_allowance_init(void)
544{
545 la_scaling_enable_count = 0;
546
547 tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
548 tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
549 tegra_set_latency_allowance(TEGRA_LA_G2DR, 20);
550 tegra_set_latency_allowance(TEGRA_LA_G2DW, 20);
551 return 0;
552}
553
554core_initcall(tegra_latency_allowance_init);
555
556#if TEST_LA_CODE
557static int __init test_la(void)
558{
559 int err;
560 enum tegra_la_id id = 0;
561 int repeat_count = 5;
562
563 do {
564 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
565 err = tegra_set_latency_allowance(id, 200);
566 if (err)
567 la_debug("\n***tegra_set_latency_allowance,"
568 " err=%d", err);
569 }
570
571 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
572 if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
573 continue;
574 if (id >= ID(VI_WSB) && id <= ID(VI_WY))
575 continue;
576 err = tegra_enable_latency_scaling(id, 20, 50, 80);
577 if (err)
578 la_debug("\n***tegra_enable_latency_scaling,"
579 " err=%d", err);
580 }
581
582 la_debug("la_scaling_enable_count =%d",
583 la_scaling_enable_count);
584 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
585 if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
586 continue;
587 if (id >= ID(VI_WSB) && id <= ID(VI_WY))
588 continue;
589 tegra_disable_latency_scaling(id);
590 }
591 la_debug("la_scaling_enable_count=%d",
592 la_scaling_enable_count);
593 } while (--repeat_count);
594 return 0;
595}
596
597late_initcall(test_la);
598#endif
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
new file mode 100644
index 00000000000..e91d681d45a
--- /dev/null
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -0,0 +1,26 @@
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 */
21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{
23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt);
25 return 0;
26}
diff --git a/arch/arm/mach-tegra/mc.c b/arch/arm/mach-tegra/mc.c
new file mode 100644
index 00000000000..0dff50461a3
--- /dev/null
+++ b/arch/arm/mach-tegra/mc.c
@@ -0,0 +1,73 @@
1/*
2 * arch/arm/mach-tegra/mc.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation
6 *
7 * Author:
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/io.h>
22#include <linux/spinlock.h>
23
24#include <mach/iomap.h>
25#include <mach/mc.h>
26
27#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
28static DEFINE_SPINLOCK(tegra_mc_lock);
29
30void tegra_mc_set_priority(unsigned long client, unsigned long prio)
31{
32 unsigned long mc_base = IO_TO_VIRT(TEGRA_MC_BASE);
33 unsigned long reg = client >> 8;
34 int field = client & 0xff;
35 unsigned long val;
36 unsigned long flags;
37
38 spin_lock_irqsave(&tegra_mc_lock, flags);
39 val = readl(mc_base + reg);
40 val &= ~(TEGRA_MC_PRIO_MASK << field);
41 val |= prio << field;
42 writel(val, mc_base + reg);
43 spin_unlock_irqrestore(&tegra_mc_lock, flags);
44
45}
46
47int tegra_mc_get_tiled_memory_bandwidth_multiplier(void)
48{
49 return 1;
50}
51
52#else
53 /* !!!FIXME!!! IMPLEMENT tegra_mc_set_priority() */
54
55#include "tegra3_emc.h"
56
57/*
58 * If using T30/DDR3, the 2nd 16 bytes part of DDR3 atom is 2nd line and is
59 * discarded in tiling mode.
60 */
61int tegra_mc_get_tiled_memory_bandwidth_multiplier(void)
62{
63 int type;
64
65 type = tegra_emc_get_dram_type();
66 WARN_ONCE(type == -1, "unknown type DRAM because DVFS is disabled\n");
67
68 if (type == DRAM_TYPE_DDR3)
69 return 2;
70 else
71 return 1;
72}
73#endif
diff --git a/arch/arm/mach-tegra/p852/Kconfig b/arch/arm/mach-tegra/p852/Kconfig
new file mode 100644
index 00000000000..ca44f9543be
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/Kconfig
@@ -0,0 +1,110 @@
1config MACH_P852
2 bool "P852 board"
3 depends on ARCH_TEGRA_2x_SOC
4 help
5 Support for NVIDIA P852 platform
6
7config P852_SKU1
8 bool "P852 SKU1 board"
9 depends on MACH_P852
10 default MACH_P852
11 help
12 Support for NVIDIA P852 SKU1 platform
13
14config P852_SKU1_B00
15 bool "P852 SKU1 rev B board"
16 depends on MACH_P852
17 default MACH_P852
18 help
19 Support for NVIDIA P852 SKU1 B00 platform
20
21config P852_SKU1_C0x
22 bool "P852 SKU1 rev C boards"
23 depends on MACH_P852
24 default MACH_P852
25 help
26 Support for NVIDIA P852 SKU1 C0x platform
27
28config P852_SKU3
29 bool "P852 SKU3 board"
30 depends on MACH_P852
31 default MACH_P852
32 help
33 Support for NVIDIA P852 SKU3 platform
34
35config P852_SKU5_B00
36 bool "P852 SKU5 rev B board"
37 depends on MACH_P852
38 default MACH_P852
39 help
40 Support for NVIDIA P852 SKU5 B00 platform
41
42config P852_SKU5_C01
43 bool "P852 SKU5 rev C board"
44 depends on MACH_P852
45 default MACH_P852
46 help
47 Support for NVIDIA P852 SKU5 C01 platform
48
49config P852_SKU8_B00
50 bool "P852 SKU8 rev B board"
51 depends on MACH_P852
52 default MACH_P852
53 help
54 Support for NVIDIA P852 SKU8 B00 platform
55
56config P852_SKU8_C01
57 bool "P852 SKU8 rev C board"
58 depends on MACH_P852
59 default MACH_P852
60 help
61 Support for NVIDIA P852 SKU8 C01 platform
62
63config P852_SKU9_B00
64 bool "P852 SKU9 rev B board"
65 depends on MACH_P852
66 default MACH_P852
67 help
68 Support for NVIDIA P852 SKU9 B00 platform
69
70config P852_SKU9_C01
71 bool "P852 SKU9 rev C board"
72 depends on MACH_P852
73 default MACH_P852
74 help
75 Support for NVIDIA P852 SKU9 C01 platform
76
77config P852_SKU13
78 bool "P852 SKU13 board"
79 depends on MACH_P852
80 default MACH_P852
81 help
82 Support for NVIDIA P852 SKU13 platform
83
84config P852_SKU13_B00
85 bool "P852 SKU13 rev B board"
86 depends on MACH_P852
87 default MACH_P852
88 help
89 Support for NVIDIA P852 SKU23 B00 platform
90
91config P852_SKU23
92 bool "P852 SKU23 board"
93 depends on MACH_P852
94 default MACH_P852
95 help
96 Support for NVIDIA P852 SKU23 platform
97
98config P852_SKU23_B00
99 bool "P852 SKU23 rev B board"
100 depends on MACH_P852
101 default MACH_P852
102 help
103 Support for NVIDIA P852 SKU23 B00 platform
104
105config P852_SKU23_C01
106 bool "P852 SKU23 rev C board"
107 depends on MACH_P852
108 default MACH_P852
109 help
110 Support for NVIDIA P852 SKU23 C01 platform
diff --git a/arch/arm/mach-tegra/p852/Makefile b/arch/arm/mach-tegra/p852/Makefile
new file mode 100644
index 00000000000..2f04ba08f71
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/Makefile
@@ -0,0 +1,39 @@
1#
2# arch/arm/mach-tegra/p852/Makefile
3#
4# Copyright (c) 2010-2011, NVIDIA Corporation.
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
17obj-${CONFIG_MACH_P852} += board-p852.o
18obj-${CONFIG_MACH_P852} += board-p852-sdhci.o
19obj-${CONFIG_MACH_P852} += board-p852-i2c.o
20obj-${CONFIG_MACH_P852} += board-p852-power.o
21obj-${CONFIG_MACH_P852} += board-p852-pinmux.o
22obj-${CONFIG_MACH_P852} += board-p852-gpio.o
23obj-${CONFIG_MACH_P852} += board-p852-panel.o
24
25obj-${CONFIG_P852_SKU1} += board-p852-sku1.o
26obj-${CONFIG_P852_SKU1_B00} += board-p852-sku1-b00.o
27obj-${CONFIG_P852_SKU1_C0x} += board-p852-sku1-c0x.o
28obj-${CONFIG_P852_SKU3} += board-p852-sku3.o
29obj-${CONFIG_P852_SKU5_B00} += board-p852-sku5-b00.o
30obj-${CONFIG_P852_SKU5_C01} += board-p852-sku5-c01.o
31obj-${CONFIG_P852_SKU8_B00} += board-p852-sku8-b00.o
32obj-${CONFIG_P852_SKU8_C01} += board-p852-sku8-c01.o
33obj-${CONFIG_P852_SKU9_B00} += board-p852-sku9-b00.o
34obj-${CONFIG_P852_SKU9_C01} += board-p852-sku9-c01.o
35obj-${CONFIG_P852_SKU13} += board-p852-sku13.o
36obj-${CONFIG_P852_SKU13_B00} += board-p852-sku13-b00.o
37obj-${CONFIG_P852_SKU23} += board-p852-sku23.o
38obj-${CONFIG_P852_SKU23_B00} += board-p852-sku23-b00.o
39obj-${CONFIG_P852_SKU23_C01} += board-p852-sku23-c01.o
diff --git a/arch/arm/mach-tegra/p852/board-p852-gpio.c b/arch/arm/mach-tegra/p852/board-p852-gpio.c
new file mode 100644
index 00000000000..71f568087c5
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-gpio.c
@@ -0,0 +1,158 @@
1/*
2 * arch/arm/mach-tegra/board-p852-gpio.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/gpio.h>
19#include <linux/irq.h>
20
21#include "board-p852.h"
22
23static struct gpio p852_sku23_gpios[] = {
24 {TEGRA_GPIO_PW1, GPIOF_OUT_INIT_LOW, "usbpwr0_ena"},
25 {TEGRA_GPIO_PB2, GPIOF_OUT_INIT_LOW, "usbpwr1_ena"},
26 {TEGRA_GPIO_PA0, GPIOF_OUT_INIT_LOW, "a0"},
27 {TEGRA_GPIO_PV2, GPIOF_OUT_INIT_HIGH, "v2"},
28 {TEGRA_GPIO_PT4, GPIOF_OUT_INIT_LOW, "t4"},
29 {TEGRA_GPIO_PD6, GPIOF_OUT_INIT_HIGH, "d6"},
30 {TEGRA_GPIO_PI3, GPIOF_OUT_INIT_LOW, "i3"},
31 {TEGRA_GPIO_PV3, GPIOF_OUT_INIT_HIGH, "v3"},
32 {TEGRA_GPIO_PW4, GPIOF_IN, "w4"},
33 {TEGRA_GPIO_PW5, GPIOF_IN, "w5"},
34 {TEGRA_GPIO_PT1, GPIOF_OUT_INIT_LOW, "t1"},
35 {TEGRA_GPIO_PW3, GPIOF_OUT_INIT_HIGH, "w3"},
36 {TEGRA_GPIO_PD5, GPIOF_IN, "d5"},
37 {TEGRA_GPIO_PBB1, GPIOF_OUT_INIT_LOW, "bb1"},
38};
39
40static struct gpio p852_sku23_b00_gpios[] = {
41 {TEGRA_GPIO_PW1, GPIOF_OUT_INIT_HIGH, "usbpwr0_ena"},
42 {TEGRA_GPIO_PB2, GPIOF_OUT_INIT_HIGH, "usbpwr1_ena"},
43 {TEGRA_GPIO_PA0, GPIOF_OUT_INIT_LOW, "a0"},
44 {TEGRA_GPIO_PV2, GPIOF_OUT_INIT_HIGH, "v2"},
45 {TEGRA_GPIO_PT4, GPIOF_OUT_INIT_LOW, "t4"},
46 {TEGRA_GPIO_PD6, GPIOF_OUT_INIT_HIGH, "d6"},
47 {TEGRA_GPIO_PI3, GPIOF_OUT_INIT_LOW, "i3"},
48 {TEGRA_GPIO_PV3, GPIOF_OUT_INIT_HIGH, "v3"},
49 {TEGRA_GPIO_PW4, GPIOF_IN, "w4"},
50 {TEGRA_GPIO_PW5, GPIOF_IN, "w5"},
51 {TEGRA_GPIO_PT1, GPIOF_OUT_INIT_LOW, "t1"},
52 {TEGRA_GPIO_PW3, GPIOF_OUT_INIT_HIGH, "w3"},
53 {TEGRA_GPIO_PD5, GPIOF_IN, "d5"},
54 {TEGRA_GPIO_PBB1, GPIOF_OUT_INIT_LOW, "bb1"},
55};
56
57static struct gpio p852_sku5_gpios[] = {
58 {TEGRA_GPIO_PW1, GPIOF_OUT_INIT_HIGH, "usbpwr0_ena"},
59 {TEGRA_GPIO_PB2, GPIOF_OUT_INIT_HIGH, "usbpwr1_ena"},
60 {TEGRA_GPIO_PA0, GPIOF_OUT_INIT_LOW, "a0"},
61 {TEGRA_GPIO_PV2, GPIOF_OUT_INIT_HIGH, "v2"},
62 {TEGRA_GPIO_PT4, GPIOF_OUT_INIT_LOW, "t4"},
63 {TEGRA_GPIO_PD6, GPIOF_OUT_INIT_HIGH, "d6"},
64 {TEGRA_GPIO_PI3, GPIOF_OUT_INIT_LOW, "i3"},
65 {TEGRA_GPIO_PV3, GPIOF_OUT_INIT_HIGH, "v3"},
66 {TEGRA_GPIO_PW4, GPIOF_IN, "w4"},
67 {TEGRA_GPIO_PW5, GPIOF_IN, "w5"},
68 {TEGRA_GPIO_PT1, GPIOF_OUT_INIT_LOW, "t1"},
69 {TEGRA_GPIO_PW3, GPIOF_OUT_INIT_HIGH, "w3"},
70 {TEGRA_GPIO_PD5, GPIOF_IN, "d5"},
71 {TEGRA_GPIO_PBB1, GPIOF_OUT_INIT_LOW, "bb1"},
72 {TEGRA_GPIO_PS3, GPIOF_IN, "s3"},
73};
74
75static struct gpio p852_sku8_gpios[] = {
76 {TEGRA_GPIO_PW1, GPIOF_OUT_INIT_HIGH, "w1"},
77 {TEGRA_GPIO_PB2, GPIOF_OUT_INIT_HIGH, "b2"},
78};
79
80static struct gpio p852_sku13_b00_gpios[] = {
81 {TEGRA_GPIO_PW1, GPIOF_OUT_INIT_HIGH, "w1"},
82 {TEGRA_GPIO_PB2, GPIOF_OUT_INIT_HIGH, "b2"},
83 {TEGRA_GPIO_PW2, GPIOF_IN, "w2"},
84 {TEGRA_GPIO_PW3, GPIOF_IN, "w3"},
85 {TEGRA_GPIO_PD5, GPIOF_OUT_INIT_LOW, "d5"},
86 {TEGRA_GPIO_PBB1, GPIOF_OUT_INIT_LOW, "bb1"},
87 {TEGRA_GPIO_PN7, GPIOF_OUT_INIT_LOW, "n7"},
88 {TEGRA_GPIO_PA6, GPIOF_OUT_INIT_HIGH, "a6"},
89 {TEGRA_GPIO_PA7, GPIOF_OUT_INIT_HIGH, "a7"},
90};
91
92static struct gpio p852_gpios[] = {
93 {TEGRA_GPIO_PW1, GPIOF_OUT_INIT_LOW, "w1"},
94 {TEGRA_GPIO_PB2, GPIOF_OUT_INIT_LOW, "b2"},
95 {TEGRA_GPIO_PW2, GPIOF_IN, "w2"},
96 {TEGRA_GPIO_PW3, GPIOF_IN, "w3"},
97 {TEGRA_GPIO_PD5, GPIOF_OUT_INIT_LOW, "d5"},
98 {TEGRA_GPIO_PBB1, GPIOF_OUT_INIT_LOW, "bb1"},
99 {TEGRA_GPIO_PN7, GPIOF_OUT_INIT_LOW, "n7"},
100 {TEGRA_GPIO_PA6, GPIOF_OUT_INIT_HIGH, "a6"},
101 {TEGRA_GPIO_PA7, GPIOF_OUT_INIT_HIGH, "a7"},
102};
103
104void __init p852_gpio_init(void)
105{
106 int pin_count = 0;
107 int i;
108 struct gpio *gpios_info = NULL;
109
110 switch (system_rev) {
111 case P852_SKU23:
112 {
113 gpios_info = p852_sku23_gpios;
114 pin_count = ARRAY_SIZE(p852_sku23_gpios);
115 }
116 break;
117 case P852_SKU23_B00:
118 case P852_SKU23_C01:
119 {
120 gpios_info = p852_sku23_b00_gpios;
121 pin_count = ARRAY_SIZE(p852_sku23_b00_gpios);
122 }
123 break;
124 case P852_SKU5_B00:
125 case P852_SKU5_C01:
126 {
127 gpios_info = p852_sku5_gpios;
128 pin_count = ARRAY_SIZE(p852_sku5_gpios);
129 }
130 break;
131 case P852_SKU8_B00:
132 case P852_SKU8_C01:
133 case P852_SKU9_B00:
134 case P852_SKU9_C01:
135 {
136 gpios_info = p852_sku8_gpios;
137 pin_count = ARRAY_SIZE(p852_sku8_gpios);
138 }
139 break;
140 case P852_SKU13_B00:
141 {
142 gpios_info = p852_sku13_b00_gpios;
143 pin_count = ARRAY_SIZE(p852_sku13_b00_gpios);
144 }
145 break;
146 default:
147 {
148 gpios_info = p852_gpios;
149 pin_count = ARRAY_SIZE(p852_gpios);
150 }
151 }
152
153 gpio_request_array(gpios_info, pin_count);
154 for (i = 0; i < pin_count; i++) {
155 tegra_gpio_enable(gpios_info[i].gpio);
156 gpio_export(gpios_info[i].gpio, true);
157 }
158}
diff --git a/arch/arm/mach-tegra/p852/board-p852-i2c.c b/arch/arm/mach-tegra/p852/board-p852-i2c.c
new file mode 100644
index 00000000000..041ec252b6c
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-i2c.c
@@ -0,0 +1,180 @@
1/*
2 * arch/arm/mach-tegra/board-p852-i2c.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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/resource.h>
18#include <linux/platform_device.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21
22#include <asm/mach-types.h>
23#include <mach/irqs.h>
24#include <mach/iomap.h>
25#include <linux/i2c.h>
26#include <mach/pinmux.h>
27#include <asm/mach-types.h>
28
29#include "board-p852.h"
30
31static struct resource i2c_resource1[] = {
32 [0] = {
33 .start = INT_I2C,
34 .end = INT_I2C,
35 .flags = IORESOURCE_IRQ,
36 },
37 [1] = {
38 .start = TEGRA_I2C_BASE,
39 .end = TEGRA_I2C_BASE + TEGRA_I2C_SIZE - 1,
40 .flags = IORESOURCE_MEM,
41 },
42};
43
44static struct resource i2c_resource2[] = {
45 [0] = {
46 .start = INT_I2C2,
47 .end = INT_I2C2,
48 .flags = IORESOURCE_IRQ,
49 },
50 [1] = {
51 .start = TEGRA_I2C2_BASE,
52 .end = TEGRA_I2C2_BASE + TEGRA_I2C2_SIZE - 1,
53 .flags = IORESOURCE_MEM,
54 },
55};
56
57static struct resource i2c_resource3[] = {
58 [0] = {
59 .start = INT_I2C3,
60 .end = INT_I2C3,
61 .flags = IORESOURCE_IRQ,
62 },
63 [1] = {
64 .start = TEGRA_I2C3_BASE,
65 .end = TEGRA_I2C3_BASE + TEGRA_I2C3_SIZE - 1,
66 .flags = IORESOURCE_MEM,
67 },
68};
69
70static struct resource i2c_resource4[] = {
71 [0] = {
72 .start = INT_DVC,
73 .end = INT_DVC,
74 .flags = IORESOURCE_IRQ,
75 },
76 [1] = {
77 .start = TEGRA_DVC_BASE,
78 .end = TEGRA_DVC_BASE + TEGRA_DVC_SIZE - 1,
79 .flags = IORESOURCE_MEM,
80 },
81};
82
83static const struct tegra_pingroup_config i2c2_ddc = {
84 .pingroup = TEGRA_PINGROUP_DDC,
85 .func = TEGRA_MUX_I2C2,
86};
87
88static const struct tegra_pingroup_config i2c_i2cp = {
89 .pingroup = TEGRA_PINGROUP_I2CP,
90 .func = TEGRA_MUX_I2C,
91};
92
93static struct tegra_i2c_platform_data p852_i2c1_platform_data = {
94 .adapter_nr = 0,
95 .bus_count = 1,
96 .bus_clk_rate = {400000},
97};
98
99static struct tegra_i2c_platform_data p852_i2c2_platform_data = {
100 .adapter_nr = 1,
101 .bus_count = 1,
102 .bus_clk_rate = {100000},
103 .bus_mux = {&i2c2_ddc},
104 .bus_mux_len = {1},
105};
106
107static struct tegra_i2c_platform_data p852_i2c3_platform_data = {
108 .adapter_nr = 2,
109 .bus_count = 1,
110 .bus_clk_rate = {400000},
111};
112
113static struct tegra_i2c_platform_data p852_dvc_platform_data = {
114 .adapter_nr = 3,
115 .bus_count = 1,
116 .bus_clk_rate = {100000},
117 .bus_mux = {&i2c_i2cp},
118 .bus_mux_len = {1},
119 .is_dvc = true,
120};
121
122struct platform_device tegra_i2c_device[] = {
123 {
124 .name = "tegra-i2c",
125 .id = 0,
126 .resource = i2c_resource1,
127 .num_resources = ARRAY_SIZE(i2c_resource1),
128 .dev = {
129 .platform_data = &p852_i2c1_platform_data,
130 },
131 },
132 {
133 .name = "tegra-i2c",
134 .id = 1,
135 .resource = i2c_resource2,
136 .num_resources = ARRAY_SIZE(i2c_resource2),
137 .dev = {
138 .platform_data = &p852_i2c2_platform_data,
139 },
140 },
141 {
142 .name = "tegra-i2c",
143 .id = 2,
144 .resource = i2c_resource3,
145 .num_resources = ARRAY_SIZE(i2c_resource3),
146 .dev = {
147 .platform_data = &p852_i2c3_platform_data,
148 },
149 },
150 {
151 .name = "tegra-i2c",
152 .id = 3,
153 .resource = i2c_resource4,
154 .num_resources = ARRAY_SIZE(i2c_resource4),
155 .dev = {
156 .platform_data = &p852_dvc_platform_data,
157 },
158 }
159};
160
161void __init p852_i2c_set_default_clock(int adapter, unsigned long clock)
162{
163 if (adapter >= 0 && adapter < ARRAY_SIZE(tegra_i2c_device))
164 ((struct tegra_i2c_platform_data *)tegra_i2c_device[adapter].
165 dev.platform_data)->bus_clk_rate[0] = clock;
166}
167
168void __init p852_i2c_init(void)
169{
170 int i;
171 unsigned int i2c_config = 0;
172 if (p852_sku_peripherals & P852_SKU_I2C_ENABLE) {
173 for (i = 0; i < P852_MAX_I2C; i++) {
174 i2c_config =
175 (p852_i2c_peripherals >> (P852_I2C_SHIFT * i));
176 if (i2c_config & P852_I2C_ENABLE)
177 platform_device_register(&tegra_i2c_device[i]);
178 }
179 }
180}
diff --git a/arch/arm/mach-tegra/p852/board-p852-panel.c b/arch/arm/mach-tegra/p852/board-p852-panel.c
new file mode 100644
index 00000000000..c47032dd4f0
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-panel.c
@@ -0,0 +1,196 @@
1/*
2 * arch/arm/mach-tegra/board-p852-panel.c
3 *
4 * Copyright (c) 2010-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/resource.h>
25#include <linux/nvhost.h>
26#include <linux/platform_device.h>
27#include <asm/mach-types.h>
28#include <mach/nvmap.h>
29#include <mach/irqs.h>
30#include <mach/iomap.h>
31#include <mach/dc.h>
32#include <mach/fb.h>
33
34#include "board-p852.h"
35
36#define CARVEOUT_IRAM {\
37 .name = "iram",\
38 .usage_mask = NVMAP_HEAP_CARVEOUT_IRAM,\
39 .base = TEGRA_IRAM_BASE,\
40 .size = TEGRA_IRAM_SIZE,\
41 .buddy_size = 0, /* no buddy allocation for IRAM */\
42}
43
44static int p852_panel_enable(void)
45{
46 pr_info("%s\n", __func__);
47 return 0;
48}
49
50static int p852_panel_disable(void)
51{
52 pr_info("%s\n", __func__);
53 return 0;
54}
55
56static struct resource p852_disp_resources[] = {
57 {
58 .name = "irq",
59 .start = INT_DISPLAY_GENERAL,
60 .end = INT_DISPLAY_GENERAL,
61 .flags = IORESOURCE_IRQ,
62 },
63 {
64 .name = "regs",
65 .start = TEGRA_DISPLAY_BASE,
66 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
67 .flags = IORESOURCE_MEM,
68 },
69 {
70 .name = "fbmem",
71 .start = 0,
72 .end = 0,
73 .flags = IORESOURCE_MEM,
74 },
75};
76
77static struct tegra_dc_mode p852_panel_modes[] = {
78/* Timings for the LG LB070WV4 panel */
79 {
80 .pclk = 33230769,
81
82 .h_ref_to_sync = 1,
83 .v_ref_to_sync = 1,
84
85 .h_sync_width = 128,
86 .v_sync_width = 2,
87
88 .h_back_porch = 88,
89 .v_back_porch = 30,
90
91 .h_front_porch = 40,
92 .v_front_porch = 13,
93
94 .h_active = 800,
95 .v_active = 480,
96 },
97};
98
99static struct tegra_fb_data p852_fb_data = {
100 .win = 0,
101 .xres = 800,
102 .yres = 480,
103 .bits_per_pixel = 16,
104};
105
106static struct tegra_dc_out p852_disp_out = {
107 .type = TEGRA_DC_OUT_RGB,
108
109 .align = TEGRA_DC_ALIGN_MSB,
110 .order = TEGRA_DC_ORDER_RED_BLUE,
111
112 .modes = p852_panel_modes,
113 .n_modes = ARRAY_SIZE(p852_panel_modes),
114
115 .enable = p852_panel_enable,
116 .disable = p852_panel_disable,
117};
118
119static struct tegra_dc_platform_data p852_disp_pdata = {
120 .flags = TEGRA_DC_FLAG_ENABLED,
121 .default_out = &p852_disp_out,
122 .fb = &p852_fb_data,
123};
124
125static struct nvhost_device p852_disp_device = {
126 .name = "tegradc",
127 .id = 0,
128 .resource = p852_disp_resources,
129 .num_resources = ARRAY_SIZE(p852_disp_resources),
130 .dev = {
131 .platform_data = &p852_disp_pdata,
132 },
133};
134
135static struct nvmap_platform_carveout p852_carveouts[] = {
136 [0] = CARVEOUT_IRAM,
137 [1] = {
138 .name = "generic-0",
139 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
140 .base = 0,
141 .size = 0,
142 .buddy_size = SZ_32K,
143 },
144};
145
146static struct nvmap_platform_data p852_nvmap_data = {
147 .carveouts = p852_carveouts,
148 .nr_carveouts = ARRAY_SIZE(p852_carveouts),
149};
150
151static struct platform_device p852_nvmap_device = {
152 .name = "tegra-nvmap",
153 .id = -1,
154 .dev = {
155 .platform_data = &p852_nvmap_data,
156 },
157};
158
159static struct platform_device *p852_gfx_devices[] __initdata = {
160 &tegra_pwfm2_device,
161};
162
163int __init p852_panel_init(void)
164{
165 int err;
166 struct resource *res;
167
168 pr_info("%s\n", __func__);
169
170 p852_carveouts[1].base = tegra_carveout_start;
171 p852_carveouts[1].size = tegra_carveout_size;
172
173 err = platform_device_register(&p852_nvmap_device);
174 if (err)
175 return err;
176
177#ifdef CONFIG_TEGRA_GRHOST
178 err = nvhost_device_register(&tegra_grhost_device);
179 if (err)
180 return err;
181#endif
182
183 err = platform_add_devices(p852_gfx_devices,
184 ARRAY_SIZE(p852_gfx_devices));
185
186 res = nvhost_get_resource_byname(&p852_disp_device,
187 IORESOURCE_MEM, "fbmem");
188
189 res->start = tegra_fb_start;
190 res->end = tegra_fb_start + tegra_fb_size - 1;
191
192 if (!err)
193 err = nvhost_device_register(&p852_disp_device);
194
195 return err;
196}
diff --git a/arch/arm/mach-tegra/p852/board-p852-pinmux.c b/arch/arm/mach-tegra/p852/board-p852-pinmux.c
new file mode 100644
index 00000000000..0ded989f7a1
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-pinmux.c
@@ -0,0 +1,439 @@
1/*
2 * arch/arm/mach-tegra/board-p852-pinmux.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 <mach/pinmux.h>
20#include <asm/mach-types.h>
21
22#include "board-p852.h"
23
24#define DEFAULT_DRIVE(_name) \
25 { \
26 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
27 .hsm = TEGRA_HSM_DISABLE, \
28 .schmitt = TEGRA_SCHMITT_ENABLE, \
29 .drive = TEGRA_DRIVE_DIV_1, \
30 .pull_down = TEGRA_PULL_31, \
31 .pull_up = TEGRA_PULL_31, \
32 .slew_rising = TEGRA_SLEW_SLOWEST, \
33 .slew_falling = TEGRA_SLEW_SLOWEST, \
34 }
35
36#define P852_PAD_DRIVE(_name) \
37 { \
38 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
39 .hsm = TEGRA_HSM_DISABLE, \
40 .schmitt = TEGRA_SCHMITT_DISABLE, \
41 .drive = TEGRA_DRIVE_DIV_1, \
42 .pull_down = TEGRA_PULL_18, \
43 .pull_up = TEGRA_PULL_22, \
44 .slew_rising = TEGRA_SLEW_SLOWEST, \
45 .slew_falling = TEGRA_SLEW_SLOWEST, \
46 }
47
48#define P852_PAD_DRIVE_HSM(_name) \
49 { \
50 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
51 .hsm = TEGRA_HSM_ENABLE, \
52 .schmitt = TEGRA_SCHMITT_ENABLE, \
53 .drive = TEGRA_DRIVE_DIV_1, \
54 .pull_down = TEGRA_PULL_31, \
55 .pull_up = TEGRA_PULL_31, \
56 .slew_rising = TEGRA_SLEW_SLOWEST, \
57 .slew_falling = TEGRA_SLEW_SLOWEST, \
58 }
59
60#define DAP_PAD_DRIVE(_name) \
61 { \
62 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
63 .hsm = TEGRA_HSM_DISABLE, \
64 .schmitt = TEGRA_SCHMITT_ENABLE, \
65 .drive = TEGRA_DRIVE_DIV_1, \
66 .pull_down = TEGRA_PULL_3, \
67 .pull_up = TEGRA_PULL_3, \
68 .slew_rising = TEGRA_SLEW_SLOWEST, \
69 .slew_falling = TEGRA_SLEW_SLOWEST, \
70 }
71
72static __initdata struct tegra_drive_pingroup_config p852_drive_pinmux[] = {
73 DEFAULT_DRIVE(DBG),
74 DEFAULT_DRIVE(DDC),
75 DEFAULT_DRIVE(VI1),
76 DEFAULT_DRIVE(VI2),
77 DEFAULT_DRIVE(SDIO1),
78 P852_PAD_DRIVE(SPI),
79 DAP_PAD_DRIVE(DAP1),
80 DAP_PAD_DRIVE(DAP2),
81 DEFAULT_DRIVE(CDEV1),
82 DEFAULT_DRIVE(CDEV2),
83};
84
85static __initdata struct tegra_drive_pingroup_config
86 p852_drive_pinmux_sku8_sku9[] = {
87 DAP_PAD_DRIVE(DAP3),
88};
89
90
91static __initdata struct tegra_pingroup_config p852_common_pinmux[] = {
92 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
94 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
95 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
96 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
97 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
99 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_DTB, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_DTE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
105 /* IRDA is same as UART2 option for the pingroup */
106 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
108 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
113 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_SPDIF, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
116 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
118 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
121 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
122 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
125 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_UAC, TEGRA_MUX_OWR, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
129 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
130 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
133 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
134 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
136 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
138 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
139 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
141 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
142 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
143 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
144};
145
146static __initdata struct tegra_pingroup_config p852_nand_pinmux[] = {
147 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
148 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
149 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
150 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
151 {TEGRA_PINGROUP_GPU, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
152 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
153 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
154 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
155 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
156 {TEGRA_PINGROUP_ATA, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
157 {TEGRA_PINGROUP_GMB, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
158 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
159 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
160 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
161 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
162 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
163 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
164 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
165};
166
167static __initdata struct tegra_pingroup_config p852_sdio3_pinmux[] = {
168 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
169 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
170 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
171};
172
173static __initdata struct tegra_pingroup_config p852_uarta_pinmux[] = {
174 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
175 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
176 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
177};
178
179static __initdata struct tegra_pingroup_config p852_ulpi_pinmux[] = {
180 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
181 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
182 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
183};
184
185static __initdata struct tegra_pingroup_config p852_uarta_1_pinmux[] = {
186 {TEGRA_PINGROUP_UAA, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
187 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
188 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
189};
190
191static __initdata struct tegra_pingroup_config p852_uartd_pinmux[] = {
192 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
193};
194
195static __initdata struct tegra_pingroup_config p852_spi4_pinmux[] = {
196 {TEGRA_PINGROUP_GMC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
197 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
198 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
199 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
200 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
201};
202
203static __initdata struct tegra_pingroup_config p852_spi4_1_pinmux[] = {
204 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
205 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
206 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
207 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
208};
209
210static __initdata struct tegra_pingroup_config p852_nor_pinmux[] = {
211 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
212 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
213 {TEGRA_PINGROUP_UCA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
214 {TEGRA_PINGROUP_UCB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
215 {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
216 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
217 {TEGRA_PINGROUP_SPID, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
218 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
219 {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
220 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
221 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
222 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
223 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
224 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
225 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
226 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
227 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
228 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
229};
230
231static __initdata struct tegra_pingroup_config p852_display_a_pinmux[] = {
232 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
233 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
234 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
235 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
236 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
237 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
238 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
239 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
240 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
241 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
242 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
243 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
244 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
245 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
246 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
247 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
248 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
249 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
250 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
251 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
252 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
253 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
254 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
255 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
256 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
257 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
258 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
259 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
260 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
261 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
262 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
263 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
264 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
265 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
266 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
267 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
268};
269
270static __initdata struct tegra_pingroup_config p852_display_b_pinmux[] = {
271 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
272 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
273 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
274 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
275 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
276 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
277 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
278 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
279 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
280 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
281 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
282 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
283 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
284 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
285 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
286 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
287 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
288 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
289 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
290 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
291 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
292 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
293 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
294 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
295 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
296 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
297 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
298 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
299 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
300 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
301 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
302 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
303 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
304 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
305 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
306 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
307 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
308};
309
310static __initdata struct tegra_drive_pingroup_config
311 p852_drive_pinmux_sku23[] = {
312 P852_PAD_DRIVE_HSM(SDMMC3),
313};
314
315static __initdata struct tegra_drive_pingroup_config
316 p852_drive_pinmux_sku13[] = {
317 P852_PAD_DRIVE_HSM(SDMMC3),
318};
319
320static __initdata struct tegra_pingroup_config p852_pupd_sku23[] = {
321 {TEGRA_PINGROUP_GPV, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
322 {TEGRA_PINGROUP_GMC, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
323 {TEGRA_PINGROUP_DTB, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
324};
325
326
327static __initdata struct tegra_pingroup_config p852_pupd_sku13[] = {
328 {TEGRA_PINGROUP_GPV, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
329};
330
331static __initdata struct tegra_pingroup_config p852_pupd_sku5[] = {
332 {TEGRA_PINGROUP_GMC, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
333 {TEGRA_PINGROUP_DTB, TEGRA_MUX_NONE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
334};
335
336static void tegra_pinmux_config_pupd_table(
337 const struct tegra_pingroup_config *config,
338 int len)
339{
340 int i;
341 for (i = 0; i < len; i++) {
342 /* config.func, the pin_mux setting is not used here */
343 tegra_pinmux_config_pullupdown_table(&config[i], 1,
344 config[i].pupd);
345 }
346}
347
348void __init p852_pinmux_init(void)
349{
350 unsigned int sdio3_config = (p852_sdhci_peripherals >>
351 P852_SDHCI3_SHIFT) & P852_SDHCI_MASK;
352 unsigned int uartd_config = (p852_uart_peripherals >> P852_UARTD_SHIFT)
353 & P852_UART_MASK;
354 unsigned int uarta_config = (p852_uart_peripherals >> P852_UARTA_SHIFT)
355 & P852_UART_MASK;
356 unsigned int spi4_config = (p852_spi_peripherals >> P852_SPI4_SHIFT)
357 & P852_SPI_MASK;
358 unsigned int displayb_config = (p852_display_peripherals >>
359 P852_DISPB_SHIFT) & P852_DISP_MASK;
360
361 tegra_pinmux_config_table(p852_common_pinmux,
362 ARRAY_SIZE(p852_common_pinmux));
363
364 if ((uarta_config & P852_UART_ENABLE)
365 && (uarta_config & P852_UART_ALT_PIN_CFG)) {
366 tegra_pinmux_config_table(p852_uarta_1_pinmux,
367 ARRAY_SIZE(p852_uarta_1_pinmux));
368 } else {
369 tegra_pinmux_config_table(p852_ulpi_pinmux,
370 ARRAY_SIZE(p852_ulpi_pinmux));
371 }
372
373 if (sdio3_config & P852_SDHCI_ENABLE) {
374 tegra_pinmux_config_table(p852_sdio3_pinmux,
375 ARRAY_SIZE(p852_sdio3_pinmux));
376 } else {
377 tegra_pinmux_config_table(p852_uarta_pinmux,
378 ARRAY_SIZE(p852_uarta_pinmux));
379 }
380
381 if ((uartd_config & P852_UART_ENABLE) &&
382 (spi4_config & P852_SPI_ENABLE)) {
383 tegra_pinmux_config_table(p852_uartd_pinmux,
384 ARRAY_SIZE(p852_uartd_pinmux));
385 tegra_pinmux_config_table(p852_spi4_1_pinmux,
386 ARRAY_SIZE(p852_spi4_1_pinmux));
387 } else {
388 tegra_pinmux_config_table(p852_spi4_pinmux,
389 ARRAY_SIZE(p852_spi4_pinmux));
390 }
391
392 if (p852_sku_peripherals & P852_SKU_NOR_ENABLE) {
393 tegra_pinmux_config_table(p852_nor_pinmux,
394 ARRAY_SIZE(p852_nor_pinmux));
395 } else {
396 tegra_pinmux_config_table(p852_nand_pinmux,
397 ARRAY_SIZE(p852_nand_pinmux));
398 }
399
400 if (p852_sku_peripherals & P852_SKU_DISPLAY_ENABLE) {
401 if (displayb_config) {
402 tegra_pinmux_config_table(p852_display_b_pinmux,
403 ARRAY_SIZE(p852_display_b_pinmux));
404 } else {
405 tegra_pinmux_config_table(p852_display_a_pinmux,
406 ARRAY_SIZE(p852_display_a_pinmux));
407 }
408 }
409
410 tegra_drive_pinmux_config_table(p852_drive_pinmux,
411 ARRAY_SIZE(p852_drive_pinmux));
412
413 if (system_rev == P852_SKU23 ||
414 system_rev == P852_SKU23_B00 ||
415 system_rev == P852_SKU23_C01) {
416 tegra_drive_pinmux_config_table(p852_drive_pinmux_sku23,
417 ARRAY_SIZE(p852_drive_pinmux_sku23));
418
419 tegra_pinmux_config_pupd_table(p852_pupd_sku23,
420 ARRAY_SIZE(p852_pupd_sku23));
421 } else if (system_rev == P852_SKU13 ||
422 system_rev == P852_SKU13_B00) {
423 tegra_drive_pinmux_config_table(p852_drive_pinmux_sku13,
424 ARRAY_SIZE(p852_drive_pinmux_sku13));
425
426 tegra_pinmux_config_pupd_table(p852_pupd_sku13,
427 ARRAY_SIZE(p852_pupd_sku13));
428 } else if (system_rev == P852_SKU5_B00 || system_rev == P852_SKU5_C01) {
429 tegra_pinmux_config_pupd_table(p852_pupd_sku5,
430 ARRAY_SIZE(p852_pupd_sku5));
431 } else if (system_rev == P852_SKU8_B00 || system_rev == P852_SKU9_B00 ||
432 system_rev == P852_SKU8_C01 || system_rev == P852_SKU9_C01) {
433 tegra_drive_pinmux_config_table(p852_drive_pinmux_sku8_sku9,
434 ARRAY_SIZE(p852_drive_pinmux_sku8_sku9));
435 }
436
437}
438
439
diff --git a/arch/arm/mach-tegra/p852/board-p852-power.c b/arch/arm/mach-tegra/p852/board-p852-power.c
new file mode 100644
index 00000000000..71f6e85d25c
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-power.c
@@ -0,0 +1,209 @@
1/*
2 * arch/arm/mach-tegra/p852/board-p852-power.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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/i2c.h>
18#include <linux/pda_power.h>
19#include <linux/platform_device.h>
20#include <linux/resource.h>
21#include <linux/regulator/machine.h>
22#include <linux/mfd/tps6586x.h>
23#include <linux/gpio.h>
24#include <linux/io.h>
25#include <mach/iomap.h>
26#include <mach/irqs.h>
27#include "board-p852.h"
28
29#define PMC_CTRL 0x0
30#define PMC_CTRL_INTR_LOW (1 << 17)
31
32static struct regulator_consumer_supply tps658621_sm0_supply[] = {
33 REGULATOR_SUPPLY("vdd_core", NULL),
34};
35static struct regulator_consumer_supply tps658621_sm1_supply[] = {
36 REGULATOR_SUPPLY("vdd_cpu", NULL),
37};
38static struct regulator_consumer_supply tps658621_sm2_supply[] = {
39 REGULATOR_SUPPLY("vdd_sm2", NULL),
40};
41static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
42 REGULATOR_SUPPLY("vddio_pex_clk", NULL),
43};
44static struct regulator_consumer_supply tps658621_ldo1_supply[] = {
45 REGULATOR_SUPPLY("avdd_pll", NULL),
46 REGULATOR_SUPPLY("avdd_plla_pc", NULL),
47 REGULATOR_SUPPLY("avdd_pllm", NULL),
48 REGULATOR_SUPPLY("avdd_pllu", NULL),
49 REGULATOR_SUPPLY("avdd_pllx6", NULL),
50};
51static struct regulator_consumer_supply tps658621_ldo2_supply[] = {
52 REGULATOR_SUPPLY("vdd_rtc", NULL),
53};
54static struct regulator_consumer_supply tps658621_ldo3_supply[] = {
55 REGULATOR_SUPPLY("avdd_usb", NULL),
56 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
57 REGULATOR_SUPPLY("avdd_lvds", NULL),
58};
59static struct regulator_consumer_supply tps658621_ldo4_supply[] = {
60 REGULATOR_SUPPLY("avdd_osc", NULL),
61 REGULATOR_SUPPLY("vddio_sys", "panjit_touch"),
62};
63static struct regulator_consumer_supply tps658621_ldo5_supply[] = {
64 REGULATOR_SUPPLY("vddio_lcd", NULL),
65};
66static struct regulator_consumer_supply tps658621_ldo6_supply[] = {
67 REGULATOR_SUPPLY("avdd_vdac", NULL),
68};
69static struct regulator_consumer_supply tps658621_ldo7_supply[] = {
70 REGULATOR_SUPPLY("vddio_vi", NULL),
71 REGULATOR_SUPPLY("vdd_fuse", NULL),
72 REGULATOR_SUPPLY("vspi", "spi_tegra.0"),
73};
74static struct regulator_consumer_supply tps658621_ldo8_supply[] = {
75 REGULATOR_SUPPLY("vddio_bb", NULL),
76 REGULATOR_SUPPLY("vmmc", "sdhci-tegra.0"),
77 REGULATOR_SUPPLY("vmmc", "sdhci-tegra.2"),
78};
79static struct regulator_consumer_supply tps658621_ldo9_supply[] = {
80 REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
81 REGULATOR_SUPPLY("vmmc", "sdhci-tegra.3"),
82};
83
84#define REGULATOR_INIT(_id, _minmv, _maxmv) \
85 { \
86 .constraints = { \
87 .min_uV = (_minmv)*1000, \
88 .max_uV = (_maxmv)*1000, \
89 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
90 REGULATOR_MODE_STANDBY), \
91 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
92 REGULATOR_CHANGE_STATUS | \
93 REGULATOR_CHANGE_VOLTAGE), \
94 }, \
95 .num_consumer_supplies = ARRAY_SIZE(tps658621_##_id##_supply),\
96 .consumer_supplies = tps658621_##_id##_supply, \
97 }
98
99static struct regulator_init_data sm0_data = REGULATOR_INIT(sm0, 725, 1500);
100static struct regulator_init_data sm1_data = REGULATOR_INIT(sm1, 725, 1500);
101static struct regulator_init_data sm2_data = REGULATOR_INIT(sm2, 3000, 4550);
102static struct regulator_init_data ldo0_data = REGULATOR_INIT(ldo0, 1250, 3300);
103static struct regulator_init_data ldo1_data = REGULATOR_INIT(ldo1, 725, 1500);
104static struct regulator_init_data ldo2_data = REGULATOR_INIT(ldo2, 725, 1225);
105static struct regulator_init_data ldo3_data = REGULATOR_INIT(ldo3, 1250, 3300);
106static struct regulator_init_data ldo4_data = REGULATOR_INIT(ldo4, 1700, 2475);
107static struct regulator_init_data ldo5_data = REGULATOR_INIT(ldo5, 1250, 3300);
108static struct regulator_init_data ldo6_data = REGULATOR_INIT(ldo6, 1250, 3300);
109static struct regulator_init_data ldo7_data = REGULATOR_INIT(ldo7, 1250, 3300);
110static struct regulator_init_data ldo8_data = REGULATOR_INIT(ldo8, 1250, 3300);
111static struct regulator_init_data ldo9_data = REGULATOR_INIT(ldo9, 1250, 3300);
112
113
114static struct tps6586x_rtc_platform_data rtc_data = {
115 .irq = TEGRA_NR_IRQS + TPS6586X_INT_RTC_ALM1,
116 .cl_sel = 0,
117};
118
119
120#define TPS_REG(_id, _data) \
121 { \
122 .id = TPS6586X_ID_##_id, \
123 .name = "tps6586x-regulator", \
124 .platform_data = _data, \
125 }
126
127static struct tps6586x_subdev_info tps_devs[] = {
128 TPS_REG(SM_0, &sm0_data),
129 TPS_REG(SM_1, &sm1_data),
130 TPS_REG(SM_2, &sm2_data),
131 TPS_REG(LDO_0, &ldo0_data),
132 TPS_REG(LDO_1, &ldo1_data),
133 TPS_REG(LDO_2, &ldo2_data),
134 TPS_REG(LDO_3, &ldo3_data),
135 TPS_REG(LDO_4, &ldo4_data),
136 TPS_REG(LDO_5, &ldo5_data),
137 TPS_REG(LDO_6, &ldo6_data),
138 TPS_REG(LDO_7, &ldo7_data),
139 TPS_REG(LDO_8, &ldo8_data),
140 TPS_REG(LDO_9, &ldo9_data),
141 {
142 .id = 0,
143 .name = "tps6586x-rtc",
144 .platform_data = &rtc_data,
145 },
146};
147
148static struct tps6586x_platform_data tps_platform = {
149 .irq_base = TEGRA_NR_IRQS,
150 .num_subdevs = ARRAY_SIZE(tps_devs),
151 .subdevs = tps_devs,
152 .gpio_base = TEGRA_NR_GPIOS,
153 .use_power_off = true,
154};
155
156static struct i2c_board_info __initdata p852_regulators[] = {
157 {
158 I2C_BOARD_INFO("tps6586x", 0x34),
159 .irq = INT_EXTERNAL_PMU,
160 .platform_data = &tps_platform,
161 },
162};
163
164static struct tegra_suspend_platform_data p852_suspend_data = {
165 .cpu_timer = 2000,
166 .cpu_off_timer = 0,
167 .suspend_mode = TEGRA_SUSPEND_LP1,
168 .core_timer = 0x7e7e,
169 .core_off_timer = 0,
170 .corereq_high = false,
171 .sysclkreq_high = true,
172};
173
174static void __init tps6586x_rtc_preinit(void)
175{
176 int i;
177 struct tps6586x_rtc_platform_data *rtc_pdata;
178
179 if (system_rev == P852_SKU23_B00 ||
180 system_rev == P852_SKU23_C01 ||
181 system_rev == P852_SKU13_B00 ||
182 system_rev == P852_SKU5_B00 ||
183 system_rev == P852_SKU5_C01) {
184 for (i = 0; i < tps_platform.num_subdevs; ++i)
185 if (!strcmp(tps_platform.subdevs[i].name,
186 "tps6586x-rtc"))
187 rtc_pdata =
188 (struct tps6586x_rtc_platform_data *)
189 (tps_platform.subdevs[i].platform_data);
190 rtc_pdata->cl_sel = TPS6586X_RTC_CL_SEL_1_5PF;
191 }
192}
193
194int __init p852_regulator_init(void)
195{
196 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
197 u32 pmc_ctrl;
198
199 /* configure the power management controller to trigger PMU
200 * interrupts when low */
201 pmc_ctrl = readl(pmc + PMC_CTRL);
202 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
203 i2c_register_board_info(3, p852_regulators, 1);
204 tegra_init_suspend(&p852_suspend_data);
205
206 tps6586x_rtc_preinit();
207
208 return 0;
209}
diff --git a/arch/arm/mach-tegra/p852/board-p852-sdhci.c b/arch/arm/mach-tegra/p852/board-p852-sdhci.c
new file mode 100644
index 00000000000..dc5b81fa372
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sdhci.c
@@ -0,0 +1,199 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sdhci.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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/resource.h>
18#include <linux/platform_device.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21
22#include <asm/mach-types.h>
23#include <mach/irqs.h>
24#include <mach/iomap.h>
25#include <mach/sdhci.h>
26#include <mach/pinmux.h>
27#include <asm/mach-types.h>
28
29#include "board-p852.h"
30
31static struct resource sdhci_resource1[] = {
32 [0] = {
33 .start = INT_SDMMC1,
34 .end = INT_SDMMC1,
35 .flags = IORESOURCE_IRQ,
36 },
37 [1] = {
38 .start = TEGRA_SDMMC1_BASE,
39 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE - 1,
40 .flags = IORESOURCE_MEM,
41 },
42};
43
44static struct resource sdhci_resource2[] = {
45 [0] = {
46 .start = INT_SDMMC2,
47 .end = INT_SDMMC2,
48 .flags = IORESOURCE_IRQ,
49 },
50 [1] = {
51 .start = TEGRA_SDMMC2_BASE,
52 .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE - 1,
53 .flags = IORESOURCE_MEM,
54 },
55};
56
57static struct resource sdhci_resource3[] = {
58 [0] = {
59 .start = INT_SDMMC3,
60 .end = INT_SDMMC3,
61 .flags = IORESOURCE_IRQ,
62 },
63 [1] = {
64 .start = TEGRA_SDMMC3_BASE,
65 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE - 1,
66 .flags = IORESOURCE_MEM,
67 },
68};
69
70static struct resource sdhci_resource4[] = {
71 [0] = {
72 .start = INT_SDMMC4,
73 .end = INT_SDMMC4,
74 .flags = IORESOURCE_IRQ,
75 },
76 [1] = {
77 .start = TEGRA_SDMMC4_BASE,
78 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE - 1,
79 .flags = IORESOURCE_MEM,
80 },
81};
82
83struct tegra_sdhci_platform_data p852_sdhci_platform_data[] = {
84 {
85 .cd_gpio = -1,
86 .wp_gpio = -1,
87 .power_gpio = -1,
88 },
89 {
90 .cd_gpio = -1,
91 .wp_gpio = -1,
92 .power_gpio = -1,
93 },
94 {
95 .cd_gpio = -1,
96 .wp_gpio = -1,
97 .power_gpio = -1,
98 },
99 {
100 .cd_gpio = -1,
101 .wp_gpio = -1,
102 .power_gpio = -1,
103 },
104};
105
106static struct platform_device tegra_sdhci_device[] = {
107 {
108 .name = "sdhci-tegra",
109 .id = 0,
110 .resource = sdhci_resource1,
111 .num_resources = ARRAY_SIZE(sdhci_resource1),
112 .dev = {
113 .platform_data = &p852_sdhci_platform_data[0],
114 },
115 },
116 {
117 .name = "sdhci-tegra",
118 .id = 1,
119 .resource = sdhci_resource2,
120 .num_resources = ARRAY_SIZE(sdhci_resource2),
121 .dev = {
122 .platform_data = &p852_sdhci_platform_data[1],
123 },
124 },
125 {
126 .name = "sdhci-tegra",
127 .id = 2,
128 .resource = sdhci_resource3,
129 .num_resources = ARRAY_SIZE(sdhci_resource3),
130 .dev = {
131 .platform_data = &p852_sdhci_platform_data[2],
132 },
133 },
134 {
135 .name = "sdhci-tegra",
136 .id = 3,
137 .resource = sdhci_resource4,
138 .num_resources = ARRAY_SIZE(sdhci_resource4),
139 .dev = {
140 .platform_data = &p852_sdhci_platform_data[3],
141 },
142 },
143
144};
145
146void __init p852_sdhci_init(void)
147{
148
149 int i, count = 10;
150 int cd = 0, wp = 0, pw = 0;
151 static char gpio_name[12][10];
152 unsigned int sdhci_config = 0;
153
154 if (p852_sku_peripherals & P852_SKU_SDHCI_ENABLE)
155 for (i = 0; i < P852_MAX_SDHCI; i++) {
156 sdhci_config =
157 (p852_sdhci_peripherals >> (P852_SDHCI_SHIFT * i));
158 cd = i * 3;
159 wp = cd + 1;
160 pw = wp + 1;
161 if (sdhci_config & P852_SDHCI_ENABLE) {
162 if (sdhci_config & P852_SDHCI_CD_EN) {
163 snprintf(gpio_name[cd], count,
164 "sdhci%d_cd", i);
165 gpio_request(p852_sdhci_platform_data
166 [i].cd_gpio,
167 gpio_name[cd]);
168 tegra_gpio_enable
169 (p852_sdhci_platform_data[i].
170 cd_gpio);
171 }
172
173 if (sdhci_config & P852_SDHCI_WP_EN) {
174 snprintf(gpio_name[wp], count,
175 "sdhci%d_wp", i);
176 gpio_request(p852_sdhci_platform_data
177 [i].wp_gpio,
178 gpio_name[wp]);
179 tegra_gpio_enable
180 (p852_sdhci_platform_data[i].
181 wp_gpio);
182 }
183
184 if (sdhci_config & P852_SDHCI_PW_EN) {
185 snprintf(gpio_name[pw], count,
186 "sdhci%d_pw", i);
187 gpio_request(p852_sdhci_platform_data
188 [i].power_gpio,
189 gpio_name[pw]);
190 tegra_gpio_enable
191 (p852_sdhci_platform_data[i].
192 power_gpio);
193 }
194
195 platform_device_register(&tegra_sdhci_device
196 [i]);
197 }
198 }
199}
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku1-b00.c b/arch/arm/mach-tegra/p852/board-p852-sku1-b00.c
new file mode 100644
index 00000000000..1cd89c5dfd7
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku1-b00.c
@@ -0,0 +1,98 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku1-b00.c
3 *
4 * Copyright (C) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku1_b00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku1_b00_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku1_b00_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE)
40 << P852_SDHCI4_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT) |
43 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
44 << P852_SDHCI3_SHIFT);
45
46 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
47 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
48 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
49 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
50}
51
52static inline void p852_sku1_b00_uart_init(void)
53{
54 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
55 p852_uart_peripherals |=
56 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
57 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
58 ((P852_UART_ENABLE | P852_UART_HS | P852_UART_ALT_PIN_CFG)
59 << P852_UARTA_SHIFT);
60}
61
62static inline void p852_sku1_b00_display_init(void)
63{
64 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
65 p852_display_peripherals |=
66 (P852_DISP_ENABLE << P852_DISPB_SHIFT);
67}
68
69static inline void p852_sku1_b00_ulpi_init(void)
70{
71 p852_sku_peripherals |= P852_SKU_ULPI_DISABLE;
72}
73
74static inline void p852_sku1_b00_i2c_init(void)
75{
76 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
77 p852_i2c_peripherals |=
78 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
79 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
80 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
81 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
82}
83
84void __init p852_sku1_b00_init(void)
85{
86 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
87
88 p852_sku1_b00_spi_init();
89 p852_sku1_b00_i2s_init();
90 p852_sku1_b00_uart_init();
91 p852_sku1_b00_sdhci_init();
92 p852_sku1_b00_i2c_init();
93 p852_sku1_b00_display_init();
94 p852_sku1_b00_ulpi_init();
95
96 p852_common_init();
97}
98
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku1-c0x.c b/arch/arm/mach-tegra/p852/board-p852-sku1-c0x.c
new file mode 100644
index 00000000000..4a783fb9b63
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku1-c0x.c
@@ -0,0 +1,98 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku1-c0x.c
3 *
4 * Copyright (C) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku1_c0x_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku1_c0x_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku1_c0x_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE)
40 << P852_SDHCI4_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT) |
43 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
44 << P852_SDHCI3_SHIFT);
45
46 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
47 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
48 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
49 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
50}
51
52static inline void p852_sku1_c0x_uart_init(void)
53{
54 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
55 p852_uart_peripherals |=
56 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
57 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
58 ((P852_UART_ENABLE | P852_UART_HS | P852_UART_ALT_PIN_CFG)
59 << P852_UARTA_SHIFT);
60}
61
62static inline void p852_sku1_c0x_display_init(void)
63{
64 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
65 p852_display_peripherals |=
66 (P852_DISP_ENABLE << P852_DISPB_SHIFT);
67}
68
69static inline void p852_sku1_c0x_ulpi_init(void)
70{
71 p852_sku_peripherals |= P852_SKU_ULPI_DISABLE;
72}
73
74static inline void p852_sku1_c0x_i2c_init(void)
75{
76 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
77 p852_i2c_peripherals |=
78 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
79 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
80 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
81 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
82}
83
84void __init p852_sku1_c0x_init(void)
85{
86 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
87
88 p852_sku1_c0x_spi_init();
89 p852_sku1_c0x_i2s_init();
90 p852_sku1_c0x_uart_init();
91 p852_sku1_c0x_sdhci_init();
92 p852_sku1_c0x_i2c_init();
93 p852_sku1_c0x_display_init();
94 p852_sku1_c0x_ulpi_init();
95
96 p852_common_init();
97}
98
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku1.c b/arch/arm/mach-tegra/p852/board-p852-sku1.c
new file mode 100644
index 00000000000..387ba054bd8
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku1.c
@@ -0,0 +1,89 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku1.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku1_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku1_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku1_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
40 << P852_SDHCI1_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI3_SHIFT) |
43 (P852_SDHCI_ENABLE << P852_SDHCI4_SHIFT);
44
45 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
46 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
47 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
48 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
49}
50
51static inline void p852_sku1_uart_init(void)
52{
53 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
54 p852_uart_peripherals |=
55 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
56 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT);
57}
58
59static inline void p852_sku1_display_init(void)
60{
61 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
62 p852_display_peripherals |=
63 (P852_DISP_ENABLE << P852_DISPB_SHIFT);
64}
65
66static inline void p852_sku1_i2c_init(void)
67{
68 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
69 p852_i2c_peripherals |=
70 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
72 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
73 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
74}
75
76void __init p852_sku1_init(void)
77{
78 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
79
80 p852_sku1_spi_init();
81 p852_sku1_i2s_init();
82 p852_sku1_uart_init();
83 p852_sku1_sdhci_init();
84 p852_sku1_i2c_init();
85 p852_sku1_display_init();
86
87 p852_common_init();
88}
89
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku13-b00.c b/arch/arm/mach-tegra/p852/board-p852-sku13-b00.c
new file mode 100644
index 00000000000..39e01f660ea
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku13-b00.c
@@ -0,0 +1,114 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku13-b00.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku13_b00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku13_b00_i2s_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
32 p852_i2s_peripherals |= (P852_I2S_ENABLE << P852_I2S1_SHIFT) |
33 (P852_I2S_ENABLE << P852_I2S2_SHIFT);
34}
35
36static inline void p852_sku13_b00_sdhci_init(void)
37{
38 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
39 p852_sdhci_peripherals |=
40 (P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
41 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT);
42
43 p852_sdhci_platform_data[1].is_8bit = true;
44}
45
46static inline void p852_sku13_b00_uart_init(void)
47{
48 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
49 p852_uart_peripherals |=
50 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTA_SHIFT) |
51 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
52 ((P852_UART_ENABLE) << P852_UARTC_SHIFT);
53}
54
55static inline void p852_sku13_b00_display_init(void)
56{
57 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
58 p852_display_peripherals |=
59 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
60}
61
62static inline void p852_sku13_b00_i2c_init(void)
63{
64 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
65 p852_i2c_peripherals |=
66 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
67 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
68 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
70 p852_i2c_set_default_clock(0, 40000);
71}
72
73#ifdef CONFIG_TEGRA_SPI_I2S
74static struct tegra_spi_i2s_platform_data spi_i2s_data = {
75 .gpio_i2s = {
76 .gpio_no = TEGRA_GPIO_PT5,
77 .active_state = 1,
78 },
79 .gpio_spi = {
80 .gpio_no = TEGRA_GPIO_PV7,
81 .active_state = 1,
82 },
83 .spi_i2s_timeout_ms = 25,
84};
85
86static inline void p852_sku13_b00_spi_i2s_init(void)
87{
88 tegra_spi_i2s_device.platform_data = &spi_i2s_data;
89 /* cpld_gpio_dir1 */
90 tegra_pinmux_set_tristate(TEGRA_PINGROUP_PTA, TEGRA_TRI_NORMAL);
91 /* cpld_gpio_dir2 */
92 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LVP0, TEGRA_TRI_NORMAL);
93 p852_spi_i2s_init();
94}
95#endif
96
97void __init p852_sku13_b00_init(void)
98{
99 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
100
101
102 p852_sku13_b00_spi_init();
103 p852_sku13_b00_i2s_init();
104 p852_sku13_b00_uart_init();
105 p852_sku13_b00_sdhci_init();
106 p852_sku13_b00_i2c_init();
107 p852_sku13_b00_display_init();
108
109 p852_common_init();
110
111#ifdef CONFIG_TEGRA_SPI_I2S
112 p852_sku13_b00_spi_i2s_init();
113#endif
114}
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku13.c b/arch/arm/mach-tegra/p852/board-p852-sku13.c
new file mode 100644
index 00000000000..92d917e6e2c
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku13.c
@@ -0,0 +1,112 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku13.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku13_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27
28}
29
30static inline void p852_sku13_i2s_init(void)
31{
32 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
33 p852_i2s_peripherals |= (P852_I2S_ENABLE << P852_I2S1_SHIFT) |
34 (P852_I2S_ENABLE << P852_I2S2_SHIFT);
35}
36
37static inline void p852_sku13_sdhci_init(void)
38{
39 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
40 p852_sdhci_peripherals |=
41 (P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
42 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT);
43
44 p852_sdhci_platform_data[1].is_8bit = true;
45}
46
47static inline void p852_sku13_uart_init(void)
48{
49 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
50 p852_uart_peripherals |=
51 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTA_SHIFT) |
52 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
53 ((P852_UART_ENABLE) << P852_UARTC_SHIFT);
54}
55
56static inline void p852_sku13_display_init(void)
57{
58 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
59 p852_display_peripherals |=
60 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
61}
62
63static inline void p852_sku13_i2c_init(void)
64{
65 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
66 p852_i2c_peripherals |=
67 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
68 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
71 p852_i2c_set_default_clock(0, 40000);
72}
73
74#ifdef CONFIG_TEGRA_SPI_I2S
75static struct tegra_spi_i2s_platform_data spi_i2s_data = {
76 .gpio_i2s = {
77 .gpio_no = TEGRA_GPIO_PS3,
78 .active_state = 0,
79 },
80 .gpio_spi = {
81 .gpio_no = TEGRA_GPIO_PS4,
82 .active_state = 0,
83 },
84 .spi_i2s_timeout_ms = 25,
85};
86
87static inline void p852_sku13_spi_i2s_init(void)
88{
89 tegra_spi_i2s_device.platform_data = &spi_i2s_data;
90 /* cpld_gpio_dir1 and cpld_gpio_dir2*/
91 tegra_pinmux_set_tristate(TEGRA_PINGROUP_KBCB, TEGRA_TRI_NORMAL);
92 p852_spi_i2s_init();
93}
94#endif
95
96void __init p852_sku13_init(void)
97{
98 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
99
100 p852_sku13_spi_init();
101 p852_sku13_i2s_init();
102 p852_sku13_uart_init();
103 p852_sku13_sdhci_init();
104 p852_sku13_i2c_init();
105 p852_sku13_display_init();
106
107 p852_common_init();
108
109#ifdef CONFIG_TEGRA_SPI_I2S
110 p852_sku13_spi_i2s_init();
111#endif
112}
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku23-b00.c b/arch/arm/mach-tegra/p852/board-p852-sku23-b00.c
new file mode 100644
index 00000000000..6f464ec3620
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku23-b00.c
@@ -0,0 +1,115 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku23-b00.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku23_b00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku23_b00_i2s_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
32 p852_i2s_peripherals |=
33 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S1_SHIFT) |
34 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S2_SHIFT);
35}
36
37static inline void p852_sku23_b00_sdhci_init(void)
38{
39 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
40 p852_sdhci_peripherals |= (P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
41 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT) |
42 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN) << P852_SDHCI3_SHIFT);
43
44 p852_sdhci_platform_data[1].is_8bit = true;
45 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
46}
47
48static inline void p852_sku23_b00_uart_init(void)
49{
50 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
51 p852_uart_peripherals |=
52 ((P852_UART_ENABLE) << P852_UARTA_SHIFT) |
53 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
54 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTC_SHIFT);
55}
56
57static inline void p852_sku23_b00_display_init(void)
58{
59 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
60 p852_display_peripherals |=
61 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
62}
63
64static inline void p852_sku23_b00_i2c_init(void)
65{
66 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
67 p852_i2c_peripherals |=
68 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74#ifdef CONFIG_TEGRA_SPI_I2S
75static struct tegra_spi_i2s_platform_data spi_i2s_data = {
76 .gpio_i2s = {
77 .gpio_no = TEGRA_GPIO_PT5,
78 .active_state = 1,
79 },
80 .gpio_spi = {
81 .gpio_no = TEGRA_GPIO_PV7,
82 .active_state = 1,
83 },
84 .spi_i2s_timeout_ms = 25,
85};
86
87static inline void p852_sku23_b00_spi_i2s_init(void)
88{
89 tegra_spi_i2s_device.platform_data = &spi_i2s_data;
90 /* cpld_gpio_dir1 */
91 tegra_pinmux_set_tristate(TEGRA_PINGROUP_PTA, TEGRA_TRI_NORMAL);
92 /* cpld_gpio_dir2 */
93 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LVP0, TEGRA_TRI_NORMAL);
94 p852_spi_i2s_init();
95}
96#endif
97
98void __init p852_sku23_b00_init(void)
99{
100 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
101
102 p852_sku23_b00_spi_init();
103 p852_sku23_b00_i2s_init();
104 p852_sku23_b00_uart_init();
105 p852_sku23_b00_sdhci_init();
106 p852_sku23_b00_i2c_init();
107 p852_sku23_b00_display_init();
108
109 p852_common_init();
110
111#ifdef CONFIG_TEGRA_SPI_I2S
112 p852_sku23_b00_spi_i2s_init();
113#endif
114}
115
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku23-c01.c b/arch/arm/mach-tegra/p852/board-p852-sku23-c01.c
new file mode 100644
index 00000000000..f946e0ed35e
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku23-c01.c
@@ -0,0 +1,87 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku23-c01.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku23_c01_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku23_c01_i2s_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
32 p852_i2s_peripherals |=
33 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S1_SHIFT) |
34 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S2_SHIFT);
35}
36
37static inline void p852_sku23_c01_sdhci_init(void)
38{
39 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
40 p852_sdhci_peripherals |= (P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
41 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT) |
42 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN) << P852_SDHCI3_SHIFT);
43
44 p852_sdhci_platform_data[1].is_8bit = true;
45 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
46}
47
48static inline void p852_sku23_c01_uart_init(void)
49{
50 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
51 p852_uart_peripherals |=
52 ((P852_UART_ENABLE) << P852_UARTA_SHIFT) |
53 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
54 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTC_SHIFT);
55}
56
57static inline void p852_sku23_c01_display_init(void)
58{
59 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
60 p852_display_peripherals |=
61 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
62}
63
64static inline void p852_sku23_c01_i2c_init(void)
65{
66 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
67 p852_i2c_peripherals |=
68 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74void __init p852_sku23_c01_init(void)
75{
76 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
77
78 p852_sku23_c01_spi_init();
79 p852_sku23_c01_i2s_init();
80 p852_sku23_c01_uart_init();
81 p852_sku23_c01_sdhci_init();
82 p852_sku23_c01_i2c_init();
83 p852_sku23_c01_display_init();
84
85 p852_common_init();
86}
87
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku23.c b/arch/arm/mach-tegra/p852/board-p852-sku23.c
new file mode 100644
index 00000000000..a2bc9b4ca0b
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku23.c
@@ -0,0 +1,113 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku23.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void __init p852_sku23_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku23_sdhci_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
32 p852_sdhci_peripherals |= (P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
33 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT) |
34 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN) << P852_SDHCI3_SHIFT);
35
36 p852_sdhci_platform_data[1].is_8bit = true;
37 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
38}
39
40static inline void p852_sku23_i2s_init(void)
41{
42 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
43 p852_i2s_peripherals |=
44 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S1_SHIFT) |
45 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S2_SHIFT);
46}
47
48static inline void p852_sku23_uart_init(void)
49{
50 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
51 p852_uart_peripherals |=
52 ((P852_UART_ENABLE) << P852_UARTA_SHIFT) |
53 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
54 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTC_SHIFT);
55}
56
57static inline void p852_sku23_display_init(void)
58{
59 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
60 p852_display_peripherals |=
61 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
62}
63
64static inline void p852_sku23_i2c_init(void)
65{
66 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
67 p852_i2c_peripherals |=
68 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74#ifdef CONFIG_TEGRA_SPI_I2S
75static struct tegra_spi_i2s_platform_data spi_i2s_data = {
76 .gpio_i2s = {
77 .gpio_no = TEGRA_GPIO_PS3,
78 .active_state = 0,
79 },
80 .gpio_spi = {
81 .gpio_no = TEGRA_GPIO_PS4,
82 .active_state = 0,
83 },
84 .spi_i2s_timeout_ms = 25,
85};
86
87static inline void p852_sku23_spi_i2s_init(void)
88{
89 tegra_spi_i2s_device.platform_data = &spi_i2s_data;
90 /* cpld_gpio_dir1 and cpld_gpio_dir2*/
91 tegra_pinmux_set_tristate(TEGRA_PINGROUP_KBCB, TEGRA_TRI_NORMAL);
92 p852_spi_i2s_init();
93}
94#endif
95
96void __init p852_sku23_init(void)
97{
98 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
99
100 p852_sku23_spi_init();
101 p852_sku23_i2s_init();
102 p852_sku23_uart_init();
103 p852_sku23_sdhci_init();
104 p852_sku23_i2c_init();
105 p852_sku23_display_init();
106
107 p852_common_init();
108
109#ifdef CONFIG_TEGRA_SPI_I2S
110 p852_sku23_spi_i2s_init();
111#endif
112}
113
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku3.c b/arch/arm/mach-tegra/p852/board-p852-sku3.c
new file mode 100644
index 00000000000..380df9a7439
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku3.c
@@ -0,0 +1,103 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku3.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku3_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku3_i2s_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
32 p852_i2s_peripherals |= (P852_I2S_ENABLE << P852_I2S1_SHIFT) |
33 (P852_I2S_ENABLE << P852_I2S2_SHIFT);
34}
35
36static inline void p852_sku3_sdhci_init(void)
37{
38 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
39 p852_sdhci_peripherals |=
40 (P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
41 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT);
42
43 p852_sdhci_platform_data[1].is_8bit = true;
44}
45
46static inline void p852_sku3_uart_init(void)
47{
48 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
49 p852_uart_peripherals |=
50 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTA_SHIFT) |
51 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
52 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTC_SHIFT);
53}
54
55static inline void p852_sku3_i2c_init(void)
56{
57 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
58 p852_i2c_peripherals |=
59 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
60 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
61 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
62 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
63 p852_i2c_set_default_clock(0, 40000);
64}
65
66#ifdef CONFIG_TEGRA_SPI_I2S
67static struct tegra_spi_i2s_platform_data spi_i2s_data = {
68 .gpio_i2s = {
69 .gpio_no = TEGRA_GPIO_PS3,
70 .active_state = 0,
71 },
72 .gpio_spi = {
73 .gpio_no = TEGRA_GPIO_PS4,
74 .active_state = 0,
75 },
76 .spi_i2s_timeout_ms = 25,
77};
78
79static inline void p852_sku3_spi_i2s_init(void)
80{
81 tegra_spi_i2s_device.platform_data = &spi_i2s_data;
82 /* cpld_gpio_dir1 and cpld_gpio_dir2*/
83 tegra_pinmux_set_tristate(TEGRA_PINGROUP_KBCB, TEGRA_TRI_NORMAL);
84 p852_spi_i2s_init();
85}
86#endif
87
88void __init p852_sku3_init(void)
89{
90 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
91
92 p852_sku3_spi_init();
93 p852_sku3_i2s_init();
94 p852_sku3_uart_init();
95 p852_sku3_sdhci_init();
96 p852_sku3_i2c_init();
97
98 p852_common_init();
99
100#ifdef CONFIG_TEGRA_SPI_I2S
101 p852_sku3_spi_i2s_init();
102#endif
103}
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku5-b00.c b/arch/arm/mach-tegra/p852/board-p852-sku5-b00.c
new file mode 100644
index 00000000000..59f6f13f772
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku5-b00.c
@@ -0,0 +1,115 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku5_b00.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku5_b00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku5_b00_i2s_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
32 p852_i2s_peripherals |=
33 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S1_SHIFT) |
34 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S2_SHIFT);
35}
36
37static inline void p852_sku5_b00_sdhci_init(void)
38{
39 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
40
41 p852_sdhci_peripherals |=
42 ((P852_SDHCI_ENABLE << P852_SDHCI1_SHIFT) |
43 (P852_SDHCI_ENABLE << P852_SDHCI2_SHIFT));
44
45 p852_sdhci_platform_data[1].is_8bit = true;
46}
47
48static inline void p852_sku5_b00_uart_init(void)
49{
50 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
51 p852_uart_peripherals |=
52 ((P852_UART_ENABLE) << P852_UARTA_SHIFT) |
53 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
54 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTC_SHIFT);
55}
56
57static inline void p852_sku5_b00_display_init(void)
58{
59 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
60 p852_display_peripherals |=
61 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
62}
63
64static inline void p852_sku5_b00_i2c_init(void)
65{
66 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
67 p852_i2c_peripherals |=
68 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74#ifdef CONFIG_TEGRA_SPI_I2S
75static struct tegra_spi_i2s_platform_data spi_i2s_data = {
76 .gpio_i2s = {
77 .gpio_no = TEGRA_GPIO_PT5,
78 .active_state = 1,
79 },
80 .gpio_spi = {
81 .gpio_no = TEGRA_GPIO_PV7,
82 .active_state = 1,
83 },
84 .spi_i2s_timeout_ms = 25,
85};
86
87static inline void p852_sku5_b00_spi_i2s_init(void)
88{
89 tegra_spi_i2s_device.platform_data = &spi_i2s_data;
90 /* cpld_gpio_dir1 */
91 tegra_pinmux_set_tristate(TEGRA_PINGROUP_PTA, TEGRA_TRI_NORMAL);
92 /* cpld_gpio_dir2 */
93 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LVP0, TEGRA_TRI_NORMAL);
94 p852_spi_i2s_init();
95}
96#endif
97
98void __init p852_sku5_b00_init(void)
99{
100 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
101
102 p852_sku5_b00_spi_init();
103 p852_sku5_b00_i2s_init();
104 p852_sku5_b00_uart_init();
105 p852_sku5_b00_sdhci_init();
106 p852_sku5_b00_i2c_init();
107 p852_sku5_b00_display_init();
108
109 p852_common_init();
110
111#ifdef CONFIG_TEGRA_SPI_I2S
112 p852_sku5_b00_spi_i2s_init();
113#endif
114}
115
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku5-c01.c b/arch/arm/mach-tegra/p852/board-p852-sku5-c01.c
new file mode 100644
index 00000000000..f9c8e72911b
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku5-c01.c
@@ -0,0 +1,93 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku5-c01.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku5_c01_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI2_SHIFT) |
25 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI3_SHIFT) |
26 ((P852_SPI_SLAVE | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
27}
28
29static inline void p852_sku5_c01_i2s_init(void)
30{
31 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
32 p852_i2s_peripherals |=
33 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S1_SHIFT) |
34 ((P852_I2S_TDM | P852_I2S_ENABLE) << P852_I2S2_SHIFT);
35}
36
37static inline void p852_sku5_c01_sdhci_init(void)
38{
39 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
40 p852_sdhci_peripherals |=
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT);
43
44 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
45 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
46}
47
48static inline void p852_sku5_c01_uart_init(void)
49{
50 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
51 p852_uart_peripherals |=
52 ((P852_UART_ENABLE) << P852_UARTA_SHIFT) |
53 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT) |
54 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTC_SHIFT);
55}
56
57static inline void p852_sku5_c01_display_init(void)
58{
59 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
60 p852_display_peripherals |=
61 (P852_DISP_ENABLE << P852_DISPA_SHIFT);
62}
63
64static inline void p852_sku5_c01_i2c_init(void)
65{
66 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
67 p852_i2c_peripherals |=
68 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
69 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C3_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74static inline void p852_sku5_c01_ulpi_init(void)
75{
76 p852_sku_peripherals |= P852_SKU_ULPI_DISABLE;
77}
78
79void __init p852_sku5_c01_init(void)
80{
81 p852_sku_peripherals |= P852_SKU_NAND_ENABLE;
82
83 p852_sku5_c01_spi_init();
84 p852_sku5_c01_i2s_init();
85 p852_sku5_c01_uart_init();
86 p852_sku5_c01_sdhci_init();
87 p852_sku5_c01_i2c_init();
88 p852_sku5_c01_display_init();
89 p852_sku5_c01_ulpi_init();
90
91 p852_common_init();
92}
93
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku8-b00.c b/arch/arm/mach-tegra/p852/board-p852-sku8-b00.c
new file mode 100644
index 00000000000..4cc4d53d980
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku8-b00.c
@@ -0,0 +1,88 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku8-b00.c
3 *
4 * Copyright (C) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku8_b00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku8_b00_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku8_b00_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE)
40 << P852_SDHCI4_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT) |
43 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
44 << P852_SDHCI3_SHIFT);
45
46 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
47 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
48 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
49 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
50}
51
52static inline void p852_sku8_b00_uart_init(void)
53{
54 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
55 p852_uart_peripherals |=
56 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
57 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT);
58}
59
60static inline void p852_sku8_b00_display_init(void)
61{
62 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
63}
64
65static inline void p852_sku8_b00_i2c_init(void)
66{
67 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
68 p852_i2c_peripherals |=
69 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74
75void __init p852_sku8_b00_init(void)
76{
77 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
78
79 p852_sku8_b00_spi_init();
80 p852_sku8_b00_i2s_init();
81 p852_sku8_b00_uart_init();
82 p852_sku8_b00_sdhci_init();
83 p852_sku8_b00_display_init();
84 p852_sku8_b00_i2c_init();
85
86 p852_common_init();
87}
88
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku8-c01.c b/arch/arm/mach-tegra/p852/board-p852-sku8-c01.c
new file mode 100644
index 00000000000..71210cd12b9
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku8-c01.c
@@ -0,0 +1,87 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku8-c00.c
3 *
4 * Copyright (C) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku8_c00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku8_c00_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku8_c00_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE)
40 << P852_SDHCI4_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT) |
43 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
44 << P852_SDHCI3_SHIFT);
45
46 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
47 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
48 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
49 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
50}
51
52static inline void p852_sku8_c00_uart_init(void)
53{
54 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
55 p852_uart_peripherals |=
56 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
57 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT);
58}
59
60static inline void p852_sku8_c00_display_init(void)
61{
62 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
63}
64
65static inline void p852_sku8_c00_i2c_init(void)
66{
67 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
68 p852_i2c_peripherals |=
69 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
70 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
71 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
72}
73
74
75void __init p852_sku8_c00_init(void)
76{
77 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
78
79 p852_sku8_c00_spi_init();
80 p852_sku8_c00_i2s_init();
81 p852_sku8_c00_uart_init();
82 p852_sku8_c00_sdhci_init();
83 p852_sku8_c00_display_init();
84 p852_sku8_c00_i2c_init();
85
86 p852_common_init();
87}
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku9-b00.c b/arch/arm/mach-tegra/p852/board-p852-sku9-b00.c
new file mode 100644
index 00000000000..7c3d9c3d9a3
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku9-b00.c
@@ -0,0 +1,93 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku9-b00.c
3 *
4 * Copyright (C) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku9_b00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku9_b00_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku9_b00_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE)
40 << P852_SDHCI4_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT) |
43 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
44 << P852_SDHCI3_SHIFT);
45
46 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
47 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
48 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
49 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
50}
51
52static inline void p852_sku9_b00_uart_init(void)
53{
54 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
55 p852_uart_peripherals |=
56 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
57 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT);
58}
59
60static inline void p852_sku9_b00_display_init(void)
61{
62 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
63}
64
65static inline void p852_sku9_b00_ulpi_init(void)
66{
67 p852_sku_peripherals |= P852_SKU_ULPI_DISABLE;
68}
69
70static inline void p852_sku9_b00_i2c_init(void)
71{
72 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
73 p852_i2c_peripherals |=
74 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
75 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
76 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
77}
78
79void __init p852_sku9_b00_init(void)
80{
81 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
82
83 p852_sku9_b00_spi_init();
84 p852_sku9_b00_i2s_init();
85 p852_sku9_b00_uart_init();
86 p852_sku9_b00_sdhci_init();
87 p852_sku9_b00_display_init();
88 p852_sku9_b00_ulpi_init();
89 p852_sku9_b00_i2c_init();
90
91 p852_common_init();
92}
93
diff --git a/arch/arm/mach-tegra/p852/board-p852-sku9-c01.c b/arch/arm/mach-tegra/p852/board-p852-sku9-c01.c
new file mode 100644
index 00000000000..94c79294fb4
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852-sku9-c01.c
@@ -0,0 +1,92 @@
1/*
2 * arch/arm/mach-tegra/board-p852-sku9-c00.c
3 *
4 * Copyright (C) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18
19static inline void p852_sku9_c00_spi_init(void)
20{
21 p852_sku_peripherals |= P852_SKU_SPI_ENABLE;
22 p852_spi_peripherals |=
23 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI1_SHIFT) |
24 ((P852_SPI_MASTER | P852_SPI_ENABLE) << P852_SPI4_SHIFT);
25}
26
27static inline void p852_sku9_c00_i2s_init(void)
28{
29 p852_sku_peripherals |= P852_SKU_I2S_ENABLE;
30 p852_i2s_peripherals |= ((P852_I2S_ENABLE | P852_I2S_TDM)
31 << P852_I2S1_SHIFT) | ((P852_I2S_ENABLE | P852_I2S_TDM)
32 << P852_I2S2_SHIFT);
33}
34
35static inline void p852_sku9_c00_sdhci_init(void)
36{
37 p852_sku_peripherals |= P852_SKU_SDHCI_ENABLE;
38 p852_sdhci_peripherals |=
39 ((P852_SDHCI_ENABLE)
40 << P852_SDHCI4_SHIFT) |
41 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
42 << P852_SDHCI1_SHIFT) |
43 ((P852_SDHCI_ENABLE | P852_SDHCI_CD_EN | P852_SDHCI_WP_EN)
44 << P852_SDHCI3_SHIFT);
45
46 p852_sdhci_platform_data[0].cd_gpio = TEGRA_GPIO_PV0;
47 p852_sdhci_platform_data[0].wp_gpio = TEGRA_GPIO_PV1;
48 p852_sdhci_platform_data[2].cd_gpio = TEGRA_GPIO_PD7;
49 p852_sdhci_platform_data[2].wp_gpio = TEGRA_GPIO_PT4;
50}
51
52static inline void p852_sku9_c00_uart_init(void)
53{
54 p852_sku_peripherals |= P852_SKU_UART_ENABLE;
55 p852_uart_peripherals |=
56 ((P852_UART_ENABLE | P852_UART_DB) << P852_UARTD_SHIFT) |
57 ((P852_UART_ENABLE | P852_UART_HS) << P852_UARTB_SHIFT);
58}
59
60static inline void p852_sku9_c00_display_init(void)
61{
62 p852_sku_peripherals |= P852_SKU_DISPLAY_ENABLE;
63}
64
65static inline void p852_sku9_c00_ulpi_init(void)
66{
67 p852_sku_peripherals |= P852_SKU_ULPI_DISABLE;
68}
69
70static inline void p852_sku9_c00_i2c_init(void)
71{
72 p852_sku_peripherals |= P852_SKU_I2C_ENABLE;
73 p852_i2c_peripherals |=
74 ((P852_I2C_ENABLE) << P852_I2C1_SHIFT) |
75 ((P852_I2C_ENABLE) << P852_I2C2_SHIFT) |
76 ((P852_I2C_ENABLE) << P852_I2C4_SHIFT);
77}
78
79void __init p852_sku9_c00_init(void)
80{
81 p852_sku_peripherals |= P852_SKU_NOR_ENABLE;
82
83 p852_sku9_c00_spi_init();
84 p852_sku9_c00_i2s_init();
85 p852_sku9_c00_uart_init();
86 p852_sku9_c00_sdhci_init();
87 p852_sku9_c00_display_init();
88 p852_sku9_c00_ulpi_init();
89 p852_sku9_c00_i2c_init();
90
91 p852_common_init();
92}
diff --git a/arch/arm/mach-tegra/p852/board-p852.c b/arch/arm/mach-tegra/p852/board-p852.c
new file mode 100644
index 00000000000..8e6551ed8c5
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852.c
@@ -0,0 +1,763 @@
1/*
2 * arch/arm/mach-tegra/board-p852.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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 "board-p852.h"
18#include <mach/spdif.h>
19
20unsigned int p852_sku_peripherals;
21unsigned int p852_spi_peripherals;
22unsigned int p852_i2s_peripherals;
23unsigned int p852_uart_peripherals;
24unsigned int p852_i2c_peripherals;
25unsigned int p852_sdhci_peripherals;
26unsigned int p852_display_peripherals;
27
28/* If enable_usb3 can have two options ehci3=eth or usb*/
29static char enable_usb3[4];
30
31int __init parse_enable_usb3(char *arg)
32{
33 if (!arg)
34 return 0;
35
36 strncpy(enable_usb3, arg, sizeof(enable_usb3));
37 return 0;
38}
39
40early_param("ehci3", parse_enable_usb3);
41
42static __initdata struct tegra_clk_init_table p852_clk_init_table[] = {
43 /* name parent rate enabled */
44 {"uarta", "pll_p", 216000000, true},
45 {"uartb", "pll_p", 216000000, true},
46 {"uartc", "pll_p", 216000000, true},
47 {"uartd", "pll_p", 216000000, true},
48 {"pll_m", "clk_m", 600000000, true},
49 {"pll_m_out1", "pll_m", 240000000, true},
50 {"pll_p_out4", "pll_p", 240000000, true},
51 {"host1x", "pll_p", 166000000, true},
52 {"disp1", "pll_p", 216000000, true},
53 {"vi", "pll_m", 100000000, true},
54 {"csus", "pll_m", 100000000, true},
55 {"emc", "pll_m", 600000000, true},
56 {"pll_c", "clk_m", 600000000, true},
57 {"pll_c_out1", "pll_c", 240000000, true},
58 {"pwm", "clk_32k", 32768, false},
59 {"clk_32k", NULL, 32768, true},
60 {"pll_a", NULL, 56448000, true},
61 {"pll_a_out0", "pll_a", 11289600, true},
62 {"audio", "pll_a_out0", 11289600, true},
63 {"audio_2x", "audio", 22579200, false},
64 {"vde", "pll_c", 240000000, false},
65 {"vi_sensor", "pll_m", 111000000, true},
66 {"epp", "pll_m", 111000000, true},
67 {"mpe", "pll_m", 111000000, true},
68 {"i2s1", "pll_a_out0", 11289600, true},
69 {"i2s2", "pll_a_out0", 11289600, true},
70 {"ndflash", "pll_p", 86500000, true},
71 {"sbc1", "pll_p", 12000000, false},
72 {"spdif_in", "pll_m", 22579000, true},
73 {"spdif_out", "pll_a_out0", 5644800, true},
74 {"sbc2", "pll_p", 12000000, false},
75 {"sbc3", "pll_p", 12000000, false},
76 {"sbc4", "pll_p", 12000000, false},
77 {"nor", "pll_p", 86500000, true},
78 {NULL, NULL, 0, 0},
79};
80
81static struct tegra_nand_chip_parms nand_chip_parms[] = {
82 /* Micron 29F4G08ABADA */
83 [0] = {
84 .vendor_id = 0x2C,
85 .device_id = 0xDC,
86 .capacity = 512,
87 .read_id_fourth_byte = 0x95,
88 .timing = {
89 .trp = 1,
90 .trh = 1,
91 .twp = 12,
92 .twh = 12,
93 .tcs = 24,
94 .twhr = 58,
95 .tcr_tar_trr = 12,
96 .twb = 116,
97 .trp_resp = 24,
98 .tadl = 24,
99 },
100 },
101 /* Micron 29F4G16ABADA */
102 [1] = {
103 .vendor_id = 0x2C,
104 .device_id = 0xCC,
105 .capacity = 512,
106 .read_id_fourth_byte = 0xD5,
107 .timing = {
108 .trp = 10,
109 .trh = 7,
110 .twp = 10,
111 .twh = 7,
112 .tcs = 15,
113 .twhr = 60,
114 .tcr_tar_trr = 20,
115 .twb = 100,
116 .trp_resp = 20,
117 .tadl = 70,
118 },
119 },
120 /* Hynix HY27UF084G2B */
121 [2] = {
122 .vendor_id = 0xAD,
123 .device_id = 0xDC,
124 .read_id_fourth_byte = 0x95,
125 .capacity = 512,
126 .timing = {
127 .trp = 12,
128 .trh = 1,
129 .twp = 12,
130 .twh = 0,
131 .tcs = 24,
132 .twhr = 58,
133 .tcr_tar_trr = 0,
134 .twb = 116,
135 .trp_resp = 24,
136 .tadl = 24,
137 },
138 },
139};
140
141struct tegra_nand_platform p852_nand_data = {
142 .max_chips = 8,
143 .chip_parms = nand_chip_parms,
144 .nr_chip_parms = ARRAY_SIZE(nand_chip_parms),
145 .wp_gpio = TEGRA_GPIO_PC7,
146};
147
148static struct resource resources_nand[] = {
149 [0] = {
150 .start = INT_NANDFLASH,
151 .end = INT_NANDFLASH,
152 .flags = IORESOURCE_IRQ,
153 },
154};
155
156static struct platform_device p852_nand_device = {
157 .name = "tegra_nand",
158 .id = -1,
159 .num_resources = ARRAY_SIZE(resources_nand),
160 .resource = resources_nand,
161 .dev = {
162 .platform_data = &p852_nand_data,
163 },
164};
165
166unsigned int p852_uart_irqs[] = {
167 INT_UARTA,
168 INT_UARTB,
169 INT_UARTC,
170 INT_UARTD,
171};
172
173unsigned int p852_uart_bases[] = {
174 TEGRA_UARTA_BASE,
175 TEGRA_UARTB_BASE,
176 TEGRA_UARTC_BASE,
177 TEGRA_UARTD_BASE,
178};
179
180static struct platform_device *p852_spi_devices[] __initdata = {
181 &tegra_spi_device1,
182 &tegra_spi_device2,
183 &tegra_spi_device3,
184 &tegra_spi_device4,
185};
186
187static struct plat_serial8250_port debug_uart_platform_data[] = {
188 {
189 .flags = UPF_BOOT_AUTOCONF,
190 .iotype = UPIO_MEM,
191 .regshift = 2,
192 .uartclk = 216000000,
193 },
194 {
195 .flags = 0,
196 }
197};
198
199#define DEF_8250_PLATFORM_DATA(_base, _irq) { \
200 .flags = UPF_BOOT_AUTOCONF, \
201 .iotype = UPIO_MEM, \
202 .membase = IO_ADDRESS(_base), \
203 .mapbase = _base, \
204 .irq = _irq, \
205 .regshift = 2, \
206 .uartclk = 216000000, \
207}
208
209static struct plat_serial8250_port tegra_8250_uarta_platform_data[] = {
210 DEF_8250_PLATFORM_DATA(TEGRA_UARTA_BASE, INT_UARTA),
211 {
212 .flags = 0,
213 }
214};
215
216static struct plat_serial8250_port tegra_8250_uartb_platform_data[] = {
217 DEF_8250_PLATFORM_DATA(TEGRA_UARTB_BASE, INT_UARTB),
218 {
219 .flags = 0,
220 }
221};
222
223static struct plat_serial8250_port tegra_8250_uartc_platform_data[] = {
224 DEF_8250_PLATFORM_DATA(TEGRA_UARTC_BASE, INT_UARTC),
225 {
226 .flags = 0,
227 }
228};
229
230static struct plat_serial8250_port tegra_8250_uartd_platform_data[] = {
231 DEF_8250_PLATFORM_DATA(TEGRA_UARTD_BASE, INT_UARTD),
232 {
233 .flags = 0,
234 }
235};
236
237static struct plat_serial8250_port tegra_8250_uarte_platform_data[] = {
238 DEF_8250_PLATFORM_DATA(TEGRA_UARTE_BASE, INT_UARTE),
239 {
240 .flags = 0,
241 }
242};
243
244struct platform_device tegra_8250_uarta_device = {
245 .name = "serial8250",
246 .id = PLAT8250_DEV_PLATFORM,
247 .dev = {
248 .platform_data = tegra_8250_uarta_platform_data,
249 },
250};
251
252struct platform_device tegra_8250_uartb_device = {
253 .name = "serial8250",
254 .id = PLAT8250_DEV_PLATFORM1,
255 .dev = {
256 .platform_data = tegra_8250_uartb_platform_data,
257 },
258};
259
260struct platform_device tegra_8250_uartc_device = {
261 .name = "serial8250",
262 .id = PLAT8250_DEV_PLATFORM2,
263 .dev = {
264 .platform_data = tegra_8250_uartc_platform_data,
265 },
266};
267
268struct platform_device tegra_8250_uartd_device = {
269 .name = "serial8250",
270 .id = PLAT8250_DEV_FOURPORT,
271 .dev = {
272 .platform_data = tegra_8250_uartd_platform_data,
273 },
274};
275
276struct platform_device tegra_8250_uarte_device = {
277 .name = "serial8250",
278 .id = PLAT8250_DEV_ACCENT,
279 .dev = {
280 .platform_data = tegra_8250_uarte_platform_data,
281 },
282};
283
284static struct platform_device debug_uart = {
285 .name = "serial8250",
286 .id = PLAT8250_DEV_PLATFORM,
287 .dev = {
288 .platform_data = debug_uart_platform_data,
289 },
290};
291
292static struct tegra_utmip_config utmi_phy_config[] = {
293 [0] = {
294 .hssync_start_delay = 0,
295 .idle_wait_delay = 17,
296 .elastic_limit = 16,
297 .term_range_adj = 6,
298 .xcvr_setup = 15,
299 .xcvr_lsfslew = 2,
300 .xcvr_lsrslew = 2,
301 },
302 [1] = {
303 .hssync_start_delay = 0,
304 .idle_wait_delay = 17,
305 .elastic_limit = 16,
306 .term_range_adj = 6,
307 .xcvr_setup = 8,
308 .xcvr_lsfslew = 2,
309 .xcvr_lsrslew = 2,
310 },
311};
312
313static struct tegra_ulpi_config ulpi_usb2_config = {
314 .reset_gpio = TEGRA_GPIO_PI5,
315};
316
317static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
318 [0] = {
319 .phy_config = &utmi_phy_config[0],
320 .operating_mode = TEGRA_USB_HOST,
321 .power_down_on_bus_suspend = 0,
322 },
323 [1] = {
324 .phy_config = &ulpi_usb2_config,
325 .operating_mode = TEGRA_USB_HOST,
326 .power_down_on_bus_suspend = 0,
327 .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI,
328 },
329 [2] = {
330 .phy_config = &utmi_phy_config[1],
331 .operating_mode = TEGRA_USB_HOST,
332 .power_down_on_bus_suspend = 0,
333 },
334};
335
336static void p852_usb_gpio_config(void)
337{
338 unsigned int usbeth_mux_gpio = 0, usb_ena_val;
339 unsigned int has_onboard_ethernet = 0;
340 unsigned int p852_eth_reset = TEGRA_GPIO_PD3;
341
342 switch (system_rev) {
343 case P852_SKU13_B00:
344 case P852_SKU23_B00:
345 case P852_SKU23_C01:
346 case P852_SKU8_B00:
347 case P852_SKU8_C01:
348 case P852_SKU9_B00:
349 case P852_SKU9_C01:
350 {
351 usbeth_mux_gpio = TEGRA_GPIO_PS3;
352 has_onboard_ethernet = 1;
353 usb_ena_val = 1;
354 }
355 break;
356 case P852_SKU5_B00:
357 case P852_SKU5_C01:
358 {
359 usb_ena_val = 1;
360 has_onboard_ethernet = 0;
361 }
362 break;
363 case P852_SKU1:
364 {
365 has_onboard_ethernet = 0;
366 usb_ena_val = 0;
367 strncpy(enable_usb3, "usb", sizeof(enable_usb3));
368 }
369 break;
370 case P852_SKU1_B00:
371 case P852_SKU1_C0X:
372 {
373 has_onboard_ethernet = 0;
374 usb_ena_val = 1;
375 strncpy(enable_usb3, "usb", sizeof(enable_usb3));
376 }
377 break;
378 default:
379 {
380 usbeth_mux_gpio = TEGRA_GPIO_PD4;
381 has_onboard_ethernet = 1;
382 usb_ena_val = 0;
383 }
384 }
385
386 if (has_onboard_ethernet) {
387 gpio_request_one(usbeth_mux_gpio, GPIOF_OUT_INIT_LOW,
388 "eth_ena");
389 tegra_gpio_enable(usbeth_mux_gpio);
390
391 /* eth reset */
392 gpio_request_one(p852_eth_reset, GPIOF_OUT_INIT_LOW,
393 "eth_reset");
394 tegra_gpio_enable(p852_eth_reset);
395 udelay(1);
396 gpio_direction_output(p852_eth_reset, 1);
397
398 if (!strcmp(enable_usb3, "eth"))
399 gpio_direction_output(usbeth_mux_gpio, 1);
400
401 /* exporting usbeth_mux_gpio */
402 gpio_export(usbeth_mux_gpio, true);
403 }
404
405 if (!strcmp(enable_usb3, "usb")) {
406 gpio_direction_output(TEGRA_GPIO_PB2, usb_ena_val);
407 gpio_direction_output(TEGRA_GPIO_PW1, usb_ena_val);
408 }
409}
410
411static struct platform_device *p852_uart_devices[] __initdata = {
412 &tegra_uarta_device,
413 &tegra_uartb_device,
414 &tegra_uartc_device,
415 &tegra_uartd_device,
416};
417
418static struct platform_device *p852_8250_uart_devices[] __initdata = {
419 &tegra_8250_uarta_device,
420 &tegra_8250_uartb_device,
421 &tegra_8250_uartc_device,
422 &tegra_8250_uartd_device,
423 &tegra_8250_uarte_device,
424};
425
426static struct platform_device tegra_itu656 = {
427 .name = "tegra_itu656",
428 .id = -1,
429};
430
431static struct platform_device *p852_devices[] __initdata = {
432 &tegra_gart_device,
433 &tegra_avp_device,
434 &tegra_itu656,
435};
436
437static struct tegra_nor_platform_data p852_nor_data = {
438 .flash = {
439 .map_name = "cfi_probe",
440 .width = 2,
441 },
442 .chip_parms = {
443 /* FIXME: use characterized clock freq */
444 .timing_default = {
445 .timing0 = 0xA0200253,
446 .timing1 = 0x00040406,
447 },
448 .timing_read = {
449 .timing0 = 0xA0200253,
450 .timing1 = 0x00000A00,
451 },
452 },
453};
454
455#ifdef CONFIG_TEGRA_SPI_I2S
456struct spi_board_info tegra_spi_i2s_device __initdata = {
457 .modalias = "spi_i2s_pcm",
458 .bus_num = 2,
459 .chip_select = 2,
460 .mode = SPI_MODE_0,
461 .max_speed_hz = 18000000,
462 .platform_data = NULL,
463 .irq = 0,
464};
465
466void __init p852_spi_i2s_init(void)
467{
468 struct tegra_spi_i2s_platform_data *pdata;
469
470 pdata = (struct tegra_spi_i2s_platform_data *)
471 tegra_spi_i2s_device.platform_data;
472 if (pdata->gpio_i2s.active_state) {
473 gpio_request_one(pdata->gpio_i2s.gpio_no, GPIOF_OUT_INIT_LOW,
474 "i2s_cpld_dir1");
475 } else {
476 gpio_request_one(pdata->gpio_i2s.gpio_no, GPIOF_OUT_INIT_HIGH,
477 "i2s_cpld_dir1");
478 }
479 tegra_gpio_enable(pdata->gpio_i2s.gpio_no);
480 if (pdata->gpio_spi.active_state) {
481 gpio_request_one(pdata->gpio_spi.gpio_no, GPIOF_OUT_INIT_LOW,
482 "spi_cpld_dir2");
483 } else {
484 gpio_request_one(pdata->gpio_spi.gpio_no, GPIOF_OUT_INIT_HIGH,
485 "spi_cpld_dir2");
486 }
487
488 tegra_gpio_enable(pdata->gpio_spi.gpio_no);
489 spi_register_board_info(&tegra_spi_i2s_device, 1);
490}
491#endif
492
493#if defined(CONFIG_SPI_TEGRA) && defined(CONFIG_SPI_SPIDEV)
494static struct spi_board_info tegra_spi_devices[] __initdata = {
495 {
496 .modalias = "spidev",
497 .bus_num = 0,
498 .chip_select = 0,
499 .mode = SPI_MODE_0,
500 .max_speed_hz = 18000000,
501 .platform_data = NULL,
502 .irq = 0,
503 },
504 {
505 .modalias = "spidev",
506 .bus_num = 1,
507 .chip_select = 1,
508 .mode = SPI_MODE_0,
509 .max_speed_hz = 18000000,
510 .platform_data = NULL,
511 .irq = 0,
512 },
513 {
514 .modalias = "spidev",
515 .bus_num = 3,
516 .chip_select = 1,
517 .mode = SPI_MODE_0,
518 .max_speed_hz = 18000000,
519 .platform_data = NULL,
520 .irq = 0,
521 },
522};
523
524static void __init p852_register_spidev(void)
525{
526 spi_register_board_info(tegra_spi_devices,
527 ARRAY_SIZE(tegra_spi_devices));
528}
529#else
530#define p852_register_spidev() do {} while (0)
531#endif
532
533static void __init p852_usb_init(void)
534{
535
536 p852_usb_gpio_config();
537 /*
538 if (system_rev == P852_SKU8)
539 {
540 platform_device_register(&tegra_udc_device);
541 }
542 else
543 */
544 {
545 tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0];
546 platform_device_register(&tegra_ehci1_device);
547 }
548
549 if (!(p852_sku_peripherals & P852_SKU_ULPI_DISABLE)) {
550 tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1];
551 platform_device_register(&tegra_ehci2_device);
552 }
553
554 tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2];
555 platform_device_register(&tegra_ehci3_device);
556}
557
558static void __init spi3_pingroup_clear_tristate(void)
559{
560 /* spi3 mosi, miso, cs, clk */
561 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LSDI, TEGRA_TRI_NORMAL);
562 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LSDA, TEGRA_TRI_NORMAL);
563 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LCSN, TEGRA_TRI_NORMAL);
564 tegra_pinmux_set_tristate(TEGRA_PINGROUP_LSCK, TEGRA_TRI_NORMAL);
565}
566
567static void __init p852_spi_init(void)
568{
569 if (p852_sku_peripherals & P852_SKU_SPI_ENABLE) {
570 int i = 0;
571 unsigned int spi_config = 0;
572 unsigned int spi3_config =
573 (p852_spi_peripherals >> P852_SPI3_SHIFT) & P852_SPI_MASK;
574
575 for (i = 0; i < P852_MAX_SPI; i++) {
576 spi_config =
577 (p852_spi_peripherals >> (P852_SPI_SHIFT * i)) &
578 P852_SPI_MASK;
579 if (spi_config & P852_SPI_ENABLE) {
580 if (spi_config & P852_SPI_SLAVE)
581 p852_spi_devices[i]->name =
582 "tegra_spi_slave";
583 platform_device_register(p852_spi_devices[i]);
584 }
585 }
586 /* Default spi3 pingroups are in tristate */
587 if (spi3_config & P852_SPI_ENABLE)
588 spi3_pingroup_clear_tristate();
589 }
590}
591
592static void __init p852_uart_init(void)
593{
594 if (p852_sku_peripherals & P852_SKU_UART_ENABLE) {
595 int i = 0;
596 unsigned int uart_config = 0, uart8250Id = 0;
597 int debug_console = -1;
598
599 /* register the debug console as the first serial console */
600 for (i = 0; i < P852_MAX_UART; i++) {
601 uart_config =
602 (p852_uart_peripherals >> (P852_UART_SHIFT * i));
603 if (uart_config & P852_UART_DB) {
604 debug_console = i;
605 debug_uart_platform_data[0].membase =
606 IO_ADDRESS(p852_uart_bases[i]);
607 debug_uart_platform_data[0].mapbase =
608 p852_uart_bases[i];
609 debug_uart_platform_data[0].irq =
610 p852_uart_irqs[i];
611 uart8250Id++;
612 platform_device_register(&debug_uart);
613 break;
614 }
615 }
616
617 /* register remaining UARTS */
618 for (i = 0; i < P852_MAX_UART; i++) {
619 uart_config =
620 (p852_uart_peripherals >> (P852_UART_SHIFT * i)) &
621 P852_UART_MASK;
622 if ((uart_config & P852_UART_ENABLE)
623 && i != debug_console) {
624 if (uart_config & P852_UART_HS) {
625 platform_device_register
626 (p852_uart_devices[i]);
627 } else {
628 p852_8250_uart_devices[i]->id =
629 uart8250Id++;
630 platform_device_register
631 (p852_8250_uart_devices[i]);
632 }
633 }
634 }
635 }
636}
637
638static struct platform_device generic_codec_driver = {
639 .name = "generic-dit",
640};
641
642static void __init p852_flash_init(void)
643{
644 if (p852_sku_peripherals & P852_SKU_NAND_ENABLE)
645 platform_device_register(&p852_nand_device);
646
647 if (p852_sku_peripherals & P852_SKU_NOR_ENABLE) {
648 tegra_nor_device.resource[2].end = TEGRA_NOR_FLASH_BASE + SZ_64M - 1;
649 tegra_nor_device.dev.platform_data = &p852_nor_data;
650 platform_device_register(&tegra_nor_device);
651 }
652}
653
654void __init p852_common_init(void)
655{
656 tegra_clk_init_from_table(p852_clk_init_table);
657
658 p852_pinmux_init();
659
660 p852_i2c_init();
661
662 p852_regulator_init();
663
664 p852_uart_init();
665
666 p852_flash_init();
667
668 platform_add_devices(p852_devices, ARRAY_SIZE(p852_devices));
669
670 //p852_panel_init();
671
672 p852_spi_init();
673
674 p852_register_spidev();
675
676 p852_usb_init();
677
678 p852_sdhci_init();
679
680 p852_gpio_init();
681}
682
683void __init tegra_p852_init(void)
684{
685 switch (system_rev) {
686 case P852_SKU3:
687 p852_sku3_init();
688 break;
689 case P852_SKU13:
690 p852_sku13_init();
691 break;
692 case P852_SKU13_B00:
693 case P852_SKU13_C01:
694 p852_sku13_b00_init();
695 break;
696 case P852_SKU23:
697 p852_sku23_init();
698 break;
699 case P852_SKU23_B00:
700 p852_sku23_b00_init();
701 break;
702 case P852_SKU23_C01:
703 p852_sku23_c01_init();
704 break;
705 case P852_SKU1:
706 p852_sku1_init();
707 break;
708 case P852_SKU11:
709 case P852_SKU1_B00:
710 p852_sku1_b00_init();
711 break;
712 case P852_SKU1_C0X:
713 p852_sku1_c0x_init();
714 break;
715 case P852_SKU5_B00:
716 p852_sku5_b00_init();
717 break;
718 case P852_SKU5_C01:
719 p852_sku5_c01_init();
720 break;
721 case P852_SKU8_B00:
722 p852_sku8_b00_init();
723 break;
724 case P852_SKU8_C01:
725 p852_sku8_c00_init();
726 break;
727 case P852_SKU9_B00:
728 p852_sku9_b00_init();
729 break;
730 case P852_SKU9_C01:
731 p852_sku9_c00_init();
732 break;
733 default:
734 printk(KERN_ERR "Unknow Board Revision\n");
735 break;
736 }
737}
738
739static void __init tegra_p852_reserve(void)
740{
741 switch (system_rev) {
742 case P852_SKU3:
743 case P852_SKU5_B00:
744 case P852_SKU5_C01:
745 case P852_SKU9_B00:
746 case P852_SKU9_C01:
747 tegra_reserve(SZ_64M + SZ_16M, SZ_8M, 0);
748 break;
749 default:
750 tegra_reserve(SZ_128M, SZ_8M, 0);
751 break;
752 }
753}
754
755MACHINE_START(P852, "Tegra P852")
756 .boot_params = 0x00000100,
757 .map_io = tegra_map_common_io,
758 .reserve = tegra_p852_reserve,
759 .init_early = tegra_init_early,
760 .init_irq = tegra_init_irq,
761 .timer = &tegra_timer,
762 .init_machine = tegra_p852_init,
763MACHINE_END
diff --git a/arch/arm/mach-tegra/p852/board-p852.h b/arch/arm/mach-tegra/p852/board-p852.h
new file mode 100644
index 00000000000..bb43febb4a2
--- /dev/null
+++ b/arch/arm/mach-tegra/p852/board-p852.h
@@ -0,0 +1,300 @@
1/*
2 * arch/arm/mach-tegra/board-p852.h
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
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_P852M_H
18#define _MACH_TEGRA_BOARD_P852M_H
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/serial_8250.h>
24#include <linux/clk.h>
25#include <linux/mtd/mtd.h>
26#include <linux/mtd/partitions.h>
27#include <linux/dma-mapping.h>
28#include <linux/io.h>
29#include <linux/delay.h>
30#include <linux/i2c.h>
31#include <linux/spi/spi.h>
32#include <linux/i2c-tegra.h>
33#include <linux/platform_data/tegra_usb.h>
34#include <linux/platform_data/tegra_nor.h>
35#include <linux/gpio.h>
36
37#include <asm/mach-types.h>
38#include <asm/mach/arch.h>
39#include <asm/mach/time.h>
40#include <asm/setup.h>
41#include <asm/mach-types.h>
42#include <asm/mach/flash.h>
43
44#include <mach/sdhci.h>
45#include <mach/iomap.h>
46#include <mach/irqs.h>
47#include <mach/nand.h>
48#include <mach/usb_phy.h>
49#include <mach/clk.h>
50#include <mach/i2s.h>
51#include <mach/audio.h>
52
53#include "../clock.h"
54#include "../board.h"
55#include "../pm.h"
56#include "../devices.h"
57#include "../gpio-names.h"
58#include "../wakeups-t2.h"
59
60
61#define P852_SKU3 0x030000UL
62#define P852_SKU13 0x130000UL
63#define P852_SKU13_B00 0x130200UL
64#define P852_SKU13_C01 0x130401UL
65#define P852_SKU23 0x230000UL
66#define P852_SKU23_B00 0x230200UL
67#define P852_SKU23_C01 0x230401UL
68#define P852_SKU1 0x010000UL
69#define P852_SKU1_B00 0x010200UL
70#define P852_SKU1_C0X 0x010400UL
71#define P852_SKU11 0x110000UL
72#define P852_SKU5_B00 0x040200UL
73#define P852_SKU5_C01 0x050401UL
74#define P852_SKU8_B00 0x080200UL
75#define P852_SKU8_C01 0x080401UL
76#define P852_SKU9_B00 0x090200UL
77#define P852_SKU9_C01 0x090401UL
78
79int p852_regulator_init(void);
80int p852_panel_init(void);
81void p852_sdhci_init(void);
82void p852_i2c_init(void);
83void p852_i2c_set_default_clock(int adapter, unsigned long clock);
84void p852_pinmux_init(void);
85void p852_gpio_init(void);
86
87void p852_sku1_init(void);
88void p852_sku1_b00_init(void);
89void p852_sku1_c0x_init(void);
90void p852_sku3_init(void);
91void p852_sku5_b00_init(void);
92void p852_sku5_c01_init(void);
93void p852_sku8_b00_init(void);
94void p852_sku8_c00_init(void);
95void p852_sku9_b00_init(void);
96void p852_sku9_c00_init(void);
97void p852_sku13_init(void);
98void p852_sku13_b00_init(void);
99void p852_sku23_init(void);
100void p852_sku23_b00_init(void);
101void p852_sku23_c01_init(void);
102
103#ifndef CONFIG_P852_SKU1
104void p852_sku1_init(void);
105#endif
106#ifndef CONFIG_P852_SKU1_B00
107void p852_sku1_b00_init(void);
108#endif
109#ifndef CONFIG_P852_SKU1_C0x
110void p852_sku1_c0x_init(void);
111#endif
112#ifndef CONFIG_P852_SKU3
113void p852_sku3_init(void);
114#endif
115#ifndef CONFIG_P852_SKU5_B00
116void p852_sku5_b00_init(void){};
117#endif
118#ifndef CONFIG_P852_SKU5_C01
119void p852_sku5_c01_init(void){};
120#endif
121#ifndef CONFIG_P852_SKU8_B00
122void p852_sku8_b00_init(void){};
123#endif
124#ifndef CONFIG_P852_SKU8_C01
125void p852_sku8_c00_init(void){};
126#endif
127#ifndef CONFIG_P852_SKU9_B00
128void p852_sku9_b00_init(void){};
129#endif
130#ifndef CONFIG_P852_SKU9_C01
131void p852_sku9_c00_init(void){};
132#endif
133#ifndef CONFIG_P852_SKU13
134void p852_sku13_init(void){};
135#endif
136#ifndef CONFIG_P852_SKU13_B00
137void p852_sku13_b00_init(void){};
138#endif
139#ifndef CONFIG_P852_SKU23
140void p852_sku23_init(void){};
141#endif
142#ifndef CONFIG_P852_SKU23_B00
143void p852_sku23_b00_init(void){};
144#endif
145#ifndef CONFIG_P852_SKU23_C01
146void p852_sku23_c01_init(void){};
147#endif
148
149extern unsigned int system_rev;
150extern unsigned int p852_sku_peripherals;
151extern unsigned int p852_spi_peripherals;
152extern unsigned int p852_i2s_peripherals;
153extern unsigned int p852_uart_peripherals;
154extern unsigned int p852_sdhci_peripherals;
155extern unsigned int p852_display_peripherals;
156extern unsigned int p852_i2c_peripherals;
157extern struct tegra_sdhci_platform_data p852_sdhci_platform_data[];
158extern struct platform_device tegra_8250_uarta_device;
159extern struct platform_device tegra_8250_uartb_device;
160extern struct platform_device tegra_8250_uartc_device;
161extern struct platform_device tegra_8250_uartd_device;
162extern struct platform_device tegra_8250_uarte_device;
163
164#ifdef CONFIG_TEGRA_SPI_I2S
165extern void p852_spi_i2s_init(void);
166extern struct spi_board_info tegra_spi_i2s_device;
167#endif
168
169void tegra_p852_fixup(struct machine_desc *desc,
170 struct tag *tags, char **cmdline, struct meminfo *mi);
171
172void p852_common_init(void);
173
174#define P852_SDIO3_PINMUX_ENABLE 0x01
175
176#define P852_SKU_SPI_SHIFT 0x00
177#define P852_SKU_SPI_ENABLE (1 << P852_SKU_SPI_SHIFT)
178#define P852_SKU_SPI_MASK (1 << P852_SKU_SPI_SHIFT)
179
180#define P852_SKU_I2S_SHIFT 0x01
181#define P852_SKU_I2S_ENABLE (1 << P852_SKU_I2S_SHIFT)
182#define P852_SKU_I2S_MASK (1 << P852_SKU_I2S_SHIFT)
183
184#define P852_SKU_SDHCI_SHIFT 0x02
185#define P852_SKU_SDHCI_ENABLE (1 << P852_SKU_SDHCI_SHIFT)
186#define P852_SKU_SDHCI_MASK (1 << P852_SKU_SDHCI_SHIFT)
187
188#define P852_SKU_UART_SHIFT 0x03
189#define P852_SKU_UART_ENABLE (1 << P852_SKU_UART_SHIFT)
190#define P852_SKU_UART_MASK (1 << P852_SKU_UART_SHIFT)
191
192#define P852_SKU_NAND_SHIFT 0x04
193#define P852_SKU_NAND_ENABLE (1 << P852_SKU_NAND_SHIFT)
194#define P852_SKU_NAND_MASK (1 << P852_SKU_NAND_SHIFT)
195
196#define P852_SKU_NOR_SHIFT 0x05
197#define P852_SKU_NOR_ENABLE (1 << P852_SKU_NOR_SHIFT)
198#define P852_SKU_NOR_MASK (1 << P852_SKU_NOR_SHIFT)
199
200#define P852_SKU_DISPLAY_SHIFT 0x06
201#define P852_SKU_DISPLAY_ENABLE (1 << P852_SKU_DISPLAY_SHIFT)
202#define P852_SKU_DISPLAY_MASK (1 << P852_SKU_DISPLAY_SHIFT)
203
204#define P852_SKU_ULPI_SHIFT 0x07
205#define P852_SKU_ULPI_DISABLE (1 << P852_SKU_ULPI_SHIFT)
206
207#define P852_SKU_I2C_SHIFT 0x08
208#define P852_SKU_I2C_ENABLE (1 << P852_SKU_I2C_SHIFT)
209#define P852_SKU_I2C_MASK (1 << P852_SKU_I2C_SHIFT)
210
211#define P852_MAX_DISP 0x2
212#define P852_DISP_SHIFT 0x16
213#define P852_DISPA_SHIFT 0x0
214#define P852_DISPB_SHIFT 0x16
215
216#define P852_DISP_MASK 0x1
217#define P852_DISP_ENABLE 0x1
218#define P852_DISPA_MASK (P852_DISP_MASK << P852_DISPA_SHIFT)
219#define P852_DISPB_MASK (P852_DISP_MASK << P852_DISPB_SHIFT)
220
221#define P852_MAX_SPI 0x04
222#define P852_SPI_SHIFT 0x03
223#define P852_SPI1_SHIFT 0x00
224#define P852_SPI2_SHIFT 0x03
225#define P852_SPI3_SHIFT 0x06
226#define P852_SPI4_SHIFT 0x09
227
228#define P852_SPI_MASK 0x07
229#define P852_SPI1_MASK (P852_SPI_MASK << P852_SPI1_SHIFT)
230#define P852_SPI2_MASK (P852_SPI_MASK << P852_SPI2_SHIFT)
231#define P852_SPI3_MASK (P852_SPI_MASK << P852_SPI3_SHIFT)
232#define P852_SPI4_MASK (P852_SPI_MASK << P852_SPI4_SHIFT)
233
234#define P852_SPI_ENABLE 0x01
235#define P852_SPI_MASTER 0x02
236#define P852_SPI_SLAVE 0x04
237
238#define P852_I2S_SHIFT 0x05
239#define P852_I2S1_SHIFT 0x00
240#define P852_I2S2_SHIFT 0x05
241
242#define P852_I2S_MASK 0x1F
243#define P852_I2S1_MASK (P852_I2S_MASK << P852_I2S1_SHIFT)
244#define P852_I2S2_MASK (P852_I2S_MASK << P852_I2S2_SHIFT)
245
246#define P852_I2S_ENABLE 0x10
247#define P852_I2S_TDM 0x08
248#define P852_MAX_SDHCI 0x04
249#define P852_SDHCI_SHIFT 0x04
250#define P852_SDHCI1_SHIFT 0x00
251#define P852_SDHCI2_SHIFT 0x04
252#define P852_SDHCI3_SHIFT 0x08
253#define P852_SDHCI4_SHIFT 0x0C
254
255#define P852_SDHCI_MASK 0x0F
256#define P852_SDHCI1_MASK (P852_SDHCI_MASK << P852_SDHCI1_SHIFT)
257#define P852_SDHCI2_MASK (P852_SDHCI_MASK << P852_SDHCI2_SHIFT)
258#define P852_SDHCI3_MASK (P852_SDHCI_MASK << P852_SDHCI3_SHIFT)
259#define P852_SDHCI4_MASK (P852_SDHCI_MASK << P852_SDHCI4_SHIFT)
260
261#define P852_SDHCI_ENABLE 0x01
262#define P852_SDHCI_CD_EN 0x02
263#define P852_SDHCI_WP_EN 0x04
264#define P852_SDHCI_PW_EN 0x08
265
266#define P852_UART_SHIFT 0x04
267#define P852_UARTA_SHIFT 0x00
268#define P852_UARTB_SHIFT 0x04
269#define P852_UARTC_SHIFT 0x08
270#define P852_UARTD_SHIFT 0x0C
271
272#define P852_UART_MASK 0x0F
273#define P852_UARTA_MASK (P852_UART_MASK << P852_UARTA_SHIFT)
274#define P852_UARTB_MASK (P852_UART_MASK << P852_UARTB_SHIFT)
275#define P852_UARTC_MASK (P852_UART_MASK << P852_UARTC_SHIFT)
276#define P852_UARTD_MASK (P852_UART_MASK << P852_UARTD_SHIFT)
277
278#define P852_MAX_UART 0x4
279#define P852_UART_ALT_PIN_CFG 0x8
280#define P852_UART_ENABLE 0x4
281#define P852_UART_DB 0x1
282#define P852_UART_HS 0x2
283
284#define P852_MAX_I2C 0x4
285#define P852_I2C_SHIFT 0x01
286#define P852_I2C1_SHIFT 0x00
287#define P852_I2C2_SHIFT 0x01
288#define P852_I2C3_SHIFT 0x02
289#define P852_I2C4_SHIFT 0x03
290
291
292#define P852_I2C_MASK 0x01
293#define P852_I2C1_MASK (P852_I2C_MASK << P852_I2C1_SHIFT)
294#define P852_I2C2_MASK (P852_I2C_MASK << P852_I2C2_SHIFT)
295#define P852_I2C3_MASK (P852_I2C_MASK << P852_I2C3_SHIFT)
296#define P852_I2C4_MASK (P852_I2C_MASK << P852_I2C4_SHIFT)
297
298#define P852_I2C_ENABLE 0x01
299
300#endif
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c
new file mode 100644
index 00000000000..3a39f45cb57
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux-t2-tables.c
@@ -0,0 +1,338 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux-t2-tables.c
3 *
4 * Common pinmux configurations for Tegra 2 SoCs
5 *
6 * Copyright (C) 2010 NVIDIA Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/errno.h>
25#include <linux/spinlock.h>
26#include <linux/io.h>
27#include <linux/init.h>
28#include <linux/string.h>
29#include <linux/syscore_ops.h>
30
31#include <mach/iomap.h>
32#include <mach/pinmux.h>
33#include "gpio-names.h"
34
35#define SET_DRIVE_PINGROUP(pg_name, r, drv_down_offset, drv_down_mask, drv_up_offset, drv_up_mask, \
36 slew_rise_offset, slew_rise_mask, slew_fall_offset, slew_fall_mask) \
37 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
38 .name = #pg_name, \
39 .reg = r, \
40 .drvup_offset = drv_up_offset, \
41 .drvup_mask = drv_up_mask, \
42 .drvdown_offset = drv_down_offset, \
43 .drvdown_mask = drv_down_mask, \
44 .slewrise_offset = slew_rise_offset, \
45 .slewrise_mask = slew_rise_mask, \
46 .slewfall_offset = slew_fall_offset, \
47 .slewfall_mask = slew_fall_mask, \
48 }
49
50#define DEFAULT_DRIVE_PINGROUP(pg_name, r) \
51 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
52 .name = #pg_name, \
53 .reg = r, \
54 .drvup_offset = 20, \
55 .drvup_mask = 0x1f, \
56 .drvdown_offset = 12, \
57 .drvdown_mask = 0x1f, \
58 .slewrise_offset = 28, \
59 .slewrise_mask = 0x3, \
60 .slewfall_offset = 30, \
61 .slewfall_mask = 0x3, \
62 }
63
64const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
65 DEFAULT_DRIVE_PINGROUP(AO1, 0x868),
66 DEFAULT_DRIVE_PINGROUP(AO2, 0x86c),
67 DEFAULT_DRIVE_PINGROUP(AT1, 0x870),
68 DEFAULT_DRIVE_PINGROUP(AT2, 0x874),
69 DEFAULT_DRIVE_PINGROUP(CDEV1, 0x878),
70 DEFAULT_DRIVE_PINGROUP(CDEV2, 0x87c),
71 DEFAULT_DRIVE_PINGROUP(CSUS, 0x880),
72 DEFAULT_DRIVE_PINGROUP(DAP1, 0x884),
73 DEFAULT_DRIVE_PINGROUP(DAP2, 0x888),
74 DEFAULT_DRIVE_PINGROUP(DAP3, 0x88c),
75 DEFAULT_DRIVE_PINGROUP(DAP4, 0x890),
76 DEFAULT_DRIVE_PINGROUP(DBG, 0x894),
77 DEFAULT_DRIVE_PINGROUP(LCD1, 0x898),
78 DEFAULT_DRIVE_PINGROUP(LCD2, 0x89c),
79 DEFAULT_DRIVE_PINGROUP(SDMMC2, 0x8a0),
80 DEFAULT_DRIVE_PINGROUP(SDMMC3, 0x8a4),
81 DEFAULT_DRIVE_PINGROUP(SPI, 0x8a8),
82 DEFAULT_DRIVE_PINGROUP(UAA, 0x8ac),
83 DEFAULT_DRIVE_PINGROUP(UAB, 0x8b0),
84 DEFAULT_DRIVE_PINGROUP(UART2, 0x8b4),
85 DEFAULT_DRIVE_PINGROUP(UART3, 0x8b8),
86 DEFAULT_DRIVE_PINGROUP(VI1, 0x8bc),
87 DEFAULT_DRIVE_PINGROUP(VI2, 0x8c0),
88 DEFAULT_DRIVE_PINGROUP(XM2A, 0x8c4),
89 DEFAULT_DRIVE_PINGROUP(XM2C, 0x8c8),
90 DEFAULT_DRIVE_PINGROUP(XM2D, 0x8cc),
91 DEFAULT_DRIVE_PINGROUP(XM2CLK, 0x8d0),
92 DEFAULT_DRIVE_PINGROUP(MEMCOMP, 0x8d4),
93 DEFAULT_DRIVE_PINGROUP(SDIO1, 0x8e0),
94 DEFAULT_DRIVE_PINGROUP(CRT, 0x8ec),
95 DEFAULT_DRIVE_PINGROUP(DDC, 0x8f0),
96 DEFAULT_DRIVE_PINGROUP(GMA, 0x8f4),
97 DEFAULT_DRIVE_PINGROUP(GMB, 0x8f8),
98 DEFAULT_DRIVE_PINGROUP(GMC, 0x8fc),
99 DEFAULT_DRIVE_PINGROUP(GMD, 0x900),
100 DEFAULT_DRIVE_PINGROUP(GME, 0x904),
101 DEFAULT_DRIVE_PINGROUP(OWR, 0x908),
102 DEFAULT_DRIVE_PINGROUP(UAD, 0x90c),
103};
104
105#define PINGROUP(pg_name, gpio_nr, vdd, f0, f1, f2, f3, f_safe, \
106 tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
107 [TEGRA_PINGROUP_ ## pg_name] = { \
108 .name = #pg_name, \
109 .vddio = TEGRA_VDDIO_ ## vdd, \
110 .funcs = { \
111 TEGRA_MUX_ ## f0, \
112 TEGRA_MUX_ ## f1, \
113 TEGRA_MUX_ ## f2, \
114 TEGRA_MUX_ ## f3, \
115 }, \
116 .gpionr = TEGRA_GPIO_ ## gpio_nr, \
117 .func_safe = TEGRA_MUX_ ## f_safe, \
118 .tri_reg = tri_r, \
119 .tri_bit = tri_b, \
120 .mux_reg = mux_r, \
121 .mux_bit = mux_b, \
122 .pupd_reg = pupd_r, \
123 .pupd_bit = pupd_b, \
124 .io_default = 0, \
125 .od_bit = -1, \
126 .lock_bit = -1, \
127 .ioreset_bit = -1, \
128}
129
130#define PINGROUPS \
131 /* pg_name,gpio_nr, vdd, f0, f1, f2, f3, f_safe, tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b*/\
132 PINGROUP(ATA, PI3, NAND, IDE, NAND, GMI, RSVD, IDE, 0x14, 0, 0x80, 24, 0xA0, 0),\
133 PINGROUP(ATB, PI2, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xA0, 2),\
134 PINGROUP(ATC, PI5, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xA0, 4),\
135 PINGROUP(ATD, PH0, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 3, 0x80, 20, 0xA0, 6),\
136 PINGROUP(ATE, PH4, NAND, IDE, NAND, GMI, RSVD, IDE, 0x18, 25, 0x80, 12, 0xA0, 8),\
137 PINGROUP(CDEV1, PW4, AUDIO, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC, 0x14, 4, 0x88, 2, 0xA8, 0),\
138 PINGROUP(CDEV2, PW5, AUDIO, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC, 0x14, 5, 0x88, 4, 0xA8, 2),\
139 PINGROUP(CRTP, INVALID, LCD, CRT, RSVD, RSVD, RSVD, RSVD, 0x20, 14, 0x98, 20, 0xA4, 24),\
140 PINGROUP(CSUS, PT1, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6, 0x88, 6, 0xAC, 24),\
141 PINGROUP(DAP1, PN0, AUDIO, DAP1, RSVD, GMI, SDIO2, DAP1, 0x14, 7, 0x88, 20, 0xA0, 10),\
142 PINGROUP(DAP2, PA2, AUDIO, DAP2, TWC, RSVD, GMI, DAP2, 0x14, 8, 0x88, 22, 0xA0, 12),\
143 PINGROUP(DAP3, PP0, BB, DAP3, RSVD, RSVD, RSVD, DAP3, 0x14, 9, 0x88, 24, 0xA0, 14),\
144 PINGROUP(DAP4, PP4, UART, DAP4, RSVD, GMI, RSVD, DAP4, 0x14, 10, 0x88, 26, 0xA0, 16),\
145 PINGROUP(DDC, INVALID, LCD, I2C2, RSVD, RSVD, RSVD, RSVD, 0x18, 31, 0x88, 0, 0xB0, 28),\
146 PINGROUP(DTA, PT4, VI, RSVD, SDIO2, VI, RSVD, RSVD4, 0x14, 11, 0x84, 20, 0xA0, 18),\
147 PINGROUP(DTB, PT2, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 12, 0x84, 22, 0xA0, 20),\
148 PINGROUP(DTC, PD6, VI, RSVD, RSVD, VI, RSVD, RSVD1, 0x14, 13, 0x84, 26, 0xA0, 22),\
149 PINGROUP(DTD, PT0, VI, RSVD, SDIO2, VI, RSVD, RSVD1, 0x14, 14, 0x84, 28, 0xA0, 24),\
150 PINGROUP(DTE, PBB1, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 15, 0x84, 30, 0xA0, 26),\
151 PINGROUP(DTF, PBB2, VI, I2C3, RSVD, VI, RSVD, RSVD4, 0x20, 12, 0x98, 30, 0xA0, 28),\
152 PINGROUP(GMA, PAA0, NAND, UARTE, SPI3, GMI, SDIO4, SPI3, 0x14, 28, 0x84, 0, 0xB0, 20),\
153 PINGROUP(GMB, PC7, NAND, IDE, NAND, GMI, GMI_INT, GMI, 0x18, 29, 0x88, 28, 0xB0, 22),\
154 PINGROUP(GMC, PJ7, NAND, UARTD, SPI4, GMI, SFLASH, SPI4, 0x14, 29, 0x84, 2, 0xB0, 24),\
155 PINGROUP(GMD, PJ0, NAND, RSVD, NAND, GMI, SFLASH, GMI, 0x18, 30, 0x88, 30, 0xB0, 26),\
156 PINGROUP(GME, PAA4, NAND, RSVD, DAP5, GMI, SDIO4, GMI, 0x18, 0, 0x8C, 0, 0xA8, 24),\
157 PINGROUP(GPU, PU0, UART, PWM, UARTA, GMI, RSVD, RSVD4, 0x14, 16, 0x8C, 4, 0xA4, 20),\
158 PINGROUP(GPU7, PU7, SYS, RTCK, RSVD, RSVD, RSVD, RTCK, 0x20, 11, 0x98, 28, 0xA4, 6),\
159 PINGROUP(GPV, PV4, SD, PCIE, RSVD, RSVD, RSVD, PCIE, 0x14, 17, 0x8C, 2, 0xA0, 30),\
160 PINGROUP(HDINT, PN7, LCD, HDMI, RSVD, RSVD, RSVD, HDMI, 0x1C, 23, 0x84, 4, 0xAC, 22),\
161 PINGROUP(I2CP, PZ6, SYS, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 18, 0x88, 8, 0xA4, 2),\
162 PINGROUP(IRRX, PJ6, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 20, 0x88, 18, 0xA8, 22),\
163 PINGROUP(IRTX, PJ5, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 19, 0x88, 16, 0xA8, 20),\
164 PINGROUP(KBCA, PR0, SYS, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC, 0x14, 22, 0x88, 10, 0xA4, 8),\
165 PINGROUP(KBCB, PR7, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x14, 21, 0x88, 12, 0xA4, 10),\
166 PINGROUP(KBCC, PQ0, SYS, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC, 0x18, 26, 0x88, 14, 0xA4, 12),\
167 PINGROUP(KBCD, PR3, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x20, 10, 0x98, 26, 0xA4, 14),\
168 PINGROUP(KBCE, PQ7, SYS, KBC, NAND, OWR, RSVD, KBC, 0x14, 26, 0x80, 28, 0xB0, 2),\
169 PINGROUP(KBCF, PQ2, SYS, KBC, NAND, TRACE, MIO, KBC, 0x14, 27, 0x80, 26, 0xB0, 0),\
170 PINGROUP(LCSN, PN4, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 31, 0x90, 12, 0xAC, 20),\
171 PINGROUP(LD0, PE0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 0, 0x94, 0, 0xAC, 12),\
172 PINGROUP(LD1, PE1, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 1, 0x94, 2, 0xAC, 12),\
173 PINGROUP(LD10, PF2, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 10, 0x94, 20, 0xAC, 12),\
174 PINGROUP(LD11, PF3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 11, 0x94, 22, 0xAC, 12),\
175 PINGROUP(LD12, PF4, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 12, 0x94, 24, 0xAC, 12),\
176 PINGROUP(LD13, PF5, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 13, 0x94, 26, 0xAC, 12),\
177 PINGROUP(LD14, PF6, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 14, 0x94, 28, 0xAC, 12),\
178 PINGROUP(LD15, PF7, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 15, 0x94, 30, 0xAC, 12),\
179 PINGROUP(LD16, PM0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 16, 0x98, 0, 0xAC, 12),\
180 PINGROUP(LD17, PM1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 17, 0x98, 2, 0xAC, 12),\
181 PINGROUP(LD2, PE2, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 2, 0x94, 4, 0xAC, 12),\
182 PINGROUP(LD3, PE3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 3, 0x94, 6, 0xAC, 12),\
183 PINGROUP(LD4, PE4, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 4, 0x94, 8, 0xAC, 12),\
184 PINGROUP(LD5, PE5, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 5, 0x94, 10, 0xAC, 12),\
185 PINGROUP(LD6, PE6, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 6, 0x94, 12, 0xAC, 12),\
186 PINGROUP(LD7, PE7, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 7, 0x94, 14, 0xAC, 12),\
187 PINGROUP(LD8, PF0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 8, 0x94, 16, 0xAC, 12),\
188 PINGROUP(LD9, PF1, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 9, 0x94, 18, 0xAC, 12),\
189 PINGROUP(LDC, PN6, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 30, 0x90, 14, 0xAC, 20),\
190 PINGROUP(LDI, PM6, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 6, 0x98, 16, 0xAC, 18),\
191 PINGROUP(LHP0, PM5, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 18, 0x98, 10, 0xAC, 16),\
192 PINGROUP(LHP1, PM2, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 19, 0x98, 4, 0xAC, 14),\
193 PINGROUP(LHP2, PM3, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 20, 0x98, 6, 0xAC, 14),\
194 PINGROUP(LHS, PJ3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x20, 7, 0x90, 22, 0xAC, 22),\
195 PINGROUP(LM0, PW0, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 24, 0x90, 26, 0xAC, 22),\
196 PINGROUP(LM1, PW1, LCD, DISPLAYA, DISPLAYB, RSVD, CRT, RSVD3, 0x1C, 25, 0x90, 28, 0xAC, 22),\
197 PINGROUP(LPP, PM7, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 8, 0x98, 14, 0xAC, 18),\
198 PINGROUP(LPW0, PB2, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, 0xAC, 20),\
199 PINGROUP(LPW1, PC1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 4, 0x90, 2, 0xAC, 20),\
200 PINGROUP(LPW2, PC6, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, 0xAC, 20),\
201 PINGROUP(LSC0, PB3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 27, 0x90, 18, 0xAC, 22),\
202 PINGROUP(LSC1, PZ3, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 28, 0x90, 20, 0xAC, 20),\
203 PINGROUP(LSCK, PZ4, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 29, 0x90, 16, 0xAC, 20),\
204 PINGROUP(LSDA, PN5, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 1, 0x90, 8, 0xAC, 20),\
205 PINGROUP(LSDI, PZ2, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, DISPLAYA, 0x20, 2, 0x90, 6, 0xAC, 20),\
206 PINGROUP(LSPI, PJ1, LCD, DISPLAYA, DISPLAYB, XIO, HDMI, DISPLAYA, 0x20, 0, 0x90, 10, 0xAC, 22),\
207 PINGROUP(LVP0, PV7, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 21, 0x90, 30, 0xAC, 22),\
208 PINGROUP(LVP1, PM4, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 22, 0x98, 8, 0xAC, 16),\
209 PINGROUP(LVS, PJ4, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 26, 0x90, 24, 0xAC, 22),\
210 PINGROUP(OWC, INVALID, SYS, OWR, RSVD, RSVD, RSVD, OWR, 0x14, 31, 0x84, 8, 0xB0, 30),\
211 PINGROUP(PMC, PBB0, SYS, PWR_ON, PWR_INTR, RSVD, RSVD, PWR_ON, 0x14, 23, 0x98, 18, -1, -1),\
212 PINGROUP(PTA, PT5, NAND, I2C2, HDMI, GMI, RSVD, RSVD, 0x14, 24, 0x98, 22, 0xA4, 4),\
213 PINGROUP(RM, PC5, UART, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 25, 0x80, 14, 0xA4, 0),\
214 PINGROUP(SDB, PA7, SD, UARTA, PWM, SDIO3, SPI2, PWM, 0x20, 15, 0x8C, 10, -1, -1),\
215 PINGROUP(SDC, PB7, SD, PWM, TWC, SDIO3, SPI3, TWC, 0x18, 1, 0x8C, 12, 0xAC, 28),\
216 PINGROUP(SDD, PA6, SD, UARTA, PWM, SDIO3, SPI3, PWM, 0x18, 2, 0x8C, 14, 0xAC, 30),\
217 PINGROUP(SDIO1, PZ0, BB, SDIO1, RSVD, UARTE, UARTA, RSVD2, 0x14, 30, 0x80, 30, 0xB0, 18),\
218 PINGROUP(SLXA, PD1, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 3, 0x84, 6, 0xA4, 22),\
219 PINGROUP(SLXC, PD3, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 5, 0x84, 10, 0xA4, 26),\
220 PINGROUP(SLXD, PD4, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 6, 0x84, 12, 0xA4, 28),\
221 PINGROUP(SLXK, PD0, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 7, 0x84, 14, 0xA4, 30),\
222 PINGROUP(SPDI, PK6, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 8, 0x8C, 8, 0xA4, 16),\
223 PINGROUP(SPDO, PK5, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 9, 0x8C, 6, 0xA4, 18),\
224 PINGROUP(SPIA, PX0, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 10, 0x8C, 30, 0xA8, 4),\
225 PINGROUP(SPIB, PX1, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 11, 0x8C, 28, 0xA8, 6),\
226 PINGROUP(SPIC, PX2, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 12, 0x8C, 26, 0xA8, 8),\
227 PINGROUP(SPID, PX4, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 13, 0x8C, 24, 0xA8, 10),\
228 PINGROUP(SPIE, PX5, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 14, 0x8C, 22, 0xA8, 12),\
229 PINGROUP(SPIF, PX7, AUDIO, SPI3, SPI1, SPI2, RSVD, RSVD4, 0x18, 15, 0x8C, 20, 0xA8, 14),\
230 PINGROUP(SPIG, PW2, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 16, 0x8C, 18, 0xA8, 16),\
231 PINGROUP(SPIH, PW3, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 17, 0x8C, 16, 0xA8, 18),\
232 PINGROUP(UAA, PO1, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 18, 0x80, 0, 0xAC, 0),\
233 PINGROUP(UAB, PO5, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 19, 0x80, 2, 0xAC, 2),\
234 PINGROUP(UAC, PV0, BB, OWR, RSVD, RSVD, RSVD, RSVD4, 0x18, 20, 0x80, 4, 0xAC, 4),\
235 PINGROUP(UAD, PC2, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF, 0x18, 21, 0x80, 6, 0xAC, 6),\
236 PINGROUP(UCA, PW6, UART, UARTC, RSVD, GMI, RSVD, RSVD4, 0x18, 22, 0x84, 16, 0xAC, 8),\
237 PINGROUP(UCB, PC0, UART, UARTC, PWM, GMI, RSVD, RSVD4, 0x18, 23, 0x84, 18, 0xAC, 10),\
238 PINGROUP(UDA, PY0, BB, SPI1, RSVD, UARTD, ULPI, RSVD2, 0x20, 13, 0x80, 8, 0xB0, 16),\
239 /* these pin groups only have pullup and pull down control */\
240 PINGROUP(CK32, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 14),\
241 PINGROUP(DDRC, INVALID, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xAC, 26),\
242 PINGROUP(PMCA, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 4),\
243 PINGROUP(PMCB, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 6),\
244 PINGROUP(PMCC, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 8),\
245 PINGROUP(PMCD, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 10),\
246 PINGROUP(PMCE, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 12),\
247 PINGROUP(XM2C, INVALID, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30),\
248 PINGROUP(XM2D, INVALID, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28),\
249 /* END OF LIST */
250
251const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
252 PINGROUPS
253};
254
255#undef PINGROUP
256
257#define PINGROUP(pg_name, gpio_nr, vdd, f0, f1, f2, f3, f_safe, \
258 tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
259 [TEGRA_GPIO_##gpio_nr] = TEGRA_PINGROUP_ ##pg_name\
260
261const int gpio_to_pingroup[TEGRA_MAX_GPIO] = {
262 PINGROUPS
263};
264
265#ifdef CONFIG_PM_SLEEP
266#define TRISTATE_REG_A 0x14
267#define TRISTATE_REG_NUM 4
268#define PIN_MUX_CTL_REG_A 0x80
269#define PIN_MUX_CTL_REG_NUM 8
270#define PULLUPDOWN_REG_A 0xa0
271#define PULLUPDOWN_REG_NUM 5
272
273static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM +
274 PULLUPDOWN_REG_NUM +
275 ARRAY_SIZE(tegra_soc_drive_pingroups)];
276
277static inline unsigned long pg_readl(unsigned long offset)
278{
279 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
280}
281
282static inline void pg_writel(unsigned long value, unsigned long offset)
283{
284 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
285}
286
287static int tegra_pinmux_suspend(void)
288{
289 unsigned int i;
290 u32 *ctx = pinmux_reg;
291
292 for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
293 *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4);
294
295 for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
296 *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4);
297
298 for (i = 0; i < TRISTATE_REG_NUM; i++)
299 *ctx++ = pg_readl(TRISTATE_REG_A + i*4);
300
301 for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
302 *ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg);
303
304 return 0;
305}
306
307static void tegra_pinmux_resume(void)
308{
309 unsigned int i;
310 u32 *ctx = pinmux_reg;
311
312 for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
313 pg_writel(*ctx++, PIN_MUX_CTL_REG_A + i*4);
314
315 for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
316 pg_writel(*ctx++, PULLUPDOWN_REG_A + i*4);
317
318 for (i = 0; i < TRISTATE_REG_NUM; i++)
319 pg_writel(*ctx++, TRISTATE_REG_A + i*4);
320
321 for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
322 pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg);
323}
324
325static struct syscore_ops tegra_pinmux_syscore_ops = {
326 .suspend = tegra_pinmux_suspend,
327 .resume = tegra_pinmux_resume,
328};
329
330void __init tegra_init_pinmux(void)
331{
332 register_syscore_ops(&tegra_pinmux_syscore_ops);
333}
334#else
335void __init tegra_init_pinmux(void)
336{
337}
338#endif
diff --git a/arch/arm/mach-tegra/pinmux-t3-tables.c b/arch/arm/mach-tegra/pinmux-t3-tables.c
new file mode 100644
index 00000000000..282a34bdd0d
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux-t3-tables.c
@@ -0,0 +1,479 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux-t3-tables.c
3 *
4 * Common pinmux configurations for Tegra 3 SoCs
5 *
6 * Copyright (C) 2010-2011 NVIDIA Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/errno.h>
25#include <linux/spinlock.h>
26#include <linux/io.h>
27#include <linux/init.h>
28#include <linux/string.h>
29#include <linux/syscore_ops.h>
30
31#include <mach/iomap.h>
32#include <mach/pinmux.h>
33#include "gpio-names.h"
34
35#define SET_DRIVE_PINGROUP(pg_name, r, drv_down_offset, drv_down_mask, drv_up_offset, drv_up_mask, \
36 slew_rise_offset, slew_rise_mask, slew_fall_offset, slew_fall_mask) \
37 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
38 .name = #pg_name, \
39 .reg = r, \
40 .drvup_offset = drv_up_offset, \
41 .drvup_mask = drv_up_mask, \
42 .drvdown_offset = drv_down_offset, \
43 .drvdown_mask = drv_down_mask, \
44 .slewrise_offset = slew_rise_offset, \
45 .slewrise_mask = slew_rise_mask, \
46 .slewfall_offset = slew_fall_offset, \
47 .slewfall_mask = slew_fall_mask, \
48 }
49
50#define DEFAULT_DRIVE_PINGROUP(pg_name, r) \
51 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
52 .name = #pg_name, \
53 .reg = r, \
54 .drvup_offset = 20, \
55 .drvup_mask = 0x1f, \
56 .drvdown_offset = 12, \
57 .drvdown_mask = 0x1f, \
58 .slewrise_offset = 28, \
59 .slewrise_mask = 0x3, \
60 .slewfall_offset = 30, \
61 .slewfall_mask = 0x3, \
62 }
63
64const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
65 DEFAULT_DRIVE_PINGROUP(AO1, 0x868),
66 DEFAULT_DRIVE_PINGROUP(AO2, 0x86c),
67 DEFAULT_DRIVE_PINGROUP(AT1, 0x870),
68 DEFAULT_DRIVE_PINGROUP(AT2, 0x874),
69 DEFAULT_DRIVE_PINGROUP(AT3, 0x878),
70 DEFAULT_DRIVE_PINGROUP(AT4, 0x87c),
71 DEFAULT_DRIVE_PINGROUP(AT5, 0x880),
72 DEFAULT_DRIVE_PINGROUP(CDEV1, 0x884),
73 DEFAULT_DRIVE_PINGROUP(CDEV2, 0x888),
74 DEFAULT_DRIVE_PINGROUP(CSUS, 0x88c),
75 DEFAULT_DRIVE_PINGROUP(DAP1, 0x890),
76 DEFAULT_DRIVE_PINGROUP(DAP2, 0x894),
77 DEFAULT_DRIVE_PINGROUP(DAP3, 0x898),
78 DEFAULT_DRIVE_PINGROUP(DAP4, 0x89c),
79 DEFAULT_DRIVE_PINGROUP(DBG, 0x8a0),
80 DEFAULT_DRIVE_PINGROUP(LCD1, 0x8a4),
81 DEFAULT_DRIVE_PINGROUP(LCD2, 0x8a8),
82 SET_DRIVE_PINGROUP(SDIO2, 0x8ac, 12, 0x7f, 20, 0x7f,
83 28, 0x3, 30, 0x3),
84 SET_DRIVE_PINGROUP(SDIO3, 0x8b0, 12, 0x7f, 20, 0x7f,
85 28, 0x3, 30, 0x3),
86 DEFAULT_DRIVE_PINGROUP(SPI, 0x8b4),
87 DEFAULT_DRIVE_PINGROUP(UAA, 0x8b8),
88 DEFAULT_DRIVE_PINGROUP(UAB, 0x8bc),
89 DEFAULT_DRIVE_PINGROUP(UART2, 0x8c0),
90 DEFAULT_DRIVE_PINGROUP(UART3, 0x8c4),
91 DEFAULT_DRIVE_PINGROUP(VI1, 0x8c8),
92 SET_DRIVE_PINGROUP(SDIO1, 0x8ec, 12, 0x7f, 20, 0x7f,
93 28, 0x3, 30, 0x3),
94 DEFAULT_DRIVE_PINGROUP(CRT, 0x8f8),
95 DEFAULT_DRIVE_PINGROUP(DDC, 0x8fc),
96 SET_DRIVE_PINGROUP(GMA, 0x900, 14, 0x1f, 19, 0x1f,
97 24, 0xf, 28, 0xf),
98 SET_DRIVE_PINGROUP(GMB, 0x904, 14, 0x1f, 19, 0x1f,
99 24, 0xf, 28, 0xf),
100 SET_DRIVE_PINGROUP(GMC, 0x908, 14, 0x1f, 19, 0x1f,
101 24, 0xf, 28, 0xf),
102 SET_DRIVE_PINGROUP(GMD, 0x90c, 14, 0x1f, 19, 0x1f,
103 24, 0xf, 28, 0xf),
104 DEFAULT_DRIVE_PINGROUP(GME, 0x910),
105 DEFAULT_DRIVE_PINGROUP(GMF, 0x914),
106 DEFAULT_DRIVE_PINGROUP(GMG, 0x918),
107 DEFAULT_DRIVE_PINGROUP(GMH, 0x91c),
108 DEFAULT_DRIVE_PINGROUP(OWR, 0x920),
109 DEFAULT_DRIVE_PINGROUP(UAD, 0x924),
110 DEFAULT_DRIVE_PINGROUP(GPV, 0x928),
111 DEFAULT_DRIVE_PINGROUP(DEV3, 0x92c),
112 DEFAULT_DRIVE_PINGROUP(CEC, 0x938),
113};
114
115#define PINGROUP(pg_name, gpio_nr, vdd, f0, f1, f2, f3, fs, iod, reg) \
116 [TEGRA_PINGROUP_ ## pg_name] = { \
117 .name = #pg_name, \
118 .vddio = TEGRA_VDDIO_ ## vdd, \
119 .funcs = { \
120 TEGRA_MUX_ ## f0, \
121 TEGRA_MUX_ ## f1, \
122 TEGRA_MUX_ ## f2, \
123 TEGRA_MUX_ ## f3, \
124 }, \
125 .gpionr = TEGRA_GPIO_ ## gpio_nr, \
126 .func_safe = TEGRA_MUX_ ## fs, \
127 .tri_reg = reg, \
128 .tri_bit = 4, \
129 .mux_reg = reg, \
130 .mux_bit = 0, \
131 .pupd_reg = reg, \
132 .pupd_bit = 2, \
133 .io_default = TEGRA_PIN_ ## iod, \
134 .od_bit = 6, \
135 .lock_bit = 7, \
136 .ioreset_bit = 8, \
137 }
138
139/* !!!FIXME!!! FILL IN fSafe COLUMN IN TABLE ....... */
140
141#define PINGROUPS \
142 /* NAME GPIO VDD f0 f1 f2 f3 fSafe io reg */\
143 PINGROUP(ULPI_DATA0, PO1, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3000),\
144 PINGROUP(ULPI_DATA1, PO2, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3004),\
145 PINGROUP(ULPI_DATA2, PO3, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3008),\
146 PINGROUP(ULPI_DATA3, PO4, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x300c),\
147 PINGROUP(ULPI_DATA4, PO5, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3010),\
148 PINGROUP(ULPI_DATA5, PO6, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3014),\
149 PINGROUP(ULPI_DATA6, PO7, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3018),\
150 PINGROUP(ULPI_DATA7, PO0, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x301c),\
151 PINGROUP(ULPI_CLK, PY0, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3020),\
152 PINGROUP(ULPI_DIR, PY1, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3024),\
153 PINGROUP(ULPI_NXT, PY2, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3028),\
154 PINGROUP(ULPI_STP, PY3, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x302c),\
155 PINGROUP(DAP3_FS, PP0, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3030),\
156 PINGROUP(DAP3_DIN, PP1, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3034),\
157 PINGROUP(DAP3_DOUT, PP2, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3038),\
158 PINGROUP(DAP3_SCLK, PP3, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x303c),\
159 PINGROUP(GPIO_PV0, PV0, BB, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3040),\
160 PINGROUP(GPIO_PV1, PV1, BB, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3044),\
161 PINGROUP(SDMMC1_CLK, PZ0, SDMMC1, SDMMC1, RSVD1, RSVD2, INVALID, RSVD, INPUT, 0x3048),\
162 PINGROUP(SDMMC1_CMD, PZ1, SDMMC1, SDMMC1, RSVD1, RSVD2, INVALID, RSVD, INPUT, 0x304c),\
163 PINGROUP(SDMMC1_DAT3, PY4, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3050),\
164 PINGROUP(SDMMC1_DAT2, PY5, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3054),\
165 PINGROUP(SDMMC1_DAT1, PY6, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3058),\
166 PINGROUP(SDMMC1_DAT0, PY7, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x305c),\
167 PINGROUP(GPIO_PV2, PV2, SDMMC1, OWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3060),\
168 PINGROUP(GPIO_PV3, PV3, SDMMC1, INVALID, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3064),\
169 PINGROUP(CLK2_OUT, PW5, SDMMC1, EXTPERIPH2, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3068),\
170 PINGROUP(CLK2_REQ, PCC5, SDMMC1, DAP, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x306c),\
171 PINGROUP(LCD_PWR1, PC1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3070),\
172 PINGROUP(LCD_PWR2, PC6, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3074),\
173 PINGROUP(LCD_SDIN, PZ2, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, RSVD, OUTPUT, 0x3078),\
174 PINGROUP(LCD_SDOUT, PN5, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x307c),\
175 PINGROUP(LCD_WR_N, PZ3, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3080),\
176 PINGROUP(LCD_CS0_N, PN4, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, RSVD, OUTPUT, 0x3084),\
177 PINGROUP(LCD_DC0, PN6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3088),\
178 PINGROUP(LCD_SCK, PZ4, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x308c),\
179 PINGROUP(LCD_PWR0, PB2, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3090),\
180 PINGROUP(LCD_PCLK, PB3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3094),\
181 PINGROUP(LCD_DE, PJ1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3098),\
182 PINGROUP(LCD_HSYNC, PJ3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x309c),\
183 PINGROUP(LCD_VSYNC, PJ4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a0),\
184 PINGROUP(LCD_D0, PE0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a4),\
185 PINGROUP(LCD_D1, PE1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a8),\
186 PINGROUP(LCD_D2, PE2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30ac),\
187 PINGROUP(LCD_D3, PE3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b0),\
188 PINGROUP(LCD_D4, PE4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b4),\
189 PINGROUP(LCD_D5, PE5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b8),\
190 PINGROUP(LCD_D6, PE6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30bc),\
191 PINGROUP(LCD_D7, PE7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c0),\
192 PINGROUP(LCD_D8, PF0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c4),\
193 PINGROUP(LCD_D9, PF1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c8),\
194 PINGROUP(LCD_D10, PF2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30cc),\
195 PINGROUP(LCD_D11, PF3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d0),\
196 PINGROUP(LCD_D12, PF4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d4),\
197 PINGROUP(LCD_D13, PF5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d8),\
198 PINGROUP(LCD_D14, PF6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30dc),\
199 PINGROUP(LCD_D15, PF7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e0),\
200 PINGROUP(LCD_D16, PM0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e4),\
201 PINGROUP(LCD_D17, PM1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e8),\
202 PINGROUP(LCD_D18, PM2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30ec),\
203 PINGROUP(LCD_D19, PM3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f0),\
204 PINGROUP(LCD_D20, PM4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f4),\
205 PINGROUP(LCD_D21, PM5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f8),\
206 PINGROUP(LCD_D22, PM6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30fc),\
207 PINGROUP(LCD_D23, PM7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3100),\
208 PINGROUP(LCD_CS1_N, PW0, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD2, RSVD, OUTPUT, 0x3104),\
209 PINGROUP(LCD_M1, PW1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3108),\
210 PINGROUP(LCD_DC1, PD2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x310c),\
211 PINGROUP(HDMI_INT, PN7, LCD, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3110),\
212 PINGROUP(DDC_SCL, PV4, LCD, I2C4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3114),\
213 PINGROUP(DDC_SDA, PV5, LCD, I2C4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3118),\
214 PINGROUP(CRT_HSYNC, PV6, LCD, CRT, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x311c),\
215 PINGROUP(CRT_VSYNC, PV7, LCD, CRT, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3120),\
216 PINGROUP(VI_D0, PT4, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3124),\
217 PINGROUP(VI_D1, PD5, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3128),\
218 PINGROUP(VI_D2, PL0, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x312c),\
219 PINGROUP(VI_D3, PL1, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3130),\
220 PINGROUP(VI_D4, PL2, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3134),\
221 PINGROUP(VI_D5, PL3, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3138),\
222 PINGROUP(VI_D6, PL4, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x313c),\
223 PINGROUP(VI_D7, PL5, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3140),\
224 PINGROUP(VI_D8, PL6, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3144),\
225 PINGROUP(VI_D9, PL7, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3148),\
226 PINGROUP(VI_D10, PT2, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x314c),\
227 PINGROUP(VI_D11, PT3, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3150),\
228 PINGROUP(VI_PCLK, PT0, VI, RSVD1, SDMMC2, VI, RSVD2, RSVD, INPUT, 0x3154),\
229 PINGROUP(VI_MCLK, PT1, VI, INVALID, INVALID, INVALID, VI, RSVD, INPUT, 0x3158),\
230 PINGROUP(VI_VSYNC, PD6, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x315c),\
231 PINGROUP(VI_HSYNC, PD7, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3160),\
232 PINGROUP(UART2_RXD, PC3, UART, IRDA, SPDIF, UARTA, SPI4, RSVD, INPUT, 0x3164),\
233 PINGROUP(UART2_TXD, PC2, UART, IRDA, SPDIF, UARTA, SPI4, RSVD, INPUT, 0x3168),\
234 PINGROUP(UART2_RTS_N, PJ6, UART, UARTA, UARTB, GMI, SPI4, RSVD, INPUT, 0x316c),\
235 PINGROUP(UART2_CTS_N, PJ5, UART, UARTA, UARTB, GMI, SPI4, RSVD, INPUT, 0x3170),\
236 PINGROUP(UART3_TXD, PW6, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x3174),\
237 PINGROUP(UART3_RXD, PW7, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x3178),\
238 PINGROUP(UART3_CTS_N, PA1, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x317c),\
239 PINGROUP(UART3_RTS_N, PC0, UART, UARTC, PWM0, GMI, RSVD2, RSVD, INPUT, 0x3180),\
240 PINGROUP(GPIO_PU0, PU0, UART, OWR, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3184),\
241 PINGROUP(GPIO_PU1, PU1, UART, RSVD1, UARTA, GMI, RSVD2, RSVD, INPUT, 0x3188),\
242 PINGROUP(GPIO_PU2, PU2, UART, RSVD1, UARTA, GMI, RSVD2, RSVD, INPUT, 0x318c),\
243 PINGROUP(GPIO_PU3, PU3, UART, PWM0, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3190),\
244 PINGROUP(GPIO_PU4, PU4, UART, PWM1, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3194),\
245 PINGROUP(GPIO_PU5, PU5, UART, PWM2, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3198),\
246 PINGROUP(GPIO_PU6, PU6, UART, PWM3, UARTA, GMI, RSVD1, RSVD, INPUT, 0x319c),\
247 PINGROUP(GEN1_I2C_SDA, PC5, UART, I2C1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31a0),\
248 PINGROUP(GEN1_I2C_SCL, PC4, UART, I2C1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31a4),\
249 PINGROUP(DAP4_FS, PP4, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31a8),\
250 PINGROUP(DAP4_DIN, PP5, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31ac),\
251 PINGROUP(DAP4_DOUT, PP6, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31b0),\
252 PINGROUP(DAP4_SCLK, PP7, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31b4),\
253 PINGROUP(CLK3_OUT, PEE0, UART, EXTPERIPH3, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31b8),\
254 PINGROUP(CLK3_REQ, PEE1, UART, DEV3, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31bc),\
255 PINGROUP(GMI_WP_N, PC7, GMI, RSVD1, NAND, GMI, GMI_ALT, RSVD, INPUT, 0x31c0),\
256 PINGROUP(GMI_IORDY, PI5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31c4),\
257 PINGROUP(GMI_WAIT, PI7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31c8),\
258 PINGROUP(GMI_ADV_N, PK0, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31cc),\
259 PINGROUP(GMI_CLK, PK1, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31d0),\
260 PINGROUP(GMI_CS0_N, PJ0, GMI, RSVD1, NAND, GMI, DTV, RSVD, INPUT, 0x31d4),\
261 PINGROUP(GMI_CS1_N, PJ2, GMI, RSVD1, NAND, GMI, DTV, RSVD, INPUT, 0x31d8),\
262 PINGROUP(GMI_CS2_N, PK3, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31dc),\
263 PINGROUP(GMI_CS3_N, PK4, GMI, RSVD1, NAND, GMI, GMI_ALT, RSVD, INPUT, 0x31e0),\
264 PINGROUP(GMI_CS4_N, PK2, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31e4),\
265 PINGROUP(GMI_CS6_N, PI3, GMI, NAND, NAND_ALT, GMI, SATA, RSVD, INPUT, 0x31e8),\
266 PINGROUP(GMI_CS7_N, PI6, GMI, NAND, NAND_ALT, GMI, GMI_ALT, RSVD, INPUT, 0x31ec),\
267 PINGROUP(GMI_AD0, PG0, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f0),\
268 PINGROUP(GMI_AD1, PG1, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f4),\
269 PINGROUP(GMI_AD2, PG2, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f8),\
270 PINGROUP(GMI_AD3, PG3, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31fc),\
271 PINGROUP(GMI_AD4, PG4, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3200),\
272 PINGROUP(GMI_AD5, PG5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3204),\
273 PINGROUP(GMI_AD6, PG6, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3208),\
274 PINGROUP(GMI_AD7, PG7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x320c),\
275 PINGROUP(GMI_AD8, PH0, GMI, PWM0, NAND, GMI, RSVD2, RSVD, INPUT, 0x3210),\
276 PINGROUP(GMI_AD9, PH1, GMI, PWM1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3214),\
277 PINGROUP(GMI_AD10, PH2, GMI, PWM2, NAND, GMI, RSVD2, RSVD, INPUT, 0x3218),\
278 PINGROUP(GMI_AD11, PH3, GMI, PWM3, NAND, GMI, RSVD2, RSVD, INPUT, 0x321c),\
279 PINGROUP(GMI_AD12, PH4, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3220),\
280 PINGROUP(GMI_AD13, PH5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3224),\
281 PINGROUP(GMI_AD14, PH6, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3228),\
282 PINGROUP(GMI_AD15, PH7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x322c),\
283 PINGROUP(GMI_A16, PJ7, GMI, UARTD, SPI4, GMI, GMI_ALT, RSVD, INPUT, 0x3230),\
284 PINGROUP(GMI_A17, PB0, GMI, UARTD, SPI4, GMI, DTV, RSVD, INPUT, 0x3234),\
285 PINGROUP(GMI_A18, PB1, GMI, UARTD, SPI4, GMI, DTV, RSVD, INPUT, 0x3238),\
286 PINGROUP(GMI_A19, PK7, GMI, UARTD, SPI4, GMI, RSVD3, RSVD, INPUT, 0x323c),\
287 PINGROUP(GMI_WR_N, PI0, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3240),\
288 PINGROUP(GMI_OE_N, PI1, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3244),\
289 PINGROUP(GMI_DQS, PI2, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3248),\
290 PINGROUP(GMI_RST_N, PI4, GMI, NAND, NAND_ALT, GMI, RSVD3, RSVD, INPUT, 0x324c),\
291 PINGROUP(GEN2_I2C_SCL, PT5, GMI, I2C2, INVALID, GMI, RSVD3, RSVD, INPUT, 0x3250),\
292 PINGROUP(GEN2_I2C_SDA, PT6, GMI, I2C2, INVALID, GMI, RSVD3, RSVD, INPUT, 0x3254),\
293 PINGROUP(SDMMC4_CLK, PCC4, SDMMC4, INVALID, NAND, GMI, SDMMC4, RSVD, INPUT, 0x3258),\
294 PINGROUP(SDMMC4_CMD, PT7, SDMMC4, I2C3, NAND, GMI, SDMMC4, RSVD, INPUT, 0x325c),\
295 PINGROUP(SDMMC4_DAT0, PAA0, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x3260),\
296 PINGROUP(SDMMC4_DAT1, PAA1, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x3264),\
297 PINGROUP(SDMMC4_DAT2, PAA2, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x3268),\
298 PINGROUP(SDMMC4_DAT3, PAA3, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x326c),\
299 PINGROUP(SDMMC4_DAT4, PAA4, SDMMC4, I2C3, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x3270),\
300 PINGROUP(SDMMC4_DAT5, PAA5, SDMMC4, VGP3, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x3274),\
301 PINGROUP(SDMMC4_DAT6, PAA6, SDMMC4, VGP4, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x3278),\
302 PINGROUP(SDMMC4_DAT7, PAA7, SDMMC4, VGP5, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x327c),\
303 PINGROUP(SDMMC4_RST_N, PCC3, SDMMC4, VGP6, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3280),\
304 PINGROUP(CAM_MCLK, PCC0, CAM, VI, INVALID, VI_ALT2, POPSDMMC4, RSVD, INPUT, 0x3284),\
305 PINGROUP(GPIO_PCC1, PCC1, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3288),\
306 PINGROUP(GPIO_PBB0, PBB0, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x328c),\
307 PINGROUP(CAM_I2C_SCL, PBB1, CAM, INVALID, I2C3, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3290),\
308 PINGROUP(CAM_I2C_SDA, PBB2, CAM, INVALID, I2C3, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3294),\
309 PINGROUP(GPIO_PBB3, PBB3, CAM, VGP3, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x3298),\
310 PINGROUP(GPIO_PBB4, PBB4, CAM, VGP4, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x329c),\
311 PINGROUP(GPIO_PBB5, PBB5, CAM, VGP5, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x32a0),\
312 PINGROUP(GPIO_PBB6, PBB6, CAM, VGP6, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x32a4),\
313 PINGROUP(GPIO_PBB7, PBB7, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x32a8),\
314 PINGROUP(GPIO_PCC2, PCC2, CAM, I2S4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32ac),\
315 PINGROUP(JTAG_RTCK, PU7, SYS, RTCK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b0),\
316 PINGROUP(PWR_I2C_SCL, PZ6, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b4),\
317 PINGROUP(PWR_I2C_SDA, PZ7, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b8),\
318 PINGROUP(KB_ROW0, PR0, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32bc),\
319 PINGROUP(KB_ROW1, PR1, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32c0),\
320 PINGROUP(KB_ROW2, PR2, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32c4),\
321 PINGROUP(KB_ROW3, PR3, SYS, KBC, INVALID, RSVD2, INVALID, RSVD, INPUT, 0x32c8),\
322 PINGROUP(KB_ROW4, PR4, SYS, KBC, INVALID, TRACE, RSVD3, RSVD, INPUT, 0x32cc),\
323 PINGROUP(KB_ROW5, PR5, SYS, KBC, INVALID, TRACE, OWR, RSVD, INPUT, 0x32d0),\
324 PINGROUP(KB_ROW6, PR6, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32d4),\
325 PINGROUP(KB_ROW7, PR7, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32d8),\
326 PINGROUP(KB_ROW8, PS0, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32dc),\
327 PINGROUP(KB_ROW9, PS1, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32e0),\
328 PINGROUP(KB_ROW10, PS2, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32e4),\
329 PINGROUP(KB_ROW11, PS3, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32e8),\
330 PINGROUP(KB_ROW12, PS4, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32ec),\
331 PINGROUP(KB_ROW13, PS5, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32f0),\
332 PINGROUP(KB_ROW14, PS6, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32f4),\
333 PINGROUP(KB_ROW15, PS7, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32f8),\
334 PINGROUP(KB_COL0, PQ0, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x32fc),\
335 PINGROUP(KB_COL1, PQ1, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3300),\
336 PINGROUP(KB_COL2, PQ2, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3304),\
337 PINGROUP(KB_COL3, PQ3, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3308),\
338 PINGROUP(KB_COL4, PQ4, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x330c),\
339 PINGROUP(KB_COL5, PQ5, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3310),\
340 PINGROUP(KB_COL6, PQ6, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3314),\
341 PINGROUP(KB_COL7, PQ7, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3318),\
342 PINGROUP(CLK_32K_OUT, PA0, SYS, BLINK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x331c),\
343 PINGROUP(SYS_CLK_REQ, PZ5, SYS, SYSCLK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3320),\
344 PINGROUP(CORE_PWR_REQ, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3324),\
345 PINGROUP(CPU_PWR_REQ, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3328),\
346 PINGROUP(PWR_INT_N, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x332c),\
347 PINGROUP(CLK_32K_IN, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3330),\
348 PINGROUP(OWR, INVALID, SYS, OWR, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3334),\
349 PINGROUP(DAP1_FS, PN0, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x3338),\
350 PINGROUP(DAP1_DIN, PN1, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x333c),\
351 PINGROUP(DAP1_DOUT, PN2, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x3340),\
352 PINGROUP(DAP1_SCLK, PN3, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x3344),\
353 PINGROUP(CLK1_REQ, PEE2, AUDIO, DAP, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x3348),\
354 PINGROUP(CLK1_OUT, PW4, AUDIO, EXTPERIPH1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x334c),\
355 PINGROUP(SPDIF_IN, PK6, AUDIO, SPDIF, HDA, INVALID, DAPSDMMC2, RSVD, INPUT, 0x3350),\
356 PINGROUP(SPDIF_OUT, PK5, AUDIO, SPDIF, RSVD1, INVALID, DAPSDMMC2, RSVD, INPUT, 0x3354),\
357 PINGROUP(DAP2_FS, PA2, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3358),\
358 PINGROUP(DAP2_DIN, PA4, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x335c),\
359 PINGROUP(DAP2_DOUT, PA5, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3360),\
360 PINGROUP(DAP2_SCLK, PA3, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3364),\
361 PINGROUP(SPI2_MOSI, PX0, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3368),\
362 PINGROUP(SPI2_MISO, PX1, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x336c),\
363 PINGROUP(SPI2_CS0_N, PX3, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3370),\
364 PINGROUP(SPI2_SCK, PX2, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3374),\
365 PINGROUP(SPI1_MOSI, PX4, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x3378),\
366 PINGROUP(SPI1_SCK, PX5, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x337c),\
367 PINGROUP(SPI1_CS0_N, PX6, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x3380),\
368 PINGROUP(SPI1_MISO, PX7, AUDIO, INVALID, SPI1, INVALID, RSVD3, RSVD, INPUT, 0x3384),\
369 PINGROUP(SPI2_CS1_N, PW2, AUDIO, INVALID, SPI2, INVALID, INVALID, RSVD, INPUT, 0x3388),\
370 PINGROUP(SPI2_CS2_N, PW3, AUDIO, INVALID, SPI2, INVALID, INVALID, RSVD, INPUT, 0x338c),\
371 PINGROUP(SDMMC3_CLK, PA6, SDMMC3, UARTA, PWM2, SDMMC3, INVALID, RSVD, INPUT, 0x3390),\
372 PINGROUP(SDMMC3_CMD, PA7, SDMMC3, UARTA, PWM3, SDMMC3, INVALID, RSVD, INPUT, 0x3394),\
373 PINGROUP(SDMMC3_DAT0, PB7, SDMMC3, RSVD0, RSVD1, SDMMC3, INVALID, RSVD, INPUT, 0x3398),\
374 PINGROUP(SDMMC3_DAT1, PB6, SDMMC3, RSVD0, RSVD1, SDMMC3, INVALID, RSVD, INPUT, 0x339c),\
375 PINGROUP(SDMMC3_DAT2, PB5, SDMMC3, RSVD0, PWM1, SDMMC3, INVALID, RSVD, INPUT, 0x33a0),\
376 PINGROUP(SDMMC3_DAT3, PB4, SDMMC3, RSVD0, PWM0, SDMMC3, INVALID, RSVD, INPUT, 0x33a4),\
377 PINGROUP(SDMMC3_DAT4, PD1, SDMMC3, PWM1, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33a8),\
378 PINGROUP(SDMMC3_DAT5, PD0, SDMMC3, PWM0, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33ac),\
379 PINGROUP(SDMMC3_DAT6, PD3, SDMMC3, SPDIF, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33b0),\
380 PINGROUP(SDMMC3_DAT7, PD4, SDMMC3, SPDIF, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33b4),\
381 PINGROUP(PEX_L0_PRSNT_N, PDD0, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33b8),\
382 PINGROUP(PEX_L0_RST_N, PDD1, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33bc),\
383 PINGROUP(PEX_L0_CLKREQ_N, PDD2, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c0),\
384 PINGROUP(PEX_WAKE_N, PDD3, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c4),\
385 PINGROUP(PEX_L1_PRSNT_N, PDD4, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c8),\
386 PINGROUP(PEX_L1_RST_N, PDD5, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33cc),\
387 PINGROUP(PEX_L1_CLKREQ_N, PDD6, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d0),\
388 PINGROUP(PEX_L2_PRSNT_N, PDD7, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d4),\
389 PINGROUP(PEX_L2_RST_N, PCC6, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d8),\
390 PINGROUP(PEX_L2_CLKREQ_N, PCC7, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33dc),\
391 PINGROUP(HDMI_CEC, PEE3, SYS, CEC, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x33e0),\
392 /* END OF LIST */
393
394const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
395 PINGROUPS
396};
397
398#undef PINGROUP
399
400#define PINGROUP(pg_name, gpio_nr, vdd, f0, f1, f2, f3, fs, iod, reg) \
401 [TEGRA_GPIO_##gpio_nr] = TEGRA_PINGROUP_ ##pg_name\
402
403const int gpio_to_pingroup[TEGRA_MAX_GPIO] = {
404 PINGROUPS
405};
406
407#ifdef CONFIG_PM_SLEEP
408
409static u32 pinmux_reg[TEGRA_MAX_PINGROUP +
410 ARRAY_SIZE(tegra_soc_drive_pingroups)];
411
412static inline unsigned long pg_readl(unsigned long offset)
413{
414 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
415}
416
417static inline void pg_writel(unsigned long value, unsigned long offset)
418{
419 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
420}
421
422static int tegra_pinmux_suspend(void)
423{
424 unsigned int i;
425 u32 *ctx = pinmux_reg;
426
427 for (i = 0; i < TEGRA_MAX_PINGROUP; i++)
428 *ctx++ = pg_readl(tegra_soc_pingroups[i].mux_reg);
429
430 for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
431 *ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg);
432
433 return 0;
434}
435
436static void tegra_pinmux_resume(void)
437{
438 unsigned int i;
439 u32 *ctx = pinmux_reg;
440
441 for (i = 0; i < TEGRA_MAX_PINGROUP; i++)
442 pg_writel(*ctx++, tegra_soc_pingroups[i].mux_reg);
443
444 for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
445 pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg);
446}
447
448static struct syscore_ops tegra_pinmux_syscore_ops = {
449 .suspend = tegra_pinmux_suspend,
450 .resume = tegra_pinmux_resume,
451};
452#endif
453
454#define SET_DRIVE(_name, _hsm, _schmitt, _drive, _pulldn_drive, _pullup_drive, _pulldn_slew, _pullup_slew) \
455 { \
456 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
457 .hsm = TEGRA_HSM_##_hsm, \
458 .schmitt = TEGRA_SCHMITT_##_schmitt, \
459 .drive = TEGRA_DRIVE_##_drive, \
460 .pull_down = TEGRA_PULL_##_pulldn_drive, \
461 .pull_up = TEGRA_PULL_##_pullup_drive, \
462 .slew_rising = TEGRA_SLEW_##_pulldn_slew, \
463 .slew_falling = TEGRA_SLEW_##_pullup_slew, \
464 }
465
466static __initdata struct tegra_drive_pingroup_config t30_def_drive_pinmux[] = {
467 SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
468 SET_DRIVE(DAP1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
469};
470
471void __init tegra_init_pinmux(void)
472{
473#ifdef CONFIG_PM_SLEEP
474 register_syscore_ops(&tegra_pinmux_syscore_ops);
475#endif
476
477 tegra_drive_pinmux_config_table(t30_def_drive_pinmux,
478 ARRAY_SIZE(t30_def_drive_pinmux));
479}
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644
index 00000000000..245aa627fdf
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -0,0 +1,1056 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
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/init.h>
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/spinlock.h>
23#include <linux/io.h>
24
25#include <mach/iomap.h>
26#include <mach/pinmux.h>
27
28#define HSM_EN(reg) (((reg) >> 2) & 0x1)
29#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
30#define LPMD(reg) (((reg) >> 4) & 0x3)
31#define DRVDN(reg, offset) (((reg) >> offset) & 0x1f)
32#define DRVUP(reg, offset) (((reg) >> offset) & 0x1f)
33#define SLWR(reg, offset) (((reg) >> offset) & 0x3)
34#define SLWF(reg, offset) (((reg) >> offset) & 0x3)
35
36static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups;
37static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups;
38static const int *gpio_to_pingroups_map = gpio_to_pingroup;
39
40static char *tegra_mux_names[TEGRA_MAX_MUX] = {
41#define TEGRA_MUX(mux) [TEGRA_MUX_##mux] = #mux,
42 TEGRA_MUX_LIST
43#undef TEGRA_MUX
44 [TEGRA_MUX_SAFE] = "<safe>",
45};
46
47static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
48 [TEGRA_DRIVE_DIV_8] = "DIV_8",
49 [TEGRA_DRIVE_DIV_4] = "DIV_4",
50 [TEGRA_DRIVE_DIV_2] = "DIV_2",
51 [TEGRA_DRIVE_DIV_1] = "DIV_1",
52};
53
54static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
55 [TEGRA_SLEW_FASTEST] = "FASTEST",
56 [TEGRA_SLEW_FAST] = "FAST",
57 [TEGRA_SLEW_SLOW] = "SLOW",
58 [TEGRA_SLEW_SLOWEST] = "SLOWEST",
59};
60
61static DEFINE_SPINLOCK(mux_lock);
62
63static const char *pingroup_name(enum tegra_pingroup pg)
64{
65 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
66 return "<UNKNOWN>";
67
68 return pingroups[pg].name;
69}
70
71static const char *func_name(enum tegra_mux_func func)
72{
73 if (func == TEGRA_MUX_RSVD1)
74 return "RSVD1";
75
76 if (func == TEGRA_MUX_RSVD2)
77 return "RSVD2";
78
79 if (func == TEGRA_MUX_RSVD3)
80 return "RSVD3";
81
82 if (func == TEGRA_MUX_RSVD4)
83 return "RSVD4";
84
85 if (func == TEGRA_MUX_INVALID)
86 return "INVALID";
87
88 if (func < 0 || func >= TEGRA_MAX_MUX)
89 return "<UNKNOWN>";
90
91 return tegra_mux_names[func];
92}
93
94
95static const char *tri_name(unsigned long val)
96{
97 return val ? "TRISTATE" : "NORMAL";
98}
99
100static const char *pupd_name(unsigned long val)
101{
102 switch (val) {
103 case 0:
104 return "NORMAL";
105
106 case 1:
107 return "PULL_DOWN";
108
109 case 2:
110 return "PULL_UP";
111
112 default:
113 return "RSVD";
114 }
115}
116
117#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
118static const char *lock_name(unsigned long val)
119{
120 switch (val) {
121 case TEGRA_PIN_LOCK_DEFAULT:
122 return "LOCK_DEFUALT";
123
124 case TEGRA_PIN_LOCK_DISABLE:
125 return "LOCK_DISABLE";
126
127 case TEGRA_PIN_LOCK_ENABLE:
128 return "LOCK_ENABLE";
129 default:
130 return "LOCK_DEFAULT";
131 }
132}
133
134static const char *od_name(unsigned long val)
135{
136 switch (val) {
137 case TEGRA_PIN_OD_DEFAULT:
138 return "OD_DEFAULT";
139
140 case TEGRA_PIN_OD_DISABLE:
141 return "OD_DISABLE";
142
143 case TEGRA_PIN_OD_ENABLE:
144 return "OD_ENABLE";
145 default:
146 return "OD_DEFAULT";
147 }
148}
149
150static const char *ioreset_name(unsigned long val)
151{
152 switch (val) {
153 case TEGRA_PIN_IO_RESET_DEFAULT:
154 return "IO_RESET_DEFAULT";
155
156 case TEGRA_PIN_IO_RESET_DISABLE:
157 return "IO_RESET_DISABLE";
158
159 case TEGRA_PIN_IO_RESET_ENABLE:
160 return "IO_RESET_ENABLE";
161 default:
162 return "IO_RESET_DEFAULT";
163 }
164}
165#endif
166
167#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
168static const char *io_name(unsigned long val)
169{
170 switch (val) {
171 case 0:
172 return "OUTPUT";
173
174 case 1:
175 return "INPUT";
176
177 default:
178 return "RSVD";
179 }
180}
181#endif
182
183static inline unsigned long pg_readl(unsigned long offset)
184{
185 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
186}
187
188static inline void pg_writel(unsigned long value, unsigned long offset)
189{
190 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
191}
192
193int tegra_pinmux_get_pingroup(int gpio_nr)
194{
195 return gpio_to_pingroups_map[gpio_nr];
196}
197EXPORT_SYMBOL_GPL(tegra_pinmux_get_pingroup);
198
199static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
200{
201 int mux = -1;
202 int i;
203 int find = 0;
204 unsigned long reg;
205 unsigned long flags;
206 enum tegra_pingroup pg = config->pingroup;
207 enum tegra_mux_func func = config->func;
208
209 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
210 return -ERANGE;
211
212 if (pingroups[pg].mux_reg <= 0)
213 return -EINVAL;
214
215 if (func == TEGRA_MUX_INVALID) {
216 pr_err("The pingroup %s is not recommended for option %s\n",
217 pingroup_name(pg), func_name(func));
218 WARN_ON(1);
219 return -EINVAL;
220 }
221
222 if (func < 0)
223 return -ERANGE;
224
225 if (func == TEGRA_MUX_SAFE)
226 func = pingroups[pg].func_safe;
227
228 if (func & TEGRA_MUX_RSVD) {
229 for (i = 0; i < 4; i++) {
230 if (pingroups[pg].funcs[i] & TEGRA_MUX_RSVD)
231 mux = i;
232
233 if (pingroups[pg].funcs[i] == func) {
234 mux = i;
235 find = 1;
236 break;
237 }
238 }
239 } else {
240 for (i = 0; i < 4; i++) {
241 if (pingroups[pg].funcs[i] == func) {
242 mux = i;
243 find = 1;
244 break;
245 }
246 }
247 }
248
249 if (mux < 0) {
250 pr_err("The pingroup %s is not supported option %s\n",
251 pingroup_name(pg), func_name(func));
252 WARN_ON(1);
253 return -EINVAL;
254 }
255
256 if (!find)
257 pr_warn("The pingroup %s was configured to %s instead of %s\n",
258 pingroup_name(pg), func_name(pingroups[pg].funcs[mux]),
259 func_name(func));
260
261 spin_lock_irqsave(&mux_lock, flags);
262
263 reg = pg_readl(pingroups[pg].mux_reg);
264 reg &= ~(0x3 << pingroups[pg].mux_bit);
265 reg |= mux << pingroups[pg].mux_bit;
266#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
267 reg &= ~(0x1 << 5);
268 reg |= ((config->io & 0x1) << 5);
269#endif
270 pg_writel(reg, pingroups[pg].mux_reg);
271
272 spin_unlock_irqrestore(&mux_lock, flags);
273
274 return 0;
275}
276
277int tegra_pinmux_get_func(enum tegra_pingroup pg)
278{
279 int mux = -1;
280 unsigned long reg;
281 unsigned long flags;
282
283 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
284 return -ERANGE;
285
286 if (pingroups[pg].mux_reg <= 0)
287 return -EINVAL;
288
289 spin_lock_irqsave(&mux_lock, flags);
290
291 reg = pg_readl(pingroups[pg].mux_reg);
292 mux = (reg >> pingroups[pg].mux_bit) & 0x3;
293
294 spin_unlock_irqrestore(&mux_lock, flags);
295
296 return mux;
297}
298
299int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
300 enum tegra_tristate tristate)
301{
302 unsigned long reg;
303 unsigned long flags;
304
305 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
306 return -ERANGE;
307
308 if (pingroups[pg].tri_reg <= 0)
309 return -EINVAL;
310
311 spin_lock_irqsave(&mux_lock, flags);
312
313 reg = pg_readl(pingroups[pg].tri_reg);
314 reg &= ~(0x1 << pingroups[pg].tri_bit);
315 if (tristate)
316 reg |= 1 << pingroups[pg].tri_bit;
317 pg_writel(reg, pingroups[pg].tri_reg);
318
319 spin_unlock_irqrestore(&mux_lock, flags);
320
321 return 0;
322}
323
324int tegra_pinmux_set_io(enum tegra_pingroup pg,
325 enum tegra_pin_io input)
326{
327#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
328 unsigned long io;
329
330 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
331 return -ERANGE;
332
333 io = pg_readl(pingroups[pg].mux_reg);
334 if (input)
335 io |= 0x20;
336 else
337 io &= ~(1 << 5);
338 pg_writel(io, pingroups[pg].mux_reg);
339#endif
340 return 0;
341}
342EXPORT_SYMBOL_GPL(tegra_pinmux_set_io);
343
344#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
345static int tegra_pinmux_set_lock(enum tegra_pingroup pg,
346 enum tegra_pin_lock lock)
347{
348 unsigned long reg;
349 unsigned long flags;
350
351 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
352 return -ERANGE;
353
354 if (pingroups[pg].mux_reg <= 0)
355 return -EINVAL;
356
357 if ((lock == TEGRA_PIN_LOCK_DEFAULT) || (pingroups[pg].lock_bit < 0))
358 return 0;
359
360 spin_lock_irqsave(&mux_lock, flags);
361
362 reg = pg_readl(pingroups[pg].mux_reg);
363 reg &= ~(0x1 << pingroups[pg].lock_bit);
364 if (lock == TEGRA_PIN_LOCK_ENABLE)
365 reg |= (0x1 << pingroups[pg].lock_bit);
366
367 pg_writel(reg, pingroups[pg].mux_reg);
368
369 spin_unlock_irqrestore(&mux_lock, flags);
370 return 0;
371}
372
373static int tegra_pinmux_set_od(enum tegra_pingroup pg,
374 enum tegra_pin_od od)
375{
376 unsigned long reg;
377 unsigned long flags;
378
379 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
380 return -ERANGE;
381
382 if (pingroups[pg].mux_reg <= 0)
383 return -EINVAL;
384
385 if ((od == TEGRA_PIN_OD_DEFAULT) || (pingroups[pg].od_bit < 0))
386 return 0;
387
388 spin_lock_irqsave(&mux_lock, flags);
389
390 reg = pg_readl(pingroups[pg].mux_reg);
391 reg &= ~(0x1 << pingroups[pg].od_bit);
392 if (od == TEGRA_PIN_OD_ENABLE)
393 reg |= 1 << pingroups[pg].od_bit;
394
395 pg_writel(reg, pingroups[pg].mux_reg);
396
397 spin_unlock_irqrestore(&mux_lock, flags);
398
399 return 0;
400}
401
402static int tegra_pinmux_set_ioreset(enum tegra_pingroup pg,
403 enum tegra_pin_ioreset ioreset)
404{
405 unsigned long reg;
406 unsigned long flags;
407
408 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
409 return -ERANGE;
410
411 if (pingroups[pg].mux_reg <= 0)
412 return -EINVAL;
413
414 if ((ioreset == TEGRA_PIN_IO_RESET_DEFAULT) || (pingroups[pg].ioreset_bit < 0))
415 return 0;
416
417 spin_lock_irqsave(&mux_lock, flags);
418
419 reg = pg_readl(pingroups[pg].mux_reg);
420 reg &= ~(0x1 << pingroups[pg].ioreset_bit);
421 if (ioreset == TEGRA_PIN_IO_RESET_ENABLE)
422 reg |= 1 << pingroups[pg].ioreset_bit;
423
424 pg_writel(reg, pingroups[pg].mux_reg);
425
426 spin_unlock_irqrestore(&mux_lock, flags);
427
428 return 0;
429}
430#endif
431
432int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
433 enum tegra_pullupdown pupd)
434{
435 unsigned long reg;
436 unsigned long flags;
437
438 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
439 return -ERANGE;
440
441 if (pingroups[pg].pupd_reg <= 0)
442 return -EINVAL;
443
444 if (pupd != TEGRA_PUPD_NORMAL &&
445 pupd != TEGRA_PUPD_PULL_DOWN &&
446 pupd != TEGRA_PUPD_PULL_UP)
447 return -EINVAL;
448
449
450 spin_lock_irqsave(&mux_lock, flags);
451
452 reg = pg_readl(pingroups[pg].pupd_reg);
453 reg &= ~(0x3 << pingroups[pg].pupd_bit);
454 reg |= pupd << pingroups[pg].pupd_bit;
455 pg_writel(reg, pingroups[pg].pupd_reg);
456
457 spin_unlock_irqrestore(&mux_lock, flags);
458
459 return 0;
460}
461
462static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
463{
464 enum tegra_pingroup pingroup = config->pingroup;
465 enum tegra_mux_func func = config->func;
466 enum tegra_pullupdown pupd = config->pupd;
467 enum tegra_tristate tristate = config->tristate;
468#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
469 enum tegra_pin_lock lock = config->lock;
470 enum tegra_pin_od od = config->od;
471 enum tegra_pin_ioreset ioreset = config->ioreset;
472#endif
473 int err;
474
475 if (pingroups[pingroup].mux_reg > 0) {
476 err = tegra_pinmux_set_func(config);
477 if (err < 0)
478 pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
479 pingroup_name(pingroup), func_name(func), err);
480 }
481
482 if (pingroups[pingroup].pupd_reg > 0) {
483 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
484 if (err < 0)
485 pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
486 pingroup_name(pingroup), pupd_name(pupd), err);
487 }
488
489 if (pingroups[pingroup].tri_reg > 0) {
490 err = tegra_pinmux_set_tristate(pingroup, tristate);
491 if (err < 0)
492 pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
493 pingroup_name(pingroup), tri_name(func), err);
494 }
495
496#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
497 if (pingroups[pingroup].mux_reg > 0) {
498 err = tegra_pinmux_set_lock(pingroup, lock);
499 if (err < 0)
500 pr_err("pinmux: can't set pingroup %s lock to %s: %d\n",
501 pingroup_name(pingroup), lock_name(func), err);
502 }
503
504 if (pingroups[pingroup].mux_reg > 0) {
505 err = tegra_pinmux_set_od(pingroup, od);
506 if (err < 0)
507 pr_err("pinmux: can't set pingroup %s od to %s: %d\n",
508 pingroup_name(pingroup), od_name(func), err);
509 }
510
511 if (pingroups[pingroup].mux_reg > 0) {
512 err = tegra_pinmux_set_ioreset(pingroup, ioreset);
513 if (err < 0)
514 pr_err("pinmux: can't set pingroup %s ioreset to %s: %d\n",
515 pingroup_name(pingroup), ioreset_name(func), err);
516 }
517#endif
518}
519
520void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
521{
522 int i;
523
524 for (i = 0; i < len; i++)
525 tegra_pinmux_config_pingroup(&config[i]);
526}
527EXPORT_SYMBOL(tegra_pinmux_config_table);
528
529static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
530{
531 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
532 return "<UNKNOWN>";
533
534 return drive_pingroups[pg].name;
535}
536
537static const char *enable_name(unsigned long val)
538{
539 return val ? "ENABLE" : "DISABLE";
540}
541
542static const char *drive_name(unsigned long val)
543{
544 if (val >= TEGRA_MAX_DRIVE)
545 return "<UNKNOWN>";
546
547 return tegra_drive_names[val];
548}
549
550static const char *slew_name(unsigned long val)
551{
552 if (val >= TEGRA_MAX_SLEW)
553 return "<UNKNOWN>";
554
555 return tegra_slew_names[val];
556}
557
558static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
559 enum tegra_hsm hsm)
560{
561 unsigned long flags;
562 u32 reg;
563 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
564 return -ERANGE;
565
566 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
567 return -EINVAL;
568
569 spin_lock_irqsave(&mux_lock, flags);
570
571 reg = pg_readl(drive_pingroups[pg].reg);
572 if (hsm == TEGRA_HSM_ENABLE)
573 reg |= (1 << 2);
574 else
575 reg &= ~(1 << 2);
576 pg_writel(reg, drive_pingroups[pg].reg);
577
578 spin_unlock_irqrestore(&mux_lock, flags);
579
580 return 0;
581}
582
583static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
584 enum tegra_schmitt schmitt)
585{
586 unsigned long flags;
587 u32 reg;
588 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
589 return -ERANGE;
590
591 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
592 return -EINVAL;
593
594 spin_lock_irqsave(&mux_lock, flags);
595
596 reg = pg_readl(drive_pingroups[pg].reg);
597 if (schmitt == TEGRA_SCHMITT_ENABLE)
598 reg |= (1 << 3);
599 else
600 reg &= ~(1 << 3);
601 pg_writel(reg, drive_pingroups[pg].reg);
602
603 spin_unlock_irqrestore(&mux_lock, flags);
604
605 return 0;
606}
607
608static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
609 enum tegra_drive drive)
610{
611 unsigned long flags;
612 u32 reg;
613 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
614 return -ERANGE;
615
616 if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
617 return -EINVAL;
618
619 spin_lock_irqsave(&mux_lock, flags);
620
621 reg = pg_readl(drive_pingroups[pg].reg);
622 reg &= ~(0x3 << 4);
623 reg |= drive << 4;
624 pg_writel(reg, drive_pingroups[pg].reg);
625
626 spin_unlock_irqrestore(&mux_lock, flags);
627
628 return 0;
629}
630
631static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
632 enum tegra_pull_strength pull_down)
633{
634 unsigned long flags;
635 u32 reg;
636
637 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
638 return -ERANGE;
639
640 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
641 return -EINVAL;
642
643 spin_lock_irqsave(&mux_lock, flags);
644
645 reg = pg_readl(drive_pingroups[pg].reg);
646 reg &= ~(drive_pingroups[pg].drvdown_mask <<
647 drive_pingroups[pg].drvdown_offset);
648 reg |= pull_down << drive_pingroups[pg].drvdown_offset;
649 pg_writel(reg, drive_pingroups[pg].reg);
650
651 spin_unlock_irqrestore(&mux_lock, flags);
652
653 return 0;
654}
655
656static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
657 enum tegra_pull_strength pull_up)
658{
659 unsigned long flags;
660 u32 reg;
661
662 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
663 return -ERANGE;
664
665 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
666 return -EINVAL;
667
668 spin_lock_irqsave(&mux_lock, flags);
669
670 reg = pg_readl(drive_pingroups[pg].reg);
671 reg &= ~(drive_pingroups[pg].drvup_mask <<
672 drive_pingroups[pg].drvup_offset);
673 reg |= pull_up << drive_pingroups[pg].drvup_offset;
674 pg_writel(reg, drive_pingroups[pg].reg);
675
676 spin_unlock_irqrestore(&mux_lock, flags);
677
678 return 0;
679}
680
681static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
682 enum tegra_slew slew_rising)
683{
684 unsigned long flags;
685 u32 reg;
686 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
687 return -ERANGE;
688
689 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
690 return -EINVAL;
691
692 spin_lock_irqsave(&mux_lock, flags);
693
694 reg = pg_readl(drive_pingroups[pg].reg);
695 reg &= ~(drive_pingroups[pg].slewrise_mask <<
696 drive_pingroups[pg].slewrise_offset);
697 reg |= slew_rising << drive_pingroups[pg].slewrise_offset;
698 pg_writel(reg, drive_pingroups[pg].reg);
699
700 spin_unlock_irqrestore(&mux_lock, flags);
701
702 return 0;
703}
704
705static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
706 enum tegra_slew slew_falling)
707{
708 unsigned long flags;
709 u32 reg;
710 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
711 return -ERANGE;
712
713 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
714 return -EINVAL;
715
716 spin_lock_irqsave(&mux_lock, flags);
717
718 reg = pg_readl(drive_pingroups[pg].reg);
719 reg &= ~(drive_pingroups[pg].slewfall_mask <<
720 drive_pingroups[pg].slewfall_offset);
721 reg |= slew_falling << drive_pingroups[pg].slewfall_offset;
722 pg_writel(reg, drive_pingroups[pg].reg);
723
724 spin_unlock_irqrestore(&mux_lock, flags);
725
726 return 0;
727}
728
729static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
730 enum tegra_hsm hsm,
731 enum tegra_schmitt schmitt,
732 enum tegra_drive drive,
733 enum tegra_pull_strength pull_down,
734 enum tegra_pull_strength pull_up,
735 enum tegra_slew slew_rising,
736 enum tegra_slew slew_falling)
737{
738 int err;
739
740 err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
741 if (err < 0)
742 pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
743 drive_pinmux_name(pingroup),
744 enable_name(hsm), err);
745
746 err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
747 if (err < 0)
748 pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
749 drive_pinmux_name(pingroup),
750 enable_name(schmitt), err);
751
752 err = tegra_drive_pinmux_set_drive(pingroup, drive);
753 if (err < 0)
754 pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
755 drive_pinmux_name(pingroup),
756 drive_name(drive), err);
757
758 err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
759 if (err < 0)
760 pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
761 drive_pinmux_name(pingroup),
762 pull_down, err);
763
764 err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
765 if (err < 0)
766 pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
767 drive_pinmux_name(pingroup),
768 pull_up, err);
769
770 err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
771 if (err < 0)
772 pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
773 drive_pinmux_name(pingroup),
774 slew_name(slew_rising), err);
775
776 err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
777 if (err < 0)
778 pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
779 drive_pinmux_name(pingroup),
780 slew_name(slew_falling), err);
781}
782
783void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
784 int len)
785{
786 int i;
787
788 for (i = 0; i < len; i++)
789 tegra_drive_pinmux_config_pingroup(config[i].pingroup,
790 config[i].hsm,
791 config[i].schmitt,
792 config[i].drive,
793 config[i].pull_down,
794 config[i].pull_up,
795 config[i].slew_rising,
796 config[i].slew_falling);
797}
798
799void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
800 int len)
801{
802 int i;
803 struct tegra_pingroup_config c;
804
805 for (i = 0; i < len; i++) {
806 int err;
807 c = config[i];
808 if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) {
809 WARN_ON(1);
810 continue;
811 }
812 c.func = pingroups[c.pingroup].func_safe;
813 err = tegra_pinmux_set_func(&c);
814 if (err < 0)
815 pr_err("%s: tegra_pinmux_set_func returned %d setting "
816 "%s to %s\n", __func__, err,
817 pingroup_name(c.pingroup), func_name(c.func));
818 }
819}
820
821void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
822 int len)
823{
824 int i;
825
826 for (i = 0; i < len; i++) {
827 int err;
828 if (config[i].pingroup < 0 ||
829 config[i].pingroup >= TEGRA_MAX_PINGROUP) {
830 WARN_ON(1);
831 continue;
832 }
833 err = tegra_pinmux_set_func(&config[i]);
834 if (err < 0)
835 pr_err("%s: tegra_pinmux_set_func returned %d setting "
836 "%s to %s\n", __func__, err,
837 pingroup_name(config[i].pingroup),
838 func_name(config[i].func));
839 }
840}
841
842void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
843 int len, enum tegra_tristate tristate)
844{
845 int i;
846 int err;
847 enum tegra_pingroup pingroup;
848
849 for (i = 0; i < len; i++) {
850 pingroup = config[i].pingroup;
851 if (pingroups[pingroup].tri_reg > 0) {
852 err = tegra_pinmux_set_tristate(pingroup, tristate);
853 if (err < 0)
854 pr_err("pinmux: can't set pingroup %s tristate"
855 " to %s: %d\n", pingroup_name(pingroup),
856 tri_name(tristate), err);
857 }
858 }
859}
860
861void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
862 int len, enum tegra_pullupdown pupd)
863{
864 int i;
865 int err;
866 enum tegra_pingroup pingroup;
867
868 for (i = 0; i < len; i++) {
869 pingroup = config[i].pingroup;
870 if (pingroups[pingroup].pupd_reg > 0) {
871 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
872 if (err < 0)
873 pr_err("pinmux: can't set pingroup %s pullupdown"
874 " to %s: %d\n", pingroup_name(pingroup),
875 pupd_name(pupd), err);
876 }
877 }
878}
879
880#ifdef CONFIG_DEBUG_FS
881
882#include <linux/debugfs.h>
883#include <linux/seq_file.h>
884
885static void dbg_pad_field(struct seq_file *s, int len)
886{
887 seq_putc(s, ',');
888
889 while (len-- > -1)
890 seq_putc(s, ' ');
891}
892
893static int dbg_pinmux_show(struct seq_file *s, void *unused)
894{
895 int i;
896 int len;
897
898 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
899 unsigned long tri;
900 unsigned long mux;
901 unsigned long pupd;
902
903 seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
904 len = strlen(pingroups[i].name);
905 dbg_pad_field(s, 15 - len);
906
907 if (pingroups[i].mux_reg <= 0) {
908 seq_printf(s, "TEGRA_MUX_NONE");
909 len = strlen("NONE");
910 } else {
911 mux = (pg_readl(pingroups[i].mux_reg) >>
912 pingroups[i].mux_bit) & 0x3;
913 BUG_ON(pingroups[i].funcs[mux] == 0);
914 if (pingroups[i].funcs[mux] == TEGRA_MUX_INVALID) {
915 seq_printf(s, "TEGRA_MUX_INVALID");
916 len = 7;
917 } else if (pingroups[i].funcs[mux] & TEGRA_MUX_RSVD) {
918 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
919 len = 5;
920 } else {
921 BUG_ON(!tegra_mux_names[pingroups[i].funcs[mux]]);
922 seq_printf(s, "TEGRA_MUX_%s",
923 tegra_mux_names[pingroups[i].funcs[mux]]);
924 len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
925 }
926 }
927 dbg_pad_field(s, 13-len);
928
929#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
930 {
931 unsigned long io;
932 io = (pg_readl(pingroups[i].mux_reg) >> 5) & 0x1;
933 seq_printf(s, "TEGRA_PIN_%s", io_name(io));
934 len = strlen(io_name(io));
935 dbg_pad_field(s, 6 - len);
936 }
937#endif
938 if (pingroups[i].pupd_reg <= 0) {
939 seq_printf(s, "TEGRA_PUPD_NORMAL");
940 len = strlen("NORMAL");
941 } else {
942 pupd = (pg_readl(pingroups[i].pupd_reg) >>
943 pingroups[i].pupd_bit) & 0x3;
944 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
945 len = strlen(pupd_name(pupd));
946 }
947 dbg_pad_field(s, 9 - len);
948
949 if (pingroups[i].tri_reg <= 0) {
950 seq_printf(s, "TEGRA_TRI_NORMAL");
951 } else {
952 tri = (pg_readl(pingroups[i].tri_reg) >>
953 pingroups[i].tri_bit) & 0x1;
954
955 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
956 }
957 seq_printf(s, "},\n");
958 }
959 return 0;
960}
961
962static int dbg_pinmux_open(struct inode *inode, struct file *file)
963{
964 return single_open(file, dbg_pinmux_show, &inode->i_private);
965}
966
967static const struct file_operations debug_fops = {
968 .open = dbg_pinmux_open,
969 .read = seq_read,
970 .llseek = seq_lseek,
971 .release = single_release,
972};
973
974static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
975{
976 int i;
977 int len;
978 u8 offset;
979
980 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
981 u32 reg;
982
983 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
984 drive_pingroups[i].name);
985 len = strlen(drive_pingroups[i].name);
986 dbg_pad_field(s, 7 - len);
987
988
989 reg = pg_readl(drive_pingroups[i].reg);
990 if (HSM_EN(reg)) {
991 seq_printf(s, "TEGRA_HSM_ENABLE");
992 len = 16;
993 } else {
994 seq_printf(s, "TEGRA_HSM_DISABLE");
995 len = 17;
996 }
997 dbg_pad_field(s, 17 - len);
998
999 if (SCHMT_EN(reg)) {
1000 seq_printf(s, "TEGRA_SCHMITT_ENABLE");
1001 len = 21;
1002 } else {
1003 seq_printf(s, "TEGRA_SCHMITT_DISABLE");
1004 len = 22;
1005 }
1006 dbg_pad_field(s, 22 - len);
1007
1008 seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
1009 len = strlen(drive_name(LPMD(reg)));
1010 dbg_pad_field(s, 5 - len);
1011
1012 offset = drive_pingroups[i].drvdown_offset;
1013 seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg, offset));
1014 len = DRVDN(reg, offset) < 10 ? 1 : 2;
1015 dbg_pad_field(s, 2 - len);
1016
1017 offset = drive_pingroups[i].drvup_offset;
1018 seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg, offset));
1019 len = DRVUP(reg, offset) < 10 ? 1 : 2;
1020 dbg_pad_field(s, 2 - len);
1021
1022 offset = drive_pingroups[i].slewrise_offset;
1023 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg, offset)));
1024 len = strlen(slew_name(SLWR(reg, offset)));
1025 dbg_pad_field(s, 7 - len);
1026
1027 offset= drive_pingroups[i].slewfall_offset;
1028 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg, offset)));
1029
1030 seq_printf(s, "},\n");
1031 }
1032 return 0;
1033}
1034
1035static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
1036{
1037 return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
1038}
1039
1040static const struct file_operations debug_drive_fops = {
1041 .open = dbg_drive_pinmux_open,
1042 .read = seq_read,
1043 .llseek = seq_lseek,
1044 .release = single_release,
1045};
1046
1047static int __init tegra_pinmux_debuginit(void)
1048{
1049 (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
1050 NULL, NULL, &debug_fops);
1051 (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
1052 NULL, NULL, &debug_drive_fops);
1053 return 0;
1054}
1055late_initcall(tegra_pinmux_debuginit);
1056#endif
diff --git a/arch/arm/mach-tegra/pm-irq.c b/arch/arm/mach-tegra/pm-irq.c
new file mode 100644
index 00000000000..57d21361ca1
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-irq.c
@@ -0,0 +1,366 @@
1/*
2 * Copyright (C) 2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/debugfs.h>
20#include <linux/delay.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/io.h>
25#include <linux/moduleparam.h>
26#include <linux/seq_file.h>
27#include <linux/syscore_ops.h>
28
29#include <mach/iomap.h>
30
31#include "pm-irq.h"
32
33#define PMC_CTRL 0x0
34#define PMC_CTRL_LATCH_WAKEUPS (1 << 5)
35#define PMC_WAKE_MASK 0xc
36#define PMC_WAKE_LEVEL 0x10
37#define PMC_WAKE_STATUS 0x14
38#define PMC_SW_WAKE_STATUS 0x18
39#ifndef CONFIG_ARCH_TEGRA_2x_SOC
40#define PMC_WAKE2_MASK 0x160
41#define PMC_WAKE2_LEVEL 0x164
42#define PMC_WAKE2_STATUS 0x168
43#define PMC_SW_WAKE2_STATUS 0x16C
44#endif
45
46#define PMC_MAX_WAKE_COUNT 64
47
48static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
49
50static u64 tegra_lp0_wake_enb;
51static u64 tegra_lp0_wake_level;
52static u64 tegra_lp0_wake_level_any;
53static int tegra_prevent_lp0;
54
55static unsigned int tegra_wake_irq_count[PMC_MAX_WAKE_COUNT];
56
57static bool debug_lp0;
58module_param(debug_lp0, bool, S_IRUGO | S_IWUSR);
59
60static bool warn_prevent_lp0;
61module_param(warn_prevent_lp0, bool, S_IRUGO | S_IWUSR);
62
63bool tegra_pm_irq_lp0_allowed(void)
64{
65 return (tegra_prevent_lp0 == 0);
66}
67
68/* ensures that sufficient time is passed for a register write to
69 * serialize into the 32KHz domain */
70static void pmc_32kwritel(u32 val, unsigned long offs)
71{
72 writel(val, pmc + offs);
73 udelay(130);
74}
75
76static inline void write_pmc_wake_mask(u64 value)
77{
78 pr_info("Wake[31-0] enable=0x%x\n", (u32)(value & 0xFFFFFFFF));
79 writel((u32)value, pmc + PMC_WAKE_MASK);
80#ifndef CONFIG_ARCH_TEGRA_2x_SOC
81 pr_info("Tegra3 wake[63-32] enable=0x%x\n", (u32)((value >> 32) &
82 0xFFFFFFFF));
83 __raw_writel((u32)(value >> 32), pmc + PMC_WAKE2_MASK);
84#endif
85}
86
87static inline u64 read_pmc_wake_level(void)
88{
89 u64 reg;
90
91#ifdef CONFIG_ARCH_TEGRA_2x_SOC
92 reg = readl(pmc + PMC_WAKE_LEVEL);
93#else
94 reg = __raw_readl(pmc + PMC_WAKE_LEVEL);
95 reg |= ((u64)readl(pmc + PMC_WAKE2_LEVEL)) << 32;
96#endif
97 return reg;
98}
99
100static inline void write_pmc_wake_level(u64 value)
101{
102 pr_info("Wake[31-0] level=0x%x\n", (u32)(value & 0xFFFFFFFF));
103 writel((u32)value, pmc + PMC_WAKE_LEVEL);
104#ifndef CONFIG_ARCH_TEGRA_2x_SOC
105 pr_info("Tegra3 wake[63-32] level=0x%x\n", (u32)((value >> 32) &
106 0xFFFFFFFF));
107 __raw_writel((u32)(value >> 32), pmc + PMC_WAKE2_LEVEL);
108#endif
109}
110
111static inline u64 read_pmc_wake_status(void)
112{
113 u64 reg;
114
115#ifdef CONFIG_ARCH_TEGRA_2x_SOC
116 reg = readl(pmc + PMC_WAKE_STATUS);
117#else
118 reg = __raw_readl(pmc + PMC_WAKE_STATUS);
119 reg |= ((u64)readl(pmc + PMC_WAKE2_STATUS)) << 32;
120#endif
121 return reg;
122}
123
124static inline u64 read_pmc_sw_wake_status(void)
125{
126 u64 reg;
127
128#ifdef CONFIG_ARCH_TEGRA_2x_SOC
129 reg = readl(pmc + PMC_SW_WAKE_STATUS);
130#else
131 reg = __raw_readl(pmc + PMC_SW_WAKE_STATUS);
132 reg |= ((u64)readl(pmc + PMC_SW_WAKE2_STATUS)) << 32;
133#endif
134 return reg;
135}
136
137static inline void clear_pmc_sw_wake_status(void)
138{
139 pmc_32kwritel(0, PMC_SW_WAKE_STATUS);
140#ifndef CONFIG_ARCH_TEGRA_2x_SOC
141 pmc_32kwritel(0, PMC_SW_WAKE2_STATUS);
142#endif
143}
144
145int tegra_pm_irq_set_wake(int irq, int enable)
146{
147 int wake = tegra_irq_to_wake(irq);
148
149 if (wake == -EALREADY) {
150 /* EALREADY means wakeup event already accounted for */
151 return 0;
152 } else if (wake == -ENOTSUPP) {
153 /* ENOTSUPP means LP0 not supported with this wake source */
154 WARN(enable && warn_prevent_lp0, "irq %d prevents lp0\n", irq);
155 if (enable)
156 tegra_prevent_lp0++;
157 else if (!WARN_ON(tegra_prevent_lp0 == 0))
158 tegra_prevent_lp0--;
159 return 0;
160 } else if (wake < 0) {
161 return -EINVAL;
162 }
163
164 if (enable) {
165 tegra_lp0_wake_enb |= 1ull << wake;
166 pr_info("Enabling wake%d\n", wake);
167 } else {
168 tegra_lp0_wake_enb &= ~(1ull << wake);
169 pr_info("Disabling wake%d\n", wake);
170 }
171
172 return 0;
173}
174
175int tegra_pm_irq_set_wake_type(int irq, int flow_type)
176{
177 int wake = tegra_irq_to_wake(irq);
178
179 if (wake < 0)
180 return 0;
181
182 switch (flow_type) {
183 case IRQF_TRIGGER_FALLING:
184 case IRQF_TRIGGER_LOW:
185 tegra_lp0_wake_level &= ~(1ull << wake);
186 tegra_lp0_wake_level_any &= ~(1ull << wake);
187 break;
188 case IRQF_TRIGGER_HIGH:
189 case IRQF_TRIGGER_RISING:
190 tegra_lp0_wake_level |= (1ull << wake);
191 tegra_lp0_wake_level_any &= ~(1ull << wake);
192 break;
193
194 case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING:
195 tegra_lp0_wake_level_any |= (1ull << wake);
196 break;
197 default:
198 return -EINVAL;
199 }
200
201 return 0;
202}
203
204/* translate lp0 wake sources back into irqs to catch edge triggered wakeups */
205static void tegra_pm_irq_syscore_resume_helper(
206 unsigned long wake_status,
207 unsigned int index)
208{
209 int wake;
210 int irq;
211 struct irq_desc *desc;
212
213 for_each_set_bit(wake, &wake_status, sizeof(wake_status) * 8) {
214 irq = tegra_wake_to_irq(wake + 32 * index);
215 if (!irq) {
216 pr_info("Resume caused by WAKE%d\n",
217 (wake + 32 * index));
218 continue;
219 }
220
221 desc = irq_to_desc(irq);
222 if (!desc || !desc->action || !desc->action->name) {
223 pr_info("Resume caused by WAKE%d, irq %d\n",
224 (wake + 32 * index), irq);
225 continue;
226 }
227
228 pr_info("Resume caused by WAKE%d, %s\n", (wake + 32 * index),
229 desc->action->name);
230
231 tegra_wake_irq_count[wake + 32 * index]++;
232
233 generic_handle_irq(irq);
234 }
235}
236
237static void tegra_pm_irq_syscore_resume(void)
238{
239 unsigned long long wake_status = read_pmc_wake_status();
240
241 pr_info(" legacy wake status=0x%x\n", (u32)wake_status);
242 tegra_pm_irq_syscore_resume_helper((unsigned long)wake_status, 0);
243#ifndef CONFIG_ARCH_TEGRA_2x_SOC
244 pr_info(" tegra3 wake status=0x%x\n", (u32)(wake_status >> 32));
245 tegra_pm_irq_syscore_resume_helper(
246 (unsigned long)(wake_status >> 32), 1);
247#endif
248}
249
250/* set up lp0 wake sources */
251static int tegra_pm_irq_syscore_suspend(void)
252{
253 u32 temp;
254 u64 status;
255 u64 lvl;
256 u64 wake_level;
257 u64 wake_enb;
258
259 clear_pmc_sw_wake_status();
260
261 temp = readl(pmc + PMC_CTRL);
262 temp |= PMC_CTRL_LATCH_WAKEUPS;
263 pmc_32kwritel(temp, PMC_CTRL);
264
265 temp &= ~PMC_CTRL_LATCH_WAKEUPS;
266 pmc_32kwritel(temp, PMC_CTRL);
267
268 status = read_pmc_sw_wake_status();
269
270 lvl = read_pmc_wake_level();
271
272 /* flip the wakeup trigger for any-edge triggered pads
273 * which are currently asserting as wakeups */
274 lvl ^= status;
275
276 lvl &= tegra_lp0_wake_level_any;
277
278 wake_level = lvl | tegra_lp0_wake_level;
279 wake_enb = tegra_lp0_wake_enb;
280
281 if (debug_lp0) {
282 wake_level = lvl ^ status;
283 wake_enb = 0xffffffff;
284 }
285
286 /* Clear PMC Wake Status register while going to suspend */
287 temp = readl(pmc + PMC_WAKE_STATUS);
288 if (temp)
289 pmc_32kwritel(temp, PMC_WAKE_STATUS);
290
291 write_pmc_wake_level(wake_level);
292
293 write_pmc_wake_mask(wake_enb);
294
295 return 0;
296}
297
298static struct syscore_ops tegra_pm_irq_syscore_ops = {
299 .suspend = tegra_pm_irq_syscore_suspend,
300 .resume = tegra_pm_irq_syscore_resume,
301};
302
303static int tegra_pm_irq_syscore_init(void)
304{
305 register_syscore_ops(&tegra_pm_irq_syscore_ops);
306
307 return 0;
308}
309subsys_initcall(tegra_pm_irq_syscore_init);
310
311#ifdef CONFIG_DEBUG_FS
312static int tegra_pm_irq_debug_show(struct seq_file *s, void *data)
313{
314 int wake;
315 int irq;
316 struct irq_desc *desc;
317 const char *irq_name;
318
319 seq_printf(s, "wake irq count name\n");
320 seq_printf(s, "----------------------\n");
321 for (wake = 0; wake < PMC_MAX_WAKE_COUNT; wake++) {
322 irq = tegra_wake_to_irq(wake);
323 if (irq < 0)
324 continue;
325
326 desc = irq_to_desc(irq);
327 if (tegra_wake_irq_count[wake] == 0 && desc->action == NULL)
328 continue;
329
330 irq_name = (desc->action && desc->action->name) ?
331 desc->action->name : "???";
332
333 seq_printf(s, "%4d %3d %5d %s\n",
334 wake, irq, tegra_wake_irq_count[wake], irq_name);
335 }
336 return 0;
337}
338
339static int tegra_pm_irq_debug_open(struct inode *inode, struct file *file)
340{
341 return single_open(file, tegra_pm_irq_debug_show, NULL);
342}
343
344static const struct file_operations tegra_pm_irq_debug_fops = {
345 .open = tegra_pm_irq_debug_open,
346 .read = seq_read,
347 .llseek = seq_lseek,
348 .release = single_release,
349};
350
351static int __init tegra_pm_irq_debug_init(void)
352{
353 struct dentry *d;
354
355 d = debugfs_create_file("wake_irq", S_IRUGO, NULL, NULL,
356 &tegra_pm_irq_debug_fops);
357 if (!d) {
358 pr_err("Failed to create suspend_mode debug file\n");
359 return -ENOMEM;
360 }
361
362 return 0;
363}
364
365late_initcall(tegra_pm_irq_debug_init);
366#endif
diff --git a/arch/arm/mach-tegra/pm-irq.h b/arch/arm/mach-tegra/pm-irq.h
new file mode 100644
index 00000000000..8e87b4bba24
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-irq.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef _MACH_TERA_PM_IRQ_H_
19#define _MACH_TERA_PM_IRQ_H_
20
21#ifdef CONFIG_PM_SLEEP
22int tegra_pm_irq_set_wake(int irq, int enable);
23int tegra_pm_irq_set_wake_type(int irq, int flow_type);
24bool tegra_pm_irq_lp0_allowed(void);
25int tegra_irq_to_wake(int irq);
26int tegra_wake_to_irq(int wake);
27#else
28static inline int tegra_pm_irq_set_wake_type(int irq, int flow_type)
29{
30 return 0;
31}
32#endif
33#endif
diff --git a/arch/arm/mach-tegra/pm-t2.c b/arch/arm/mach-tegra/pm-t2.c
new file mode 100644
index 00000000000..7ddbb212559
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-t2.c
@@ -0,0 +1,376 @@
1/*
2 * arch/arm/mach-tegra/pm-t2.c
3 *
4 * Tegra 2 LP0 scratch register preservation
5 *
6 * Copyright (c) 2009-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/gpio.h>
25#include <linux/init.h>
26#include <linux/io.h>
27#include <linux/module.h>
28
29#include <mach/iomap.h>
30#include <mach/irqs.h>
31
32#include "pm.h"
33
34#define PMC_SCRATCH3 0x5c
35#define PMC_SCRATCH5 0x64
36#define PMC_SCRATCH6 0x68
37#define PMC_SCRATCH7 0x6c
38#define PMC_SCRATCH8 0x70
39#define PMC_SCRATCH9 0x74
40#define PMC_SCRATCH10 0x78
41#define PMC_SCRATCH11 0x7c
42#define PMC_SCRATCH12 0x80
43#define PMC_SCRATCH13 0x84
44#define PMC_SCRATCH14 0x88
45#define PMC_SCRATCH15 0x8c
46#define PMC_SCRATCH16 0x90
47#define PMC_SCRATCH17 0x94
48#define PMC_SCRATCH18 0x98
49#define PMC_SCRATCH19 0x9c
50#define PMC_SCRATCH20 0xa0
51#define PMC_SCRATCH21 0xa4
52#define PMC_SCRATCH22 0xa8
53#define PMC_SCRATCH23 0xac
54#define PMC_SCRATCH25 0x100
55#define PMC_SCRATCH35 0x128
56#define PMC_SCRATCH36 0x12c
57#define PMC_SCRATCH40 0x13c
58
59struct pmc_scratch_field {
60 unsigned long addr;
61 unsigned int mask;
62 int shift_src;
63 int shift_dst;
64};
65
66#define field(reg, start, end, dst) \
67 { \
68 .addr = (reg), \
69 .mask = 0xfffffffful >> (31 - ((end) - (start))), \
70 .shift_src = (start), \
71 .shift_dst = (dst), \
72 }
73
74static const struct pmc_scratch_field pllx[] __initdata = {
75 field(TEGRA_CLK_RESET_BASE + 0xe0, 20, 22, 15), /* PLLX_DIVP */
76 field(TEGRA_CLK_RESET_BASE + 0xe0, 8, 17, 5), /* PLLX_DIVN */
77 field(TEGRA_CLK_RESET_BASE + 0xe0, 0, 4, 0), /* PLLX_DIVM */
78 field(TEGRA_CLK_RESET_BASE + 0xe4, 8, 11, 22), /* PLLX_CPCON */
79 field(TEGRA_CLK_RESET_BASE + 0xe4, 4, 7, 18), /* PLLX_LFCON */
80 field(TEGRA_APB_MISC_BASE + 0x8e4, 24, 27, 27), /* XM2CFGC_VREF_DQ */
81 field(TEGRA_APB_MISC_BASE + 0x8c8, 3, 3, 26), /* XM2CFGC_SCHMT_EN */
82 field(TEGRA_APB_MISC_BASE + 0x8d0, 2, 2, 31), /* XM2CLKCFG_PREEMP_EN */
83};
84
85static const struct pmc_scratch_field emc_0[] __initdata = {
86 field(TEGRA_EMC_BASE + 0x3c, 0, 4, 27), /* R2W */
87 field(TEGRA_EMC_BASE + 0x34, 0, 5, 15), /* RAS */
88 field(TEGRA_EMC_BASE + 0x2c, 0, 5, 0), /* RC */
89 field(TEGRA_EMC_BASE + 0x30, 0, 8, 6), /* RFC */
90 field(TEGRA_EMC_BASE + 0x38, 0, 5, 21), /* RP */
91};
92
93static const struct pmc_scratch_field emc_1[] __initdata = {
94 field(TEGRA_EMC_BASE + 0x44, 0, 4, 5), /* R2P */
95 field(TEGRA_EMC_BASE + 0x4c, 0, 5, 15), /* RD_RCD */
96 field(TEGRA_EMC_BASE + 0x54, 0, 3, 27), /* RRD */
97 field(TEGRA_EMC_BASE + 0x48, 0, 4, 10), /* W2P */
98 field(TEGRA_EMC_BASE + 0x40, 0, 4, 0), /* W2R */
99 field(TEGRA_EMC_BASE + 0x50, 0, 5, 21), /* WR_RCD */
100};
101
102static const struct pmc_scratch_field emc_2[] __initdata = {
103 field(TEGRA_EMC_BASE + 0x2b8, 2, 2, 31), /* CLKCHANGE_SR_ENABLE */
104 field(TEGRA_EMC_BASE + 0x2b8, 10, 10, 30), /* USE_ADDR_CLK */
105 field(TEGRA_EMC_BASE + 0x80, 0, 4, 25), /* PCHG2PDEN */
106 field(TEGRA_EMC_BASE + 0x64, 0, 3, 12), /* QRST */
107 field(TEGRA_EMC_BASE + 0x68, 0, 3, 16), /* QSAFE */
108 field(TEGRA_EMC_BASE + 0x60, 0, 3, 8), /* QUSE */
109 field(TEGRA_EMC_BASE + 0x6c, 0, 4, 20), /* RDV */
110 field(TEGRA_EMC_BASE + 0x58, 0, 3, 0), /* REXT */
111 field(TEGRA_EMC_BASE + 0x5c, 0, 3, 4), /* WDV */
112};
113
114static const struct pmc_scratch_field emc_3[] __initdata = {
115 field(TEGRA_EMC_BASE + 0x74, 0, 3, 16), /* BURST_REFRESH_NUM */
116 field(TEGRA_EMC_BASE + 0x7c, 0, 3, 24), /* PDEX2RD */
117 field(TEGRA_EMC_BASE + 0x78, 0, 3, 20), /* PDEX2WR */
118 field(TEGRA_EMC_BASE + 0x70, 0, 4, 0), /* REFRESH_LO */
119 field(TEGRA_EMC_BASE + 0x70, 5, 15, 5), /* REFRESH */
120 field(TEGRA_EMC_BASE + 0xa0, 0, 3, 28), /* TCLKSTABLE */
121};
122
123static const struct pmc_scratch_field emc_4[] __initdata = {
124 field(TEGRA_EMC_BASE + 0x84, 0, 4, 0), /* ACT2PDEN */
125 field(TEGRA_EMC_BASE + 0x88, 0, 4, 5), /* AR2PDEN */
126 field(TEGRA_EMC_BASE + 0x8c, 0, 5, 10), /* RW2PDEN */
127 field(TEGRA_EMC_BASE + 0x94, 0, 3, 28), /* TCKE */
128 field(TEGRA_EMC_BASE + 0x90, 0, 11, 16), /* TXSR */
129};
130
131static const struct pmc_scratch_field emc_5[] __initdata = {
132 field(TEGRA_EMC_BASE + 0x8, 10, 10, 30), /* AP_REQ_BUSY_CTRL */
133 field(TEGRA_EMC_BASE + 0x8, 24, 24, 31), /* CFG_PRIORITY */
134 field(TEGRA_EMC_BASE + 0x8, 2, 2, 26), /* FORCE_UPDATE */
135 field(TEGRA_EMC_BASE + 0x8, 4, 4, 27), /* MRS_WAIT */
136 field(TEGRA_EMC_BASE + 0x8, 5, 5, 28), /* PERIODIC_QRST */
137 field(TEGRA_EMC_BASE + 0x8, 9, 9, 29), /* READ_DQM_CTRL */
138 field(TEGRA_EMC_BASE + 0x8, 0, 0, 24), /* READ_MUX */
139 field(TEGRA_EMC_BASE + 0x8, 1, 1, 25), /* WRITE_MUX */
140 field(TEGRA_EMC_BASE + 0xa4, 0, 3, 6), /* TCLKSTOP */
141 field(TEGRA_EMC_BASE + 0xa8, 0, 13, 10), /* TREFBW */
142 field(TEGRA_EMC_BASE + 0x9c, 0, 5, 0), /* TRPAB */
143};
144
145static const struct pmc_scratch_field emc_6[] __initdata = {
146 field(TEGRA_EMC_BASE + 0xfc, 0, 1, 0), /* DQSIB_DLY_MSB_BYTE_0 */
147 field(TEGRA_EMC_BASE + 0xfc, 8, 9, 2), /* DQSIB_DLY_MSB_BYTE_1 */
148 field(TEGRA_EMC_BASE + 0xfc, 16, 17, 4), /* DQSIB_DLY_MSB_BYTE_2 */
149 field(TEGRA_EMC_BASE + 0xfc, 24, 25, 6), /* DQSIB_DLY_MSB_BYTE_3 */
150 field(TEGRA_EMC_BASE + 0x110, 0, 1, 8), /* QUSE_DLY_MSB_BYTE_0 */
151 field(TEGRA_EMC_BASE + 0x110, 8, 9, 10), /* QUSE_DLY_MSB_BYTE_1 */
152 field(TEGRA_EMC_BASE + 0x110, 16, 17, 12), /* QUSE_DLY_MSB_BYTE_2 */
153 field(TEGRA_EMC_BASE + 0x110, 24, 25, 14), /* QUSE_DLY_MSB_BYTE_3 */
154 field(TEGRA_EMC_BASE + 0xac, 0, 3, 22), /* QUSE_EXTRA */
155 field(TEGRA_EMC_BASE + 0x98, 0, 5, 16), /* TFAW */
156 field(TEGRA_APB_MISC_BASE + 0x8e4, 5, 5, 30), /* XM2CFGC_VREF_DQ_EN */
157 field(TEGRA_APB_MISC_BASE + 0x8e4, 16, 19, 26), /* XM2CFGC_VREF_DQS */
158};
159
160static const struct pmc_scratch_field emc_dqsib_dly[] __initdata = {
161 field(TEGRA_EMC_BASE + 0xf8, 0, 31, 0), /* DQSIB_DLY_BYTE_0 - DQSIB_DLY_BYTE_3*/
162};
163
164static const struct pmc_scratch_field emc_quse_dly[] __initdata = {
165 field(TEGRA_EMC_BASE + 0x10c, 0, 31, 0), /* QUSE_DLY_BYTE_0 - QUSE_DLY_BYTE_3*/
166};
167
168static const struct pmc_scratch_field emc_clktrim[] __initdata = {
169 field(TEGRA_EMC_BASE + 0x2d0, 0, 29, 0), /* DATA0_CLKTRIM - DATA3_CLKTRIM +
170 * MCLK_ADDR_CLKTRIM */
171};
172
173static const struct pmc_scratch_field emc_autocal_fbio[] __initdata = {
174 field(TEGRA_EMC_BASE + 0x2a4, 29, 29, 29), /* AUTO_CAL_ENABLE */
175 field(TEGRA_EMC_BASE + 0x2a4, 30, 30, 30), /* AUTO_CAL_OVERRIDE */
176 field(TEGRA_EMC_BASE + 0x2a4, 8, 12, 14), /* AUTO_CAL_PD_OFFSET */
177 field(TEGRA_EMC_BASE + 0x2a4, 0, 4, 9), /* AUTO_CAL_PU_OFFSET */
178 field(TEGRA_EMC_BASE + 0x2a4, 16, 25, 19), /* AUTO_CAL_STEP */
179 field(TEGRA_EMC_BASE + 0xf4, 16, 16, 0), /* CFG_DEN_EARLY */
180 field(TEGRA_EMC_BASE + 0x104, 8, 8, 8), /* CTT_TERMINATION */
181 field(TEGRA_EMC_BASE + 0x104, 7, 7, 7), /* DIFFERENTIAL_DQS */
182 field(TEGRA_EMC_BASE + 0x104, 9, 9, 31), /* DQS_PULLD */
183 field(TEGRA_EMC_BASE + 0x104, 0, 1, 4), /* DRAM_TYPE */
184 field(TEGRA_EMC_BASE + 0x104, 4, 4, 6), /* DRAM_WIDTH */
185 field(TEGRA_EMC_BASE + 0x114, 0, 2, 1), /* CFG_QUSE_LATE */
186};
187
188static const struct pmc_scratch_field emc_autocal_interval[] __initdata = {
189 field(TEGRA_EMC_BASE + 0x2a8, 0, 27, 0), /* AUTOCAL_INTERVAL */
190 field(TEGRA_EMC_BASE + 0x2b8, 1, 1, 29), /* CLKCHANGE_PD_ENABLE */
191 field(TEGRA_EMC_BASE + 0x2b8, 0, 0, 28), /* CLKCHANGE_REQ_ENABLE */
192 field(TEGRA_EMC_BASE + 0x2b8, 8, 9, 30), /* PIN_CONFIG */
193};
194
195static const struct pmc_scratch_field emc_cfgs[] __initdata = {
196 field(TEGRA_EMC_BASE + 0x10, 8, 9, 3), /* EMEM_BANKWIDTH */
197 field(TEGRA_EMC_BASE + 0x10, 0, 2, 0), /* EMEM_COLWIDTH */
198 field(TEGRA_EMC_BASE + 0x10, 16, 19, 5), /* EMEM_DEVSIZE */
199 field(TEGRA_EMC_BASE + 0x10, 24, 25, 9), /* EMEM_NUMDEV */
200 field(TEGRA_EMC_BASE + 0xc, 24, 24, 21), /* AUTO_PRE_RD */
201 field(TEGRA_EMC_BASE + 0xc, 25, 25, 22), /* AUTO_PRE_WR */
202 field(TEGRA_EMC_BASE + 0xc, 16, 16, 20), /* CLEAR_AP_PREV_SPREQ */
203 field(TEGRA_EMC_BASE + 0xc, 29, 29, 23), /* DRAM_ACPD */
204 field(TEGRA_EMC_BASE + 0xc, 30, 30, 24), /* DRAM_CLKSTOP_PDSR_ONLY */
205 field(TEGRA_EMC_BASE + 0xc, 31, 31, 25), /* DRAM_CLKSTOP */
206 field(TEGRA_EMC_BASE + 0xc, 8, 15, 12), /* PRE_IDLE_CYCLES */
207 field(TEGRA_EMC_BASE + 0xc, 0, 0, 11), /* PRE_IDLE_EN */
208 field(TEGRA_EMC_BASE + 0x2bc, 28, 29, 28), /* CFG_DLL_LOCK_LIMIT */
209 field(TEGRA_EMC_BASE + 0x2bc, 6, 7, 30), /* CFG_DLL_MODE */
210 field(TEGRA_MC_BASE + 0x10c, 0, 0, 26), /* LL_CTRL */
211 field(TEGRA_MC_BASE + 0x10c, 1, 1, 27), /* LL_SEND_BOTH */
212};
213
214static const struct pmc_scratch_field emc_adr_cfg1[] __initdata = {
215 field(TEGRA_EMC_BASE + 0x14, 8, 9, 8), /* EMEM1_BANKWIDTH */
216 field(TEGRA_EMC_BASE + 0x14, 0, 2, 5), /* EMEM1_COLWIDTH */
217 field(TEGRA_EMC_BASE + 0x14, 16, 19, 10), /* EMEM1_DEVSIZE */
218 field(TEGRA_EMC_BASE + 0x2dc, 24, 28, 0), /* TERM_DRVUP */
219 field(TEGRA_APB_MISC_BASE + 0x8d4, 0, 3, 14), /* XM2COMP_VREF_SEL */
220 field(TEGRA_APB_MISC_BASE + 0x8d8, 16, 18, 21), /* XM2VTTGEN_CAL_DRVDN */
221 field(TEGRA_APB_MISC_BASE + 0x8d8, 24, 26, 18), /* XM2VTTGEN_CAL_DRVUP */
222 field(TEGRA_APB_MISC_BASE + 0x8d8, 1, 1, 30), /* XM2VTTGEN_SHORT_PWRGND */
223 field(TEGRA_APB_MISC_BASE + 0x8d8, 0, 0, 31), /* XM2VTTGEN_SHORT */
224 field(TEGRA_APB_MISC_BASE + 0x8d8, 12, 14, 24), /* XM2VTTGEN_VAUXP_LEVEL */
225 field(TEGRA_APB_MISC_BASE + 0x8d8, 8, 10, 27), /* XM2VTTGEN_VCLAMP_LEVEL */
226};
227
228static const struct pmc_scratch_field emc_digital_dll[] __initdata = {
229 field(TEGRA_EMC_BASE + 0x2bc, 1, 1, 23), /* DLI_TRIMMER_EN */
230 field(TEGRA_EMC_BASE + 0x2bc, 0, 0, 22), /* DLL_EN */
231 field(TEGRA_EMC_BASE + 0x2bc, 5, 5, 27), /* DLL_LOWSPEED */
232 field(TEGRA_EMC_BASE + 0x2bc, 2, 2, 24), /* DLL_OVERRIDE_EN */
233 field(TEGRA_EMC_BASE + 0x2bc, 8, 11, 28), /* DLL_UDSET */
234 field(TEGRA_EMC_BASE + 0x2bc, 4, 4, 26), /* PERBYTE_TRIMMER_OVERRIDE */
235 field(TEGRA_EMC_BASE + 0x2bc, 3, 3, 25), /* USE_SINGLE_DLL */
236 field(TEGRA_MC_BASE + 0xc, 0, 21, 0), /* EMEM_SIZE_KB */
237};
238
239static const struct pmc_scratch_field emc_dqs_clktrim[] __initdata = {
240 field(TEGRA_EMC_BASE + 0x2d4, 0, 29, 0), /* DQS0_CLKTRIM - DQS3 + MCLK*/
241 field(TEGRA_APB_MISC_BASE + 0x8e4, 3, 3, 31), /* XM2CFGC_CTT_HIZ_EN */
242 field(TEGRA_APB_MISC_BASE + 0x8e4, 4, 4, 30), /* XM2CFGC_VREF_DQS_EN */
243};
244
245static const struct pmc_scratch_field emc_dq_clktrim[] __initdata = {
246 field(TEGRA_EMC_BASE + 0x2d8, 0, 29, 0),
247 field(TEGRA_APB_MISC_BASE + 0x8e4, 2, 2, 30), /* XM2CFGC_PREEMP_EN */
248 field(TEGRA_APB_MISC_BASE + 0x8e4, 0, 0, 31), /* XM2CFGC_RX_FT_REC_EN */
249};
250
251static const struct pmc_scratch_field emc_dll_xform_dqs[] __initdata = {
252 field(TEGRA_EMC_BASE + 0x2bc, 16, 25, 20), /* CFG_DLL_OVERRIDE_VAL */
253 field(TEGRA_EMC_BASE + 0x2c0, 0, 4, 0), /* DQS_MULT */
254 field(TEGRA_EMC_BASE + 0x2c0, 8, 22, 5), /* DQS_OFFS */
255 field(TEGRA_MC_BASE + 0x10c, 31, 31, 30), /* LL_DRAM_INTERLEAVE */
256};
257
258static const struct pmc_scratch_field emc_odt_rw[] __initdata = {
259 field(TEGRA_EMC_BASE + 0x2c4, 0, 4, 0), /* QUSE_MULT */
260 field(TEGRA_EMC_BASE + 0x2c4, 8, 22, 5), /* QUSE_OFF */
261 field(TEGRA_EMC_BASE + 0xb4, 31, 31, 29), /* DISABLE_ODT_DURING_READ */
262 field(TEGRA_EMC_BASE + 0xb4, 30, 30, 28), /* B4_READ */
263 field(TEGRA_EMC_BASE + 0xb4, 0, 2, 25), /* RD_DELAY */
264 field(TEGRA_EMC_BASE + 0xb0, 31, 31, 24), /* ENABLE_ODT_DURING_WRITE */
265 field(TEGRA_EMC_BASE + 0xb0, 30, 30, 23), /* B4_WRITE */
266 field(TEGRA_EMC_BASE + 0xb0, 0, 2, 20), /* WR_DELAY */
267};
268
269static const struct pmc_scratch_field arbitration_xbar[] __initdata = {
270 field(TEGRA_AHB_GIZMO_BASE + 0xdc, 0, 31, 0),
271};
272
273static const struct pmc_scratch_field emc_zcal[] __initdata = {
274 field(TEGRA_EMC_BASE + 0x2e0, 0, 23, 0), /* ZCAL_REF_INTERVAL */
275 field(TEGRA_EMC_BASE + 0x2e4, 0, 7, 24), /* ZCAL_WAIT_CNT */
276};
277
278static const struct pmc_scratch_field emc_ctt_term[] __initdata = {
279 field(TEGRA_EMC_BASE + 0x2dc, 15, 19, 26), /* TERM_DRVDN */
280 field(TEGRA_EMC_BASE + 0x2dc, 8, 12, 21), /* TERM_OFFSET */
281 field(TEGRA_EMC_BASE + 0x2dc, 31, 31, 31), /* TERM_OVERRIDE */
282 field(TEGRA_EMC_BASE + 0x2dc, 0, 2, 18), /* TERM_SLOPE */
283 field(TEGRA_EMC_BASE + 0x2e8, 16, 23, 8), /* ZQ_MRW_MA */
284 field(TEGRA_EMC_BASE + 0x2e8, 0, 7, 0), /* ZQ_MRW_OP */
285};
286
287static const struct pmc_scratch_field xm2_cfgd[] __initdata = {
288 field(TEGRA_APB_MISC_BASE + 0x8e8, 16, 18, 9), /* CFGD0_DLYIN_TRM */
289 field(TEGRA_APB_MISC_BASE + 0x8e8, 20, 22, 6), /* CFGD1_DLYIN_TRM */
290 field(TEGRA_APB_MISC_BASE + 0x8e8, 24, 26, 3), /* CFGD2_DLYIN_TRM */
291 field(TEGRA_APB_MISC_BASE + 0x8e8, 28, 30, 0), /* CFGD3_DLYIN_TRM */
292 field(TEGRA_APB_MISC_BASE + 0x8e8, 3, 3, 12), /* XM2CFGD_CTT_HIZ_EN */
293 field(TEGRA_APB_MISC_BASE + 0x8e8, 2, 2, 13), /* XM2CFGD_PREEMP_EN */
294 field(TEGRA_APB_MISC_BASE + 0x8e8, 0, 0, 14), /* CM2CFGD_RX_FT_REC_EN */
295};
296
297struct pmc_scratch_reg {
298 const struct pmc_scratch_field *fields;
299 void __iomem *scratch_addr;
300 int num_fields;
301};
302
303#define scratch(offs, field_list) \
304 { \
305 .scratch_addr = IO_ADDRESS(TEGRA_PMC_BASE) + offs, \
306 .fields = field_list, \
307 .num_fields = ARRAY_SIZE(field_list), \
308 }
309
310static const struct pmc_scratch_reg scratch[] __initdata = {
311 scratch(PMC_SCRATCH3, pllx),
312 scratch(PMC_SCRATCH5, emc_0),
313 scratch(PMC_SCRATCH6, emc_1),
314 scratch(PMC_SCRATCH7, emc_2),
315 scratch(PMC_SCRATCH8, emc_3),
316 scratch(PMC_SCRATCH9, emc_4),
317 scratch(PMC_SCRATCH10, emc_5),
318 scratch(PMC_SCRATCH11, emc_6),
319 scratch(PMC_SCRATCH12, emc_dqsib_dly),
320 scratch(PMC_SCRATCH13, emc_quse_dly),
321 scratch(PMC_SCRATCH14, emc_clktrim),
322 scratch(PMC_SCRATCH15, emc_autocal_fbio),
323 scratch(PMC_SCRATCH16, emc_autocal_interval),
324 scratch(PMC_SCRATCH17, emc_cfgs),
325 scratch(PMC_SCRATCH18, emc_adr_cfg1),
326 scratch(PMC_SCRATCH19, emc_digital_dll),
327 scratch(PMC_SCRATCH20, emc_dqs_clktrim),
328 scratch(PMC_SCRATCH21, emc_dq_clktrim),
329 scratch(PMC_SCRATCH22, emc_dll_xform_dqs),
330 scratch(PMC_SCRATCH23, emc_odt_rw),
331 scratch(PMC_SCRATCH25, arbitration_xbar),
332 scratch(PMC_SCRATCH35, emc_zcal),
333 scratch(PMC_SCRATCH36, emc_ctt_term),
334 scratch(PMC_SCRATCH40, xm2_cfgd),
335};
336
337void __init tegra2_lp0_suspend_init(void)
338{
339 int i;
340 int j;
341 unsigned int v;
342 unsigned int r;
343
344 for (i = 0; i < ARRAY_SIZE(scratch); i++) {
345 r = 0;
346
347 for (j = 0; j < scratch[i].num_fields; j++) {
348 v = readl(IO_ADDRESS(scratch[i].fields[j].addr));
349 v >>= scratch[i].fields[j].shift_src;
350 v &= scratch[i].fields[j].mask;
351 v <<= scratch[i].fields[j].shift_dst;
352 r |= v;
353 }
354
355 __raw_writel(r, scratch[i].scratch_addr);
356 }
357 wmb();
358}
359
360struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
361{
362 return NULL;
363}
364EXPORT_SYMBOL(tegra_io_dpd_get);
365
366void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
367{
368 return;
369}
370EXPORT_SYMBOL(tegra_io_dpd_enable);
371
372void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
373{
374 return;
375}
376EXPORT_SYMBOL(tegra_io_dpd_disable);
diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c
new file mode 100644
index 00000000000..a8317422449
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-t3.c
@@ -0,0 +1,529 @@
1/*
2 * arch/arm/mach-tegra/pm-t3.c
3 *
4 * Tegra3 SOC-specific power and cluster management
5 *
6 * Copyright (c) 2009-2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/smp.h>
23#include <linux/interrupt.h>
24#include <linux/clk.h>
25#include <linux/delay.h>
26#include <linux/irq.h>
27#include <linux/device.h>
28#include <linux/module.h>
29#include <linux/clockchips.h>
30
31#include <mach/gpio.h>
32#include <mach/iomap.h>
33#include <mach/irqs.h>
34
35#include <asm/cpu_pm.h>
36#include <asm/hardware/gic.h>
37
38#include <trace/events/power.h>
39
40#include "clock.h"
41#include "cpuidle.h"
42#include "pm.h"
43#include "sleep.h"
44#include "tegra3_emc.h"
45#include "dvfs.h"
46
47#ifdef CONFIG_TEGRA_CLUSTER_CONTROL
48#define CAR_CCLK_BURST_POLICY \
49 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x20)
50
51#define CAR_SUPER_CCLK_DIVIDER \
52 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x24)
53
54#define CAR_CCLKG_BURST_POLICY \
55 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x368)
56
57#define CAR_SUPER_CCLKG_DIVIDER \
58 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x36C)
59
60#define CAR_CCLKLP_BURST_POLICY \
61 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x370)
62#define PLLX_DIV2_BYPASS_LP (1<<16)
63
64#define CAR_SUPER_CCLKLP_DIVIDER \
65 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x374)
66
67#define CAR_BOND_OUT_V \
68 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x390)
69#define CAR_BOND_OUT_V_CPU_G (1<<0)
70#define CAR_BOND_OUT_V_CPU_LP (1<<1)
71
72#define CAR_CLK_ENB_V_SET \
73 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x440)
74#define CAR_CLK_ENB_V_CPU_G (1<<0)
75#define CAR_CLK_ENB_V_CPU_LP (1<<1)
76
77#define CAR_RST_CPUG_CMPLX_SET \
78 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x450)
79
80#define CAR_RST_CPUG_CMPLX_CLR \
81 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x454)
82
83#define CAR_RST_CPULP_CMPLX_SET \
84 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x458)
85
86#define CAR_RST_CPULP_CMPLX_CLR \
87 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x45C)
88
89#define CAR_CLK_CPUG_CMPLX_SET \
90 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x460)
91
92#define CAR_CLK_CPUG_CMPLX_CLR \
93 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x464)
94
95#define CAR_CLK_CPULP_CMPLX_SET \
96 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x468)
97
98#define CAR_CLK_CPULP_CMPLX_CLR \
99 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x46C)
100
101#define CPU_CLOCK(cpu) (0x1<<(8+cpu))
102#define CPU_RESET(cpu) (0x1111ul<<(cpu))
103
104static int cluster_switch_prolog_clock(unsigned int flags)
105{
106 u32 reg;
107 u32 CclkBurstPolicy;
108 u32 SuperCclkDivier;
109
110 /* Read the bond out register containing the G and LP CPUs. */
111 reg = readl(CAR_BOND_OUT_V);
112
113 /* Sync G-PLLX divider bypass with LP (no effect on G, just to prevent
114 LP settings overwrite by save/restore code */
115 CclkBurstPolicy = ~PLLX_DIV2_BYPASS_LP & readl(CAR_CCLKG_BURST_POLICY);
116 CclkBurstPolicy |= PLLX_DIV2_BYPASS_LP & readl(CAR_CCLKLP_BURST_POLICY);
117 writel(CclkBurstPolicy, CAR_CCLKG_BURST_POLICY);
118
119 /* Switching to G? */
120 if (flags & TEGRA_POWER_CLUSTER_G) {
121 /* Do the G CPUs exist? */
122 if (reg & CAR_BOND_OUT_V_CPU_G)
123 return -ENXIO;
124
125 /* Keep G CPU clock policy set by upper laayer, with the
126 exception of the transition via LP1 */
127 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
128 /* In LP1 power mode come up on CLKM (oscillator) */
129 CclkBurstPolicy = readl(CAR_CCLKG_BURST_POLICY);
130 CclkBurstPolicy &= ~0xF;
131 SuperCclkDivier = 0;
132
133 writel(CclkBurstPolicy, CAR_CCLKG_BURST_POLICY);
134 writel(SuperCclkDivier, CAR_SUPER_CCLKG_DIVIDER);
135 }
136
137 /* Hold G CPUs 1-3 in reset after the switch */
138 reg = CPU_RESET(1) | CPU_RESET(2) | CPU_RESET(3);
139 writel(reg, CAR_RST_CPUG_CMPLX_SET);
140
141 /* Take G CPU 0 out of reset after the switch */
142 reg = CPU_RESET(0);
143 writel(reg, CAR_RST_CPUG_CMPLX_CLR);
144
145 /* Disable the clocks on G CPUs 1-3 after the switch */
146 reg = CPU_CLOCK(1) | CPU_CLOCK(2) | CPU_CLOCK(3);
147 writel(reg, CAR_CLK_CPUG_CMPLX_SET);
148
149 /* Enable the clock on G CPU 0 after the switch */
150 reg = CPU_CLOCK(0);
151 writel(reg, CAR_CLK_CPUG_CMPLX_CLR);
152
153 /* Enable the G CPU complex clock after the switch */
154 reg = CAR_CLK_ENB_V_CPU_G;
155 writel(reg, CAR_CLK_ENB_V_SET);
156 }
157 /* Switching to LP? */
158 else if (flags & TEGRA_POWER_CLUSTER_LP) {
159 /* Does the LP CPU exist? */
160 if (reg & CAR_BOND_OUT_V_CPU_LP)
161 return -ENXIO;
162
163 /* Keep LP CPU clock policy set by upper layer, with the
164 exception of the transition via LP1 */
165 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
166 /* In LP1 power mode come up on CLKM (oscillator) */
167 CclkBurstPolicy = readl(CAR_CCLKLP_BURST_POLICY);
168 CclkBurstPolicy &= ~0xF;
169 SuperCclkDivier = 0;
170
171 writel(CclkBurstPolicy, CAR_CCLKLP_BURST_POLICY);
172 writel(SuperCclkDivier, CAR_SUPER_CCLKLP_DIVIDER);
173 }
174
175 /* Take the LP CPU ut of reset after the switch */
176 reg = CPU_RESET(0);
177 writel(reg, CAR_RST_CPULP_CMPLX_CLR);
178
179 /* Enable the clock on the LP CPU after the switch */
180 reg = CPU_CLOCK(0);
181 writel(reg, CAR_CLK_CPULP_CMPLX_CLR);
182
183 /* Enable the LP CPU complex clock after the switch */
184 reg = CAR_CLK_ENB_V_CPU_LP;
185 writel(reg, CAR_CLK_ENB_V_SET);
186 }
187
188 return 0;
189}
190
191void tegra_cluster_switch_prolog(unsigned int flags)
192{
193 unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK;
194 unsigned int current_cluster = is_lp_cluster()
195 ? TEGRA_POWER_CLUSTER_LP
196 : TEGRA_POWER_CLUSTER_G;
197 u32 reg;
198
199 /* Read the flow controler CSR register and clear the CPU switch
200 and immediate flags. If an actual CPU switch is to be performed,
201 re-write the CSR register with the desired values. */
202 reg = readl(FLOW_CTRL_CPU_CSR(0));
203 reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE |
204 FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER);
205
206 /* Program flow controller for immediate wake if requested */
207 if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
208 reg |= FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE;
209
210 /* Do nothing if no switch actions requested */
211 if (!target_cluster)
212 goto done;
213
214 if ((current_cluster != target_cluster) ||
215 (flags & TEGRA_POWER_CLUSTER_FORCE)) {
216 if (current_cluster != target_cluster) {
217 // Set up the clocks for the target CPU.
218 if (cluster_switch_prolog_clock(flags)) {
219 /* The target CPU does not exist */
220 goto done;
221 }
222
223 /* Set up the flow controller to switch CPUs. */
224 reg |= FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER;
225 }
226 }
227
228done:
229 writel(reg, FLOW_CTRL_CPU_CSR(0));
230}
231
232
233static void cluster_switch_epilog_actlr(void)
234{
235 u32 actlr;
236
237 /* TLB maintenance broadcast bit (FW) is stubbed out on LP CPU (reads
238 as zero, writes ignored). Hence, it is not preserved across G=>LP=>G
239 switch by CPU save/restore code, but SMP bit is restored correctly.
240 Synchronize these two bits here after LP=>G transition. Note that
241 only CPU0 core is powered on before and after the switch. See also
242 bug 807595. */
243
244 __asm__("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
245
246 if (actlr & (0x1 << 6)) {
247 actlr |= 0x1;
248 __asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
249 }
250}
251
252static void cluster_switch_epilog_gic(void)
253{
254 unsigned int max_irq, i;
255 void __iomem *gic_base = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
256
257 /* Reprogram the interrupt affinity because the on the LP CPU,
258 the interrupt distributor affinity regsiters are stubbed out
259 by ARM (reads as zero, writes ignored). So when the LP CPU
260 context save code runs, the affinity registers will read
261 as all zero. This causes all interrupts to be effectively
262 disabled when back on the G CPU because they aren't routable
263 to any CPU. See bug 667720 for details. */
264
265 max_irq = readl(gic_base + GIC_DIST_CTR) & 0x1f;
266 max_irq = (max_irq + 1) * 32;
267
268 for (i = 32; i < max_irq; i += 4) {
269 u32 val = 0x01010101;
270#ifdef CONFIG_GIC_SET_MULTIPLE_CPUS
271 unsigned int irq;
272 for (irq = i; irq < (i + 4); irq++) {
273 struct cpumask mask;
274 struct irq_desc *desc = irq_to_desc(irq);
275
276 if (desc && desc->affinity_hint &&
277 desc->irq_data.affinity) {
278 if (cpumask_and(&mask, desc->affinity_hint,
279 desc->irq_data.affinity))
280 val |= (*cpumask_bits(&mask) & 0xff) <<
281 ((irq & 3) * 8);
282 }
283 }
284#endif
285 writel(val, gic_base + GIC_DIST_TARGET + i * 4 / 4);
286 }
287}
288
289void tegra_cluster_switch_epilog(unsigned int flags)
290{
291 u32 reg;
292
293 /* Make sure the switch and immediate flags are cleared in
294 the flow controller to prevent undesirable side-effects
295 for future users of the flow controller. */
296 reg = readl(FLOW_CTRL_CPU_CSR(0));
297 reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE |
298 FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER);
299 writel(reg, FLOW_CTRL_CPU_CSR(0));
300
301 /* Perform post-switch LP=>G clean-up */
302 if (!is_lp_cluster()) {
303 cluster_switch_epilog_actlr();
304 cluster_switch_epilog_gic();
305 }
306
307 #if DEBUG_CLUSTER_SWITCH
308 {
309 /* FIXME: clock functions below are taking mutex */
310 struct clk *c = tegra_get_clock_by_name(
311 is_lp_cluster() ? "cpu_lp" : "cpu_g");
312 DEBUG_CLUSTER(("%s: %s freq %lu\r\n", __func__,
313 is_lp_cluster() ? "LP" : "G", clk_get_rate(c)));
314 }
315 #endif
316}
317
318int tegra_cluster_control(unsigned int us, unsigned int flags)
319{
320 static ktime_t last_g2lp;
321
322 unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK;
323 unsigned int current_cluster = is_lp_cluster()
324 ? TEGRA_POWER_CLUSTER_LP
325 : TEGRA_POWER_CLUSTER_G;
326 unsigned long irq_flags;
327
328 if ((target_cluster == TEGRA_POWER_CLUSTER_MASK) || !target_cluster)
329 return -EINVAL;
330
331 if (num_online_cpus() > 1)
332 return -EBUSY;
333
334 if ((current_cluster == target_cluster)
335 && !(flags & TEGRA_POWER_CLUSTER_FORCE))
336 return -EEXIST;
337
338 if (target_cluster == TEGRA_POWER_CLUSTER_G)
339 if (!is_g_cluster_present())
340 return -EPERM;
341
342 trace_power_start(POWER_PSTATE, target_cluster, 0);
343
344 if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
345 us = 0;
346
347 DEBUG_CLUSTER(("%s(LP%d): %s->%s %s %s %d\r\n", __func__,
348 (flags & TEGRA_POWER_SDRAM_SELFREFRESH) ? 1 : 2,
349 is_lp_cluster() ? "LP" : "G",
350 (target_cluster == TEGRA_POWER_CLUSTER_G) ? "G" : "LP",
351 (flags & TEGRA_POWER_CLUSTER_IMMEDIATE) ? "immediate" : "",
352 (flags & TEGRA_POWER_CLUSTER_FORCE) ? "force" : "",
353 us));
354
355 local_irq_save(irq_flags);
356
357 if (current_cluster != target_cluster && !timekeeping_suspended) {
358 ktime_t now = ktime_get();
359 if (target_cluster == TEGRA_POWER_CLUSTER_G) {
360 s64 t = ktime_to_us(ktime_sub(now, last_g2lp));
361 s64 t_off = tegra_cpu_power_off_time();
362 if (t_off > t)
363 udelay((unsigned int)(t_off - t));
364
365 tegra_dvfs_rail_on(tegra_cpu_rail, now);
366
367 } else {
368 last_g2lp = now;
369 tegra_dvfs_rail_off(tegra_cpu_rail, now);
370 }
371 }
372
373 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
374 if (us)
375 tegra_lp2_set_trigger(us);
376
377 tegra_cluster_switch_prolog(flags);
378 tegra_suspend_dram(TEGRA_SUSPEND_LP1, flags);
379 tegra_cluster_switch_epilog(flags);
380
381 if (us)
382 tegra_lp2_set_trigger(0);
383 } else {
384 int cpu = 0;
385
386 tegra_set_cpu_in_lp2(0);
387 cpu_pm_enter();
388 if (!timekeeping_suspended)
389 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
390 &cpu);
391 tegra_idle_lp2_last(0, flags);
392 if (!timekeeping_suspended)
393 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
394 &cpu);
395 cpu_pm_exit();
396 tegra_clear_cpu_in_lp2(0);
397 }
398 local_irq_restore(irq_flags);
399
400 DEBUG_CLUSTER(("%s: %s\r\n", __func__, is_lp_cluster() ? "LP" : "G"));
401
402 return 0;
403}
404#endif
405
406#ifdef CONFIG_PM_SLEEP
407
408void tegra_lp0_suspend_mc(void)
409{
410 /* Since memory frequency after LP0 is restored to boot rate
411 mc timing is saved during init, not on entry to LP0. Keep
412 this hook just in case, anyway */
413}
414
415void tegra_lp0_resume_mc(void)
416{
417 tegra_mc_timing_restore();
418}
419
420void tegra_lp0_cpu_mode(bool enter)
421{
422 static bool entered_on_g = false;
423 unsigned int flags;
424
425 if (enter)
426 entered_on_g = !is_lp_cluster();
427
428 if (entered_on_g) {
429 flags = enter ? TEGRA_POWER_CLUSTER_LP : TEGRA_POWER_CLUSTER_G;
430 flags |= TEGRA_POWER_CLUSTER_IMMEDIATE;
431 tegra_cluster_control(0, flags);
432 pr_info("Tegra: switched to %s cluster\n", enter ? "LP" : "G");
433 }
434}
435#endif
436
437#define IO_DPD_INFO(_name, _index, _bit) \
438 { \
439 .name = _name, \
440 .io_dpd_reg_index = _index, \
441 .io_dpd_bit = _bit, \
442 }
443
444/* PMC IO DPD register offsets */
445#define APBDEV_PMC_IO_DPD_REQ_0 0x1b8
446#define APBDEV_PMC_IO_DPD_STATUS_0 0x1bc
447#define APBDEV_PMC_SEL_DPD_TIM_0 0x1c8
448#define APBDEV_DPD_ENABLE_LSB 30
449#define APBDEV_DPD2_ENABLE_LSB 5
450#define PMC_DPD_SAMPLE 0x20
451
452struct tegra_io_dpd tegra_list_io_dpd[] = {
453/* Empty DPD list - sd dpd entries removed */
454};
455
456struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
457{
458 int i;
459 const char *name = dev ? dev_name(dev) : NULL;
460 if (name) {
461 for (i = 0; i < (sizeof(tegra_list_io_dpd) /
462 sizeof(struct tegra_io_dpd)); i++) {
463 if (!(strncmp(tegra_list_io_dpd[i].name, name,
464 strlen(name)))) {
465 return &tegra_list_io_dpd[i];
466 }
467 }
468 }
469 dev_info(dev, "Error: tegra3 io dpd not supported for %s\n",
470 ((name) ? name : "NULL"));
471 return NULL;
472}
473EXPORT_SYMBOL(tegra_io_dpd_get);
474
475static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
476static DEFINE_SPINLOCK(tegra_io_dpd_lock);
477
478void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
479{
480 unsigned int enable_mask;
481 unsigned int dpd_status;
482 unsigned int dpd_enable_lsb;
483
484 if ((!hnd))
485 return;
486 spin_lock(&tegra_io_dpd_lock);
487 dpd_enable_lsb = (hnd->io_dpd_reg_index) ? APBDEV_DPD2_ENABLE_LSB :
488 APBDEV_DPD_ENABLE_LSB;
489 writel(0x1, pmc + PMC_DPD_SAMPLE);
490 writel(0x10, pmc + APBDEV_PMC_SEL_DPD_TIM_0);
491 enable_mask = ((1 << hnd->io_dpd_bit) | (2 << dpd_enable_lsb));
492 writel(enable_mask, pmc + (APBDEV_PMC_IO_DPD_REQ_0 +
493 hnd->io_dpd_reg_index * 8));
494 udelay(1);
495 dpd_status = readl(pmc + (APBDEV_PMC_IO_DPD_STATUS_0 +
496 hnd->io_dpd_reg_index * 8));
497 if (!(dpd_status & (1 << hnd->io_dpd_bit)))
498 pr_info("Error: dpd%d enable failed, status=%#x\n",
499 (hnd->io_dpd_reg_index + 1), dpd_status);
500 /* Sample register must be reset before next sample operation */
501 writel(0x0, pmc + PMC_DPD_SAMPLE);
502 spin_unlock(&tegra_io_dpd_lock);
503 return;
504}
505EXPORT_SYMBOL(tegra_io_dpd_enable);
506
507void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
508{
509 unsigned int enable_mask;
510 unsigned int dpd_status;
511 unsigned int dpd_enable_lsb;
512
513 if ((!hnd))
514 return;
515 spin_lock(&tegra_io_dpd_lock);
516 dpd_enable_lsb = (hnd->io_dpd_reg_index) ? APBDEV_DPD2_ENABLE_LSB :
517 APBDEV_DPD_ENABLE_LSB;
518 enable_mask = ((1 << hnd->io_dpd_bit) | (1 << dpd_enable_lsb));
519 writel(enable_mask, pmc + (APBDEV_PMC_IO_DPD_REQ_0 +
520 hnd->io_dpd_reg_index * 8));
521 dpd_status = readl(pmc + (APBDEV_PMC_IO_DPD_STATUS_0 +
522 hnd->io_dpd_reg_index * 8));
523 if (dpd_status & (1 << hnd->io_dpd_bit))
524 pr_info("Error: dpd%d disable failed, status=%#x\n",
525 (hnd->io_dpd_reg_index + 1), dpd_status);
526 spin_unlock(&tegra_io_dpd_lock);
527 return;
528}
529EXPORT_SYMBOL(tegra_io_dpd_disable);
diff --git a/arch/arm/mach-tegra/powerdetect.c b/arch/arm/mach-tegra/powerdetect.c
new file mode 100644
index 00000000000..6a2a5779458
--- /dev/null
+++ b/arch/arm/mach-tegra/powerdetect.c
@@ -0,0 +1,348 @@
1/*
2 * arch/arm/mach-tegra/powerdetect.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/delay.h>
22#include <linux/spinlock.h>
23#include <linux/io.h>
24#include <linux/err.h>
25#include <linux/notifier.h>
26#include <linux/regulator/consumer.h>
27
28#include <mach/iomap.h>
29
30#include "board.h"
31#include "fuse.h"
32
33#define PMC_PWR_IO_DISABLE 0x44
34#define PMC_PWR_DET_ENABLE 0x48
35#define PMC_PWR_DET_LATCH 0x4C
36#define PMC_PWR_DET_VAL 0xE4
37
38struct pwr_detect_cell {
39 const char *reg_id;
40 u32 pwrdet_mask;
41 u32 pwrio_mask;
42 u32 package_mask;
43
44 struct notifier_block regulator_nb;
45};
46
47static bool pwrdet_rails_found;
48static bool pwrdet_always_on;
49static bool pwrio_always_on;
50static u32 pwrdet_val;
51static u32 pwrio_val;
52static u32 pwrio_disabled_mask;
53
54static DEFINE_SPINLOCK(pwr_lock);
55
56static void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
57
58static inline void pmc_writel(u32 val, unsigned long addr)
59{
60 writel(val, (u32)pmc_base + addr);
61}
62static inline u32 pmc_readl(unsigned long addr)
63{
64 return readl((u32)pmc_base + addr);
65}
66
67
68#define POWER_CELL(_reg_id, _pwrdet_mask, _pwrio_mask, _package_mask) \
69 { \
70 .reg_id = _reg_id, \
71 .pwrdet_mask = _pwrdet_mask, \
72 .pwrio_mask = _pwrio_mask, \
73 .package_mask = _package_mask, \
74 }
75
76/* Some IO pads does not have power detect cells, but still can/should be
77 * turned off when no power - set pwrdet_mask=0 for such pads */
78static struct pwr_detect_cell pwr_detect_cells[] = {
79 POWER_CELL("pwrdet_nand", (0x1 << 1), (0x1 << 1), 0xFFFFFFFF),
80 POWER_CELL("pwrdet_uart", (0x1 << 2), (0x1 << 2), 0xFFFFFFFF),
81 POWER_CELL("pwrdet_bb", (0x1 << 3), (0x1 << 3), 0xFFFFFFFF),
82#ifdef CONFIG_ARCH_TEGRA_2x_SOC
83 POWER_CELL("pwrdet_vi", 0, (0x1 << 4), 0xFFFFFFFF),
84#else
85 /* Tegra3 VI is connected on MID package only (id = 1, mask = 0x2) */
86 POWER_CELL("pwrdet_vi", 0, (0x1 << 4), 0x00000002),
87#endif
88 POWER_CELL("pwrdet_audio", (0x1 << 5), (0x1 << 5), 0xFFFFFFFF),
89 POWER_CELL("pwrdet_lcd", (0x1 << 6), (0x1 << 6), 0xFFFFFFFF),
90#ifdef CONFIG_ARCH_TEGRA_2x_SOC
91 POWER_CELL("pwrdet_sd", 0, (0x1 << 8), 0xFFFFFFFF),
92#endif
93 POWER_CELL("pwrdet_mipi", 0, (0x1 << 9), 0xFFFFFFFF),
94#ifndef CONFIG_ARCH_TEGRA_2x_SOC
95 POWER_CELL("pwrdet_cam", (0x1 << 10), (0x1 << 10), 0xFFFFFFFF),
96 POWER_CELL("pwrdet_pex_ctl", (0x1 << 11), (0x1 << 11), 0xFFFFFFFF),
97 POWER_CELL("pwrdet_sdmmc1", (0x1 << 12), (0x1 << 12), 0xFFFFFFFF),
98 POWER_CELL("pwrdet_sdmmc3", (0x1 << 13), (0x1 << 13), 0xFFFFFFFF),
99 POWER_CELL("pwrdet_sdmmc4", 0, (0x1 << 14), 0xFFFFFFFF),
100#endif
101};
102
103static void pwr_detect_reset(u32 pwrdet_mask)
104{
105 pmc_writel(pwrdet_mask, PMC_PWR_DET_ENABLE);
106 barrier();
107 pmc_writel(pwrdet_mask, PMC_PWR_DET_VAL);
108
109 pmc_readl(PMC_PWR_DET_VAL);
110 pmc_writel(0, PMC_PWR_DET_ENABLE);
111}
112
113static void pwr_detect_start(u32 pwrdet_mask)
114{
115 pmc_writel(pwrdet_mask, PMC_PWR_DET_ENABLE);
116 udelay(4);
117
118 pmc_writel(1, PMC_PWR_DET_LATCH);
119 pmc_readl(PMC_PWR_DET_LATCH);
120}
121
122static void pwr_detect_latch(void)
123{
124 pmc_writel(0, PMC_PWR_DET_LATCH);
125
126 pmc_readl(PMC_PWR_DET_VAL);
127 pmc_writel(0, PMC_PWR_DET_ENABLE);
128}
129
130static void pwr_io_enable(u32 pwrio_mask)
131{
132 u32 val = pmc_readl(PMC_PWR_IO_DISABLE);
133 val &= ~pwrio_mask;
134 pmc_writel(val, PMC_PWR_IO_DISABLE);
135}
136
137static void pwr_io_disable(u32 pwrio_mask)
138{
139 u32 val = pmc_readl(PMC_PWR_IO_DISABLE);
140 val |= pwrio_mask;
141 pmc_writel(val, PMC_PWR_IO_DISABLE);
142}
143
144static int pwrdet_always_on_set(const char *arg, const struct kernel_param *kp)
145{
146 int ret;
147 unsigned long flags;
148
149 spin_lock_irqsave(&pwr_lock, flags);
150
151 ret = param_set_bool(arg, kp);
152 if (ret) {
153 spin_unlock_irqrestore(&pwr_lock, flags);
154 return ret;
155 }
156
157 if (pwrdet_always_on)
158 pwr_detect_start(0xFFFFFFFF);
159 else
160 pwr_detect_latch();
161
162 spin_unlock_irqrestore(&pwr_lock, flags);
163 return 0;
164}
165
166static int pwrio_always_on_set(const char *arg, const struct kernel_param *kp)
167{
168 int ret;
169 unsigned long flags;
170
171 spin_lock_irqsave(&pwr_lock, flags);
172
173 ret = param_set_bool(arg, kp);
174 if (ret) {
175 spin_unlock_irqrestore(&pwr_lock, flags);
176 return ret;
177 }
178
179 if (pwrio_always_on)
180 pwr_io_enable(0xFFFFFFFF);
181 else
182 pwr_io_disable(pwrio_disabled_mask);
183
184 spin_unlock_irqrestore(&pwr_lock, flags);
185 return 0;
186}
187
188static int pwrdet_always_on_get(char *buffer, const struct kernel_param *kp)
189{
190 return param_get_bool(buffer, kp);
191}
192
193static struct kernel_param_ops pwrdet_always_on_ops = {
194 .set = pwrdet_always_on_set,
195 .get = pwrdet_always_on_get,
196};
197static struct kernel_param_ops pwrio_always_on_ops = {
198 .set = pwrio_always_on_set,
199 .get = pwrdet_always_on_get,
200};
201module_param_cb(pwrdet_always_on, &pwrdet_always_on_ops,
202 &pwrdet_always_on, 0644);
203module_param_cb(pwrio_always_on, &pwrio_always_on_ops,
204 &pwrio_always_on, 0644);
205
206static int pwrdet_val_get(char *buffer, const struct kernel_param *kp)
207{
208 pwrdet_val = pmc_readl(PMC_PWR_DET_VAL);
209 return param_get_ulong(buffer, kp);
210}
211static struct kernel_param_ops pwrdet_val_ops = {
212 .get = pwrdet_val_get,
213};
214module_param_cb(pwrdet_val, &pwrdet_val_ops, &pwrdet_val, 0444);
215
216static int pwrio_val_get(char *buffer, const struct kernel_param *kp)
217{
218 pwrio_val = pmc_readl(PMC_PWR_IO_DISABLE);
219 return param_get_ulong(buffer, kp);
220}
221static struct kernel_param_ops pwrio_val_ops = {
222 .get = pwrio_val_get,
223};
224module_param_cb(pwrio_val, &pwrio_val_ops, &pwrio_val, 0444);
225
226
227static int pwrdet_notify_cb(
228 struct notifier_block *nb, unsigned long event, void *v)
229{
230 unsigned long flags;
231 struct pwr_detect_cell *cell;
232
233 if (!pwrdet_rails_found)
234 return NOTIFY_OK;
235
236 cell = container_of(nb, struct pwr_detect_cell, regulator_nb);
237
238 spin_lock_irqsave(&pwr_lock, flags);
239
240 if (event & REGULATOR_EVENT_PRE_ENABLE) {
241 pwrio_disabled_mask &= ~cell->pwrio_mask;
242 if (!pwrio_always_on)
243 pwr_io_enable(cell->pwrio_mask);
244 }
245 if (event & (REGULATOR_EVENT_PRE_ENABLE |
246 REGULATOR_EVENT_OUT_PRECHANGE)) {
247 if (!pwrdet_always_on && cell->pwrdet_mask)
248 pwr_detect_reset(cell->pwrdet_mask);
249 }
250 if (event & (REGULATOR_EVENT_POST_ENABLE |
251 REGULATOR_EVENT_OUT_POSTCHANGE)) {
252 if (!pwrdet_always_on && cell->pwrdet_mask) {
253 pwr_detect_start(cell->pwrdet_mask);
254 pwr_detect_latch();
255 }
256 }
257 if (event & (REGULATOR_EVENT_DISABLE |
258 REGULATOR_EVENT_FORCE_DISABLE)) {
259 pwrio_disabled_mask |= cell->pwrio_mask;
260 if (!pwrio_always_on)
261 pwr_io_disable(cell->pwrio_mask);
262 }
263
264 pr_debug("tegra: %s: event %lu, pwrdet 0x%x, pwrio 0x%x\n",
265 cell->reg_id, event,
266 pmc_readl(PMC_PWR_DET_VAL), pmc_readl(PMC_PWR_IO_DISABLE));
267 spin_unlock_irqrestore(&pwr_lock, flags);
268
269 return NOTIFY_OK;
270}
271
272static int __init pwr_detect_cell_init_one(
273 struct pwr_detect_cell *cell, u32 *disabled_mask)
274{
275 int ret;
276 struct regulator *regulator = regulator_get(NULL, cell->reg_id);
277
278 if (IS_ERR(regulator))
279 return PTR_ERR(regulator);
280
281 cell->regulator_nb.notifier_call = pwrdet_notify_cb;
282 ret = regulator_register_notifier(regulator, &cell->regulator_nb);
283 if (ret) {
284 regulator_put(regulator);
285 return ret;
286 }
287
288 if (!regulator_is_enabled(regulator))
289 *disabled_mask |= cell->pwrio_mask;
290
291 regulator_put(regulator);
292 return 0;
293}
294
295int __init tegra_pwr_detect_cell_init(void)
296{
297 int i, ret;
298 u32 package_mask;
299 unsigned long flags;
300 bool rails_found = true;
301
302 i = tegra_package_id();
303 if ((i != -1) && (i & (~0x1F))) {
304 pr_err("tegra: not supported package id %d - io power detection"
305 " is left always on\n", i);
306 return 0;
307 }
308 package_mask = (i == -1) ? i : (0x1 << i);
309
310 for (i = 0; i < ARRAY_SIZE(pwr_detect_cells); i++) {
311 struct pwr_detect_cell *cell = &pwr_detect_cells[i];
312
313 if (!(cell->package_mask & package_mask)) {
314 pwrio_disabled_mask |= cell->pwrio_mask;
315 continue;
316 }
317
318 ret = pwr_detect_cell_init_one(cell, &pwrio_disabled_mask);
319 if (ret) {
320 pr_err("tegra: failed to map regulator to power detect"
321 " cell %s(%d)\n", cell->reg_id, ret);
322 rails_found = false;
323 }
324 }
325
326 if (!rails_found) {
327 pr_err("tegra: failed regulators mapping - io power detection"
328 " is left always on\n");
329 return 0;
330 }
331 pwrdet_rails_found = true;
332
333 /* Latch initial i/o power levels, disable all detection cells
334 and not powered interfaces */
335 spin_lock_irqsave(&pwr_lock, flags);
336 if (!pwrdet_always_on)
337 pwr_detect_latch();
338 if (!pwrio_always_on)
339 pwr_io_disable(pwrio_disabled_mask);
340 spin_unlock_irqrestore(&pwr_lock, flags);
341
342 pr_info("tegra: started io power detection dynamic control\n");
343 pr_info("tegra: NO_IO_POWER setting 0x%x\n", pwrio_disabled_mask);
344
345 return 0;
346}
347
348fs_initcall(tegra_pwr_detect_cell_init);
diff --git a/arch/arm/mach-tegra/pwm.c b/arch/arm/mach-tegra/pwm.c
new file mode 100644
index 00000000000..a268c391cb2
--- /dev/null
+++ b/arch/arm/mach-tegra/pwm.c
@@ -0,0 +1,296 @@
1/*
2 * arch/arm/mach-tegra/pwm.c
3 *
4 * Tegra pulse-width-modulation controller driver
5 *
6 * Copyright (c) 2010, NVIDIA Corporation.
7 * Based on arch/arm/plat-mxc/pwm.c by Sascha Hauer <s.hauer@pengutronix.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23
24#include <linux/clk.h>
25#include <linux/err.h>
26#include <linux/io.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/platform_device.h>
30#include <linux/pwm.h>
31#include <linux/slab.h>
32
33#define PWM_ENABLE (1 << 31)
34#define PWM_DUTY_WIDTH 8
35#define PWM_DUTY_SHIFT 16
36#define PWM_SCALE_WIDTH 13
37#define PWM_SCALE_SHIFT 0
38
39struct pwm_device {
40 struct list_head node;
41 struct platform_device *pdev;
42
43 const char *label;
44 struct clk *clk;
45
46 int clk_enb;
47 void __iomem *mmio_base;
48
49 unsigned int in_use;
50 unsigned int id;
51};
52
53static DEFINE_MUTEX(pwm_lock);
54static LIST_HEAD(pwm_list);
55
56static inline int pwm_writel(struct pwm_device *pwm, unsigned long val)
57{
58 int rc;
59
60 rc = clk_enable(pwm->clk);
61 if (WARN_ON(rc))
62 return rc;
63 writel(val, pwm->mmio_base);
64 clk_disable(pwm->clk);
65 return 0;
66}
67
68int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
69{
70 unsigned long long c;
71 unsigned long rate, hz;
72 u32 val = 0;
73
74 /* convert from duty_ns / period_ns to a fixed number of duty
75 * ticks per (1 << PWM_DUTY_WIDTH) cycles. */
76 c = duty_ns * ((1 << PWM_DUTY_WIDTH) - 1);
77 do_div(c, period_ns);
78
79 val = (u32)c << PWM_DUTY_SHIFT;
80
81 /* compute the prescaler value for which (1 << PWM_DUTY_WIDTH)
82 * cycles at the PWM clock rate will take period_ns nanoseconds. */
83 rate = clk_get_rate(pwm->clk) >> PWM_DUTY_WIDTH;
84 hz = 1000000000ul / period_ns;
85
86 rate = (rate + (hz / 2)) / hz;
87
88 if (rate >> PWM_SCALE_WIDTH)
89 return -EINVAL;
90 /* Due to the PWM divider is zero-based, we need to minus 1 to get desired frequency*/
91 if (rate>0)
92 rate--;
93
94 val |= (rate << PWM_SCALE_SHIFT);
95
96 /* the struct clk may be shared across multiple PWM devices, so
97 * only enable the PWM if this device has been enabled */
98 if (pwm->clk_enb)
99 val |= PWM_ENABLE;
100
101 return pwm_writel(pwm, val);
102}
103EXPORT_SYMBOL(pwm_config);
104
105int pwm_enable(struct pwm_device *pwm)
106{
107 int rc = 0;
108
109 mutex_lock(&pwm_lock);
110 if (!pwm->clk_enb) {
111 rc = clk_enable(pwm->clk);
112 if (!rc) {
113 u32 val = readl(pwm->mmio_base);
114 writel(val | PWM_ENABLE, pwm->mmio_base);
115 pwm->clk_enb = 1;
116 }
117 }
118 mutex_unlock(&pwm_lock);
119
120 return rc;
121}
122EXPORT_SYMBOL(pwm_enable);
123
124void pwm_disable(struct pwm_device *pwm)
125{
126 mutex_lock(&pwm_lock);
127 if (pwm->clk_enb) {
128 u32 val = readl(pwm->mmio_base);
129 writel(val & ~PWM_ENABLE, pwm->mmio_base);
130 clk_disable(pwm->clk);
131 pwm->clk_enb = 0;
132 } else
133 dev_warn(&pwm->pdev->dev, "%s called on disabled PWM\n",
134 __func__);
135 mutex_unlock(&pwm_lock);
136}
137EXPORT_SYMBOL(pwm_disable);
138
139struct pwm_device *pwm_request(int pwm_id, const char *label)
140{
141 struct pwm_device *pwm;
142 int found = 0;
143
144 mutex_lock(&pwm_lock);
145
146 list_for_each_entry(pwm, &pwm_list, node) {
147 if (pwm->id == pwm_id) {
148 found = 1;
149 break;
150 }
151 }
152
153 if (found) {
154 if (!pwm->in_use) {
155 pwm->in_use = 1;
156 pwm->label = label;
157 } else
158 pwm = ERR_PTR(-EBUSY);
159 } else
160 pwm = ERR_PTR(-ENOENT);
161
162 mutex_unlock(&pwm_lock);
163
164 return pwm;
165}
166EXPORT_SYMBOL(pwm_request);
167
168void pwm_free(struct pwm_device *pwm)
169{
170 mutex_lock(&pwm_lock);
171 if (pwm->in_use) {
172 pwm->in_use = 0;
173 pwm->label = NULL;
174 } else
175 dev_warn(&pwm->pdev->dev, "PWM device already freed\n");
176
177 mutex_unlock(&pwm_lock);
178}
179EXPORT_SYMBOL(pwm_free);
180
181static int tegra_pwm_probe(struct platform_device *pdev)
182{
183 struct pwm_device *pwm;
184 struct resource *r;
185 int ret;
186
187 pwm = kzalloc(sizeof(*pwm), GFP_KERNEL);
188 if (!pwm) {
189 dev_err(&pdev->dev, "failed to allocate memory\n");
190 return -ENOMEM;
191 }
192 pwm->clk = clk_get(&pdev->dev, NULL);
193
194 if (IS_ERR(pwm->clk)) {
195 ret = PTR_ERR(pwm->clk);
196 goto err_free;
197 }
198
199 pwm->clk_enb = 0;
200 pwm->in_use = 0;
201 pwm->id = pdev->id;
202 pwm->pdev = pdev;
203
204 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
205 if (!r) {
206 dev_err(&pdev->dev, "no memory resources defined\n");
207 ret = -ENODEV;
208 goto err_put_clk;
209 }
210
211 r = request_mem_region(r->start, resource_size(r), pdev->name);
212 if (!r) {
213 dev_err(&pdev->dev, "failed to request memory\n");
214 ret = -EBUSY;
215 goto err_put_clk;
216 }
217
218 pwm->mmio_base = ioremap(r->start, resource_size(r));
219 if (!pwm->mmio_base) {
220 dev_err(&pdev->dev, "failed to ioremap() region\n");
221 ret = -ENODEV;
222 goto err_free_mem;
223 }
224
225 platform_set_drvdata(pdev, pwm);
226
227 mutex_lock(&pwm_lock);
228 list_add_tail(&pwm->node, &pwm_list);
229 mutex_unlock(&pwm_lock);
230
231 return 0;
232
233err_free_mem:
234 release_mem_region(r->start, resource_size(r));
235err_put_clk:
236 clk_put(pwm->clk);
237err_free:
238 kfree(pwm);
239 return ret;
240}
241
242static int __devexit tegra_pwm_remove(struct platform_device *pdev)
243{
244 struct pwm_device *pwm = platform_get_drvdata(pdev);
245 struct resource *r;
246 int rc;
247
248 if (WARN_ON(!pwm))
249 return -ENODEV;
250
251 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
252
253 mutex_lock(&pwm_lock);
254 if (pwm->in_use) {
255 mutex_unlock(&pwm_lock);
256 return -EBUSY;
257 }
258 list_del(&pwm->node);
259 mutex_unlock(&pwm_lock);
260
261 rc = pwm_writel(pwm, 0);
262
263 iounmap(pwm->mmio_base);
264 release_mem_region(r->start, resource_size(r));
265
266 if (pwm->clk_enb)
267 clk_disable(pwm->clk);
268
269 clk_put(pwm->clk);
270
271 kfree(pwm);
272 return rc;
273}
274
275static struct platform_driver tegra_pwm_driver = {
276 .driver = {
277 .name = "tegra_pwm",
278 },
279 .probe = tegra_pwm_probe,
280 .remove = __devexit_p(tegra_pwm_remove),
281};
282
283static int __init tegra_pwm_init(void)
284{
285 return platform_driver_register(&tegra_pwm_driver);
286}
287subsys_initcall(tegra_pwm_init);
288
289static void __exit tegra_pwm_exit(void)
290{
291 platform_driver_unregister(&tegra_pwm_driver);
292}
293module_exit(tegra_pwm_exit);
294
295MODULE_LICENSE("GPL v2");
296MODULE_AUTHOR("NVIDIA Corporation");
diff --git a/arch/arm/mach-tegra/sleep-t2.S b/arch/arm/mach-tegra/sleep-t2.S
new file mode 100644
index 00000000000..f70360628f3
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep-t2.S
@@ -0,0 +1,574 @@
1/*
2 * arch/arm/mach-tegra/include/mach/sleep-t2.S
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 * Copyright (c) 2011, Google, Inc.
6 *
7 * Author: Colin Cross <ccross@android.com>
8 * Gary King <gking@nvidia.com>
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 as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25#include <linux/const.h>
26#include <linux/init.h>
27#include <linux/linkage.h>
28
29#include <asm/assembler.h>
30#include <asm/cache.h>
31#include <asm/domain.h>
32#include <asm/memory.h>
33#include <asm/page.h>
34#include <asm/ptrace.h>
35#include <asm/asm-offsets.h>
36#include <asm/glue-cache.h>
37#include <asm/glue-proc.h>
38#include <asm/system.h>
39
40#include <mach/iomap.h>
41#include <mach/io.h>
42
43#include "asm_macros.h"
44#include "sleep.h"
45
46#define EMC_CFG 0xc
47#define EMC_ADR_CFG 0x10
48#define EMC_REFRESH 0x70
49#define EMC_NOP 0xdc
50#define EMC_SELF_REF 0xe0
51#define EMC_REQ_CTRL 0x2b0
52#define EMC_EMC_STATUS 0x2b4
53
54#define CLK_RESET_CCLK_BURST 0x20
55#define CLK_RESET_CCLK_DIVIDER 0x24
56#define CLK_RESET_SCLK_BURST 0x28
57#define CLK_RESET_SCLK_DIVIDER 0x2c
58
59#define CLK_RESET_PLLC_BASE 0x80
60#define CLK_RESET_PLLM_BASE 0x90
61#define CLK_RESET_PLLP_BASE 0xa0
62#define CLK_RESET_PLLP_OUTA 0xa4
63#define CLK_RESET_PLLP_OUTB 0xa8
64#define CLK_RESET_PLLP_MISC 0xac
65#define CLK_RESET_PLLX_BASE 0xe0
66#define CLK_RESET_PLLX_MISC 0xe4
67
68#define CLK_RESET_RST_CPU_CMPLX_SET 0x340
69
70#define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
71#define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS + IO_CPU_VIRT)
72#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS + IO_PPSB_VIRT)
73
74#ifdef CONFIG_HOTPLUG_CPU
75/*
76 * tegra2_hotplug_shutdown(void)
77 *
78 * puts the current cpu in reset
79 * should never return
80 */
81ENTRY(tegra2_hotplug_shutdown)
82 mov r6, lr
83 bl tegra_cpu_exit_coherency
84
85 /* Put this CPU into reset. */
86 cpu_id r0
87 bl tegra2_cpu_reset
88 mov pc, r6
89ENDPROC(tegra2_hotplug_shutdown)
90#endif
91
92#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
93/*
94 * tegra2_cpu_reset(int cpu)
95 *
96 * r0 is cpu to reset
97 *
98 * puts the specified CPU in wait-for-event mode on the flow controller
99 * and puts the CPU in reset
100 * can be called on the current cpu or another cpu
101 * if called on the current cpu, does not return
102 * MUST NOT BE CALLED FOR CPU 0.
103 *
104 * corrupts r0-r3, r12
105 */
106ENTRY(tegra2_cpu_reset)
107 cmp r0, #0
108 moveq pc, lr @ must not be called for CPU 0
109
110 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
111 mov r12, #CPU_RESETTABLE
112 str r12, [r1]
113
114 cpu_to_halt_reg r1, r0
115 mov32 r3, TEGRA_FLOW_CTRL_VIRT
116 mov r2, #FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME
117 str r2, [r3, r1] @ put flow controller in wait event mode
118 ldr r2, [r3, r1]
119 isb
120 dsb
121 movw r1, 0x1011
122 mov r1, r1, lsl r0
123 mov32 r3, TEGRA_CLK_RESET_VIRT
124 str r1, [r3, #CLK_RESET_RST_CPU_CMPLX_SET] @ put slave CPU in reset
125 isb
126 dsb
127 cpu_id r3
128 cmp r3, r0
129 beq .
130 mov pc, lr
131ENDPROC(tegra2_cpu_reset)
132#endif
133
134#ifdef CONFIG_PM_SLEEP
135/*
136 * tegra2_cpu_clear_resettable(void)
137 *
138 * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when
139 * it is expected that the secondary CPU will be idle soon.
140 */
141ENTRY(tegra2_cpu_clear_resettable)
142 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
143 mov r12, #CPU_NOT_RESETTABLE
144 str r12, [r1]
145 mov pc, lr
146ENDPROC(tegra2_cpu_clear_resettable)
147
148/*
149 * tegra2_cpu_set_resettable_soon(void)
150 *
151 * Called to set the "resettable soon" flag in PMC_SCRATCH41 when
152 * it is expected that the secondary CPU will be idle soon.
153 */
154ENTRY(tegra2_cpu_set_resettable_soon)
155 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
156 mov r12, #CPU_RESETTABLE_SOON
157 str r12, [r1]
158 mov pc, lr
159ENDPROC(tegra2_cpu_set_resettable_soon)
160
161/*
162 * tegra2_cpu_is_resettable_soon(void)
163 *
164 * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been
165 * set because it is expected that the secondary CPU will be idle soon.
166 */
167ENTRY(tegra2_cpu_is_resettable_soon)
168 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
169 ldr r12, [r1]
170 cmp r12, #CPU_RESETTABLE_SOON
171 moveq r0, #1
172 movne r0, #0
173 mov pc, lr
174ENDPROC(tegra2_cpu_is_resettable_soon)
175
176/*
177 * tegra2_sleep_core(unsigned long v2p)
178 *
179 * enters suspend in LP0 or LP1 by turning off the mmu and jumping to
180 * tegra2_tear_down_core in IRAM
181 */
182ENTRY(tegra2_sleep_core)
183 mov r12, pc @ return here is via r12
184 b tegra_cpu_save
185 mov32 r1, tegra2_tear_down_core
186 mov32 r2, tegra2_iram_start
187 sub r1, r1, r2
188 mov32 r2, TEGRA_IRAM_CODE_AREA
189 add r1, r1, r2
190 b tegra_turn_off_mmu
191ENDPROC(tegra2_sleep_core)
192
193/*
194 * tegra2_sleep_wfi(unsigned long v2p)
195 */
196ENTRY(tegra2_sleep_wfi)
197 mrc p15, 0, r2, c1, c0, 1 @ save actlr before exiting coherency
198 mov r12, pc @ return here is via r12
199 b tegra_cpu_save
200 mov r11, r2
201
202 mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
203 mov r3, #CPU_RESETTABLE
204 str r3, [r0]
205
206 bl tegra_cpu_wfi
207
208 mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
209 mov r3, #CPU_NOT_RESETTABLE
210 str r3, [r0]
211
212 /*
213 * cpu may be reset while in wfi, which will return through
214 * tegra_resume to tegra_cpu_resume_phys to tegra_cpu_resume
215 * or interrupt may wake wfi, which will return here
216 * cpu state is unchanged - MMU is on, cache is on, coherency
217 * is off, and the data cache is off
218 *
219 * r11 contains the original actlr
220 */
221
222 mov sp, r7 @ restore SP for aborted suspend
223 bl tegra_pen_lock
224
225 mov32 r3, TEGRA_PMC_VIRT
226 add r0, r3, #PMC_SCRATCH41
227 mov r3, #CPU_NOT_RESETTABLE
228 str r3, [r0]
229
230 bl tegra_pen_unlock
231
232#if USE_TEGRA_CPU_SUSPEND
233 /* Enable the data cache and SMP coherency */
234 mrc p15, 0, r10, c1, c0, 0
235 orr r10, r10, #CR_C
236 dsb
237 mcr p15, 0, r10, c1, c0, 0
238 isb
239 mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
240
241#else
242 mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
243#endif
244 /* Invalidate the TLBs & BTAC */
245 mov r1, #0
246 mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
247 mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC
248 dsb
249 isb
250
251 @ the cpu was running with coherency disabled, caches may be out of date
252#ifdef MULTI_CACHE
253 mov32 r10, cpu_cache
254 mov lr, pc
255 ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
256#else
257 bl __cpuc_flush_kern_all
258#endif
259
260#ifdef CONFIG_CACHE_L2X0
261 cpu_id r2
262 cmp r2, #0
263 bne no_l2_sync
264 /* Issue a PL310 cache sync operation */
265 dsb
266 mov32 r2, TEGRA_PL310_VIRT
267 movw r1, 0x730 @ cache sync
268 add r2, r2, r1
269 mov r1, #0
270 str r1, [r2]
271
272no_l2_sync:
273#endif
274
275 pop_ctx_regs r0, r1 @ restore context registers
276 mov pc, lr
277ENDPROC(tegra2_sleep_wfi)
278
279/*
280 * tegra2_tear_down_cpu
281 *
282 * Switches the CPU cluster to PLL-P and enters sleep.
283 */
284ENTRY(tegra2_tear_down_cpu)
285 bl tegra_cpu_pllp
286 b tegra2_enter_sleep
287ENDPROC(tegra2_tear_down_cpu)
288
289/* START OF ROUTINES COPIED TO IRAM */
290 .align L1_CACHE_SHIFT
291 .globl tegra2_iram_start
292tegra2_iram_start:
293
294/*
295 * tegra2_lp1_reset
296 *
297 * reset vector for LP1 restore; copied into IRAM during suspend.
298 * brings the system back up to a safe starting point (SDRAM out of
299 * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
300 * system clock running on the same PLL that it suspended at), and
301 * jumps to tegra_lp2_startup to restore PLLX and virtual addressing.
302 * physical address of tegra_lp2_startup expected to be stored in
303 * PMC_SCRATCH41
304 *
305 * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA AND MUST BE FIRST.
306 */
307ENTRY(tegra2_lp1_reset)
308 /*
309 * the CPU and system bus are running at 32KHz and executing from
310 * IRAM when this code is executed; immediately switch to CLKM and
311 * enable PLLP.
312 */
313 mov32 r0, TEGRA_CLK_RESET_BASE
314#ifndef CONFIG_TRUSTED_FOUNDATIONS
315 /* secure code handles 32KHz to CLKM/OSC clock switch */
316 mov r1, #(1 << 28)
317 str r1, [r0, #CLK_RESET_SCLK_BURST]
318 str r1, [r0, #CLK_RESET_CCLK_BURST]
319 mov r1, #0
320 str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
321 str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
322#endif
323 ldr r1, [r0, #CLK_RESET_PLLM_BASE]
324 tst r1, #(1 << 30)
325 orreq r1, r1, #(1 << 30)
326 streq r1, [r0, #CLK_RESET_PLLM_BASE]
327 ldr r1, [r0, #CLK_RESET_PLLP_BASE]
328 tst r1, #(1 << 30)
329 orreq r1, r1, #(1 << 30)
330 streq r1, [r0, #CLK_RESET_PLLP_BASE]
331 ldr r1, [r0, #CLK_RESET_PLLC_BASE]
332 tst r1, #(1 << 30)
333 orreq r1, r1, #(1 << 30)
334 streq r1, [r0, #CLK_RESET_PLLC_BASE]
335
336 adr r2, tegra2_sdram_pad_address
337 adr r4, tegra2_sdram_pad_save
338 mov r5, #0
339
340padload:
341 ldr r0, [r2, r5] @ r0 is emc register address
342
343 ldr r1, [r4, r5]
344 str r1, [r0] @ set emc register to safe vals
345
346 add r5, r5, #4
347 ldr r0, tegra2_sdram_pad_size
348 cmp r0, r5
349 bne padload
350
351padload_done:
352 mov32 r7, TEGRA_TMRUS_BASE
353 ldr r1, [r7]
354 add r1, r1, #0xff @ 255uS delay for PLL stabilization
355
3561: ldr r0, [r7]
357 cmp r0, r1
358 dmb
359 bmi 1b
360
361 adr r4, tegra2_sclk_save
362 ldr r4, [r4]
363 mov32 r0, TEGRA_CLK_RESET_BASE
364 str r4, [r0, #CLK_RESET_SCLK_BURST]
365 ldr r4, =((1 << 28) | (4)) @ burst policy is PLLP
366 str r4, [r0, #CLK_RESET_CCLK_BURST]
367
368 mov32 r0, TEGRA_EMC_BASE
369 ldr r1, [r0, #EMC_CFG]
370 bic r1, r1, #(1 << 31) @ disable DRAM_CLK_STOP
371 str r1, [r0, #EMC_CFG]
372
373 mov r1, #0
374 str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
375 mov r1, #1
376 str r1, [r0, #EMC_NOP]
377 str r1, [r0, #EMC_NOP]
378 str r1, [r0, #EMC_REFRESH]
379
380 ldr r1, [r0, #EMC_ADR_CFG]
381 tst r1, #(0x3 << 24)
382 moveq r1, #(0x1 << 8) @ just 1 device
383 movne r1, #(0x3 << 8) @ 2 devices
384
385exit_selfrefresh_loop:
386 ldr r2, [r0, #EMC_EMC_STATUS]
387 ands r2, r2, r1
388 bne exit_selfrefresh_loop
389
390 mov r1, #0
391 str r1, [r0, #EMC_REQ_CTRL]
392
393 mov32 r0, TEGRA_PMC_BASE
394 ldr r0, [r0, #PMC_SCRATCH41]
395 mov pc, r0
396ENDPROC(tegra2_lp1_reset)
397
398/*
399 * tegra2_tear_down_core
400 *
401 * copied into and executed from IRAM
402 * puts memory in self-refresh for LP0 and LP1
403 */
404tegra2_tear_down_core:
405 bl tegra2_sdram_self_refresh
406 bl tegra2_cpu_clk32k
407 b tegra2_enter_sleep
408
409/*
410 * tegra2_cpu_clk32k
411 *
412 * In LP0 and LP1 all plls will be turned off. Switch the CPU and system clock
413 * to the 32khz clock (clks)
414 */
415tegra2_cpu_clk32k:
416 /* start by jumping to clkm to safely disable PLLs, then jump
417 * to clks */
418 mov r0, #(1 << 28)
419 str r0, [r5, #CLK_RESET_SCLK_BURST]
420 str r0, [r5, #CLK_RESET_CCLK_BURST]
421 mov r0, #0
422 str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
423 str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
424
425 /* 2 us delay between changing sclk and disabling PLLs */
426 mov32 r7, TEGRA_TMRUS_BASE
427 ldr r1, [r7]
428 add r1, r1, #3
429
4301: ldr r0, [r7]
431 cmp r0, r1
432 dmb
433 bmi 1b
434
435 /* switch to CLKS */
436 mov r0, #0 /* burst policy = 32KHz */
437 str r0, [r5, #CLK_RESET_SCLK_BURST]
438
439 /* disable PLLP, PLLM, PLLC in LP0 and LP1 states */
440 ldr r0, [r5, #CLK_RESET_PLLM_BASE]
441 bic r0, r0, #(1 << 30)
442 str r0, [r5, #CLK_RESET_PLLM_BASE]
443 ldr r0, [r5, #CLK_RESET_PLLP_BASE]
444 bic r0, r0, #(1 << 30)
445 str r0, [r5, #CLK_RESET_PLLP_BASE]
446 ldr r0, [r5, #CLK_RESET_PLLC_BASE]
447 bic r0, r0, #(1 << 30)
448 str r0, [r5, #CLK_RESET_PLLC_BASE]
449 mov pc, lr
450
451/*
452 * tegra2_enter_sleep
453 *
454 * uses flow controller to enter sleep state
455 * executes from IRAM with SDRAM in selfrefresh when target state is LP0 and LP1
456 * executes from SDRAM with target state is LP2
457 */
458tegra2_enter_sleep:
459 mov32 r7, TEGRA_TMRUS_BASE
460 ldr r1, [r7]
461 mov32 r4, TEGRA_PMC_BASE
462 str r1, [r4, #PMC_SCRATCH38]
463 dsb
464 mov32 r6, TEGRA_FLOW_CTRL_BASE
465
466 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
467 orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
468 cpu_id r1
469 cpu_to_halt_reg r1, r1
470 str r0, [r6, r1]
471 dsb
472 ldr r0, [r6, r1] /* memory barrier */
473
474halted: dsb
475 wfe /* CPU should be power gated here */
476 isb
477 b halted
478
479/*
480 * tegra2_sdram_self_refresh
481 *
482 * called with MMU off and caches disabled
483 * puts sdram in self refresh
484 * must execute from IRAM
485 */
486tegra2_sdram_self_refresh:
487 mov32 r1, TEGRA_EMC_BASE
488 mov r2, #3
489 str r2, [r1, #EMC_REQ_CTRL] @ stall incoming DRAM requests
490
491emcidle:ldr r2, [r1, #EMC_EMC_STATUS]
492 tst r2, #4
493 beq emcidle
494
495 mov r2, #1
496 str r2, [r1, #EMC_SELF_REF]
497
498 ldr r2, [r1, #EMC_ADR_CFG]
499 tst r2, #(0x3 << 24)
500 moveq r2, #(0x1 << 8) @ just 1 device
501 movne r2, #(0x3 << 8) @ 2 devices
502
503emcself:ldr r3, [r1, #EMC_EMC_STATUS]
504 and r3, r3, r2
505 cmp r3, r2
506 bne emcself @ loop until DDR in self-refresh
507
508 adr r2, tegra2_sdram_pad_address
509 adr r3, tegra2_sdram_pad_safe
510 adr r4, tegra2_sdram_pad_save
511 mov r5, #0
512
513padsave:
514 ldr r0, [r2, r5] @ r0 is emc register address
515
516 ldr r1, [r0]
517 str r1, [r4, r5] @ save emc register
518
519 ldr r1, [r3, r5]
520 str r1, [r0] @ set emc register to safe vals
521
522 add r5, r5, #4
523 ldr r0, tegra2_sdram_pad_size
524 cmp r0, r5
525 bne padsave
526padsave_done:
527
528 mov32 r5, TEGRA_CLK_RESET_BASE
529 ldr r0, [r5, #CLK_RESET_SCLK_BURST]
530 adr r2, tegra2_sclk_save
531 str r0, [r2]
532 dsb
533 mov pc, lr
534
535tegra2_sdram_pad_address:
536 .word TEGRA_APB_MISC_BASE + 0x8c8 /* XM2CFGCPADCTRL */
537 .word TEGRA_APB_MISC_BASE + 0x8cc /* XM2CFGDPADCTRL */
538 .word TEGRA_APB_MISC_BASE + 0x8d0 /* XM2CLKCFGPADCTRL */
539 .word TEGRA_APB_MISC_BASE + 0x8d4 /* XM2COMPPADCTRL */
540 .word TEGRA_APB_MISC_BASE + 0x8d8 /* XM2VTTGENPADCTRL */
541 .word TEGRA_APB_MISC_BASE + 0x8e4 /* XM2CFGCPADCTRL2 */
542 .word TEGRA_APB_MISC_BASE + 0x8e8 /* XM2CFGDPADCTRL2 */
543
544tegra2_sdram_pad_size:
545 .word tegra2_sdram_pad_size - tegra2_sdram_pad_address
546
547tegra2_sdram_pad_safe:
548 .word 0x8
549 .word 0x8
550 .word 0x0
551 .word 0x8
552 .word 0x5500
553 .word 0x08080040
554 .word 0x0
555
556tegra2_sclk_save:
557 .word 0x0
558
559tegra2_sdram_pad_save:
560 .word 0
561 .word 0
562 .word 0
563 .word 0
564 .word 0
565 .word 0
566 .word 0
567
568 .ltorg
569/* dummy symbol for end of IRAM */
570 .align L1_CACHE_SHIFT
571 .globl tegra2_iram_end
572tegra2_iram_end:
573 b .
574#endif
diff --git a/arch/arm/mach-tegra/sleep-t3.S b/arch/arm/mach-tegra/sleep-t3.S
new file mode 100644
index 00000000000..5ea7334c45f
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep-t3.S
@@ -0,0 +1,715 @@
1/*
2 * arch/arm/mach-tegra/include/mach/sleep-t3.S
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/const.h>
22#include <linux/init.h>
23#include <linux/linkage.h>
24
25#include <asm/assembler.h>
26#include <asm/cache.h>
27#include <asm/domain.h>
28#include <asm/memory.h>
29#include <asm/page.h>
30#include <asm/ptrace.h>
31#include <asm/asm-offsets.h>
32#include <asm/glue-cache.h>
33#include <asm/glue-proc.h>
34#include <asm/system.h>
35
36#include <mach/iomap.h>
37#include <mach/io.h>
38
39#include "asm_macros.h"
40#include "sleep.h"
41#include "clock.h"
42
43#define EMC_CFG 0xc
44#define EMC_ADR_CFG 0x10
45#define EMC_TIMING_CONTROL 0x28
46#define EMC_REFRESH 0x70
47#define EMC_NOP 0xdc
48#define EMC_SELF_REF 0xe0
49#define EMC_MRW 0xe8
50#define EMC_REQ_CTRL 0x2b0
51#define EMC_EMC_STATUS 0x2b4
52#define EMC_FBIO_CFG5 0x104
53#define EMC_AUTO_CAL_CONFIG 0x2a4
54#define EMC_AUTO_CAL_INTERVAL 0x2a8
55#define EMC_AUTO_CAL_STATUS 0x2ac
56#define EMC_CFG_DIG_DLL 0x2bc
57#define EMC_ZCAL_INTERVAL 0x2e0
58#define EMC_ZQ_CAL 0x2ec
59#define EMC_XM2VTTGENPADCTRL 0x310
60#define EMC_XM2VTTGENPADCTRL2 0x314
61
62#define PMC_CTRL 0x0
63#define PMC_CTRL_SIDE_EFFECT_LP0 (1 << 14) /* enter LP0 when CPU pwr gated */
64
65#define PMC_PWRGATE_TOGGLE 0x30
66#define PMC_REMOVE_CLAMPING_CMD 0x34
67#define PMC_PWRGATE_STATUS 0x38
68
69#define PMC_PWRGATE_PARTID_L2C (0x5)
70
71#define PMC_IO_DPD_REQ 0x1b8
72#define PMC_IO_DPD_STATUS 0x1bc
73
74#define CLK_RESET_CCLK_BURST 0x20
75#define CLK_RESET_CCLK_DIVIDER 0x24
76#define CLK_RESET_SCLK_BURST 0x28
77#define CLK_RESET_SCLK_DIVIDER 0x2c
78
79#define CLK_RESET_PLLC_BASE 0x80
80#define CLK_RESET_PLLM_BASE 0x90
81#define CLK_RESET_PLLP_BASE 0xa0
82#define CLK_RESET_PLLA_BASE 0xb0
83#define CLK_RESET_PLLX_BASE 0xe0
84
85#define CLK_RESET_PLLC_MISC 0x8c
86#define CLK_RESET_PLLM_MISC 0x9c
87#define CLK_RESET_PLLP_MISC 0xac
88#define CLK_RESET_PLLA_MISC 0xbc
89#define CLK_RESET_PLLX_MISC 0xe4
90
91#define CLK_RESET_PLLP_OUTA 0xa4
92#define CLK_RESET_PLLP_OUTB 0xa8
93
94#define PMC_PLLP_WB0_OVERRIDE 0xf8
95
96#define CLK_RESET_CLK_SOURCE_MSELECT 0x3b4
97
98#define MSELECT_CLKM (0x3 << 30)
99
100#if USE_PLL_LOCK_BITS
101#define LOCK_DELAY PLL_POST_LOCK_DELAY
102#else
103#define LOCK_DELAY 0xff /* 255uS delay for PLL stabilization */
104#endif
105
106#define USE_PLLP_ON_SLEEP_ENTRY 0
107
108.macro emc_device_mask, rd, base
109 ldr \rd, [\base, #EMC_ADR_CFG]
110 tst \rd, #0x1
111 moveq \rd, #(0x1<<8) @ just 1 device
112 movne \rd, #(0x3<<8) @ 2 devices
113.endm
114
115.macro emc_timing_update, rd, base
116 mov \rd, #1
117 str \rd, [\base, #EMC_TIMING_CONTROL]
1181001:
119 ldr \rd, [\base, #EMC_EMC_STATUS]
120 tst \rd, #(0x1<<23) @ wait until EMC_STATUS_TIMING_UPDATE_STALLED is clear
121 bne 1001b
122.endm
123
124#ifdef CONFIG_HOTPLUG_CPU
125/*
126 * tegra3_hotplug_shutdown(void)
127 *
128 * Powergates the current CPU.
129 * Should never return.
130 */
131ENTRY(tegra3_hotplug_shutdown)
132 mov r6, lr
133 bl tegra_cpu_exit_coherency
134
135 /* Powergate this CPU. */
136 mov r0, #TEGRA_POWER_HOTPLUG_SHUTDOWN
137 bl tegra3_cpu_reset
138 mov pc, r6 @ should never get here
139ENDPROC(tegra3_hotplug_shutdown)
140#endif
141
142#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
143/*
144 * tegra3_cpu_reset(unsigned long flags)
145 *
146 * Puts the current CPU in wait-for-event mode on the flow controller
147 * and powergates it -- flags (in R0) indicate the request type.
148 * Must never be called for CPU 0.
149 *
150 * corrupts r0-r4, r12
151 */
152ENTRY(tegra3_cpu_reset)
153 cpu_id r3
154 cmp r3, #0
155 moveq pc, lr @ Must never be called for CPU 0
156
157 mov32 r12, TEGRA_FLOW_CTRL_VIRT
158 cpu_to_csr_reg r1, r3
159 add r1, r1, r12 @ virtual CSR address for this CPU
160 cpu_to_halt_reg r2, r3
161 add r2, r2, r12 @ virtual HALT_EVENTS address for this CPU
162
163 /* Clear this CPU's "event" and "interrupt" flags and power gate
164 it when halting but not before it is in the "WFE" state. */
165 movw r12, FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | FLOW_CTRL_CSR_ENABLE
166 mov r4, #(1 << 4)
167 orr r12, r12, r4, lsl r3
168 str r12, [r1]
169
170 /* Halt this CPU. */
171 mov r3, #0x400
172delay_1:
173 subs r3, r3, #1 @ delay as a part of wfe war.
174 bge delay_1;
175 cpsid a @ disable imprecise aborts.
176 ldr r3, [r1] @ read CSR
177 str r3, [r1] @ clear CSR
178 tst r0, #TEGRA_POWER_HOTPLUG_SHUTDOWN
179 moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2
180 movne r3, #FLOW_CTRL_WAITEVENT @ For hotplug
181 str r3, [r2]
182 ldr r0, [r2]
183 b wfe_war
184
185__cpu_reset_again:
186 dsb
187 .align 5
188 wfe @ CPU should be power gated here
189wfe_war:
190 b __cpu_reset_again
191
192 /* 38 nop's, which fills reset of wfe cache line and 4 more cachelines with nop*/
193 .rept 38
194 nop
195 .endr
196 b . @ should never get here
197
198ENDPROC(tegra3_cpu_reset)
199#endif
200
201#ifdef CONFIG_PM_SLEEP
202
203/*
204 * tegra3_sleep_core(unsigned long v2p)
205 *
206 * enters suspend in LP0 or LP1 by turning off the mmu and jumping to
207 * tegra3_tear_down_core in IRAM
208 */
209ENTRY(tegra3_sleep_core)
210 mov r12, pc @ return here is via r12
211 b tegra_cpu_save
212
213 /* preload all the address literals that are needed for the
214 * CPU power-gating process, to avoid loads from SDRAM (which are
215 * not supported once SDRAM is put into self-refresh.
216 * LP0 / LP1 use physical address, since the MMU needs to be
217 * disabled before putting SDRAM into self-refresh to avoid
218 * memory access due to page table walks */
219 mov32 r4, TEGRA_PMC_BASE
220 mov32 r5, TEGRA_CLK_RESET_BASE
221 mov32 r6, TEGRA_FLOW_CTRL_BASE
222 mov32 r7, TEGRA_TMRUS_BASE
223
224 mov32 r1, tegra3_tear_down_core
225 mov32 r2, tegra3_iram_start
226 sub r1, r1, r2
227 mov32 r2, TEGRA_IRAM_CODE_AREA
228 add r1, r1, r2
229 b tegra_turn_off_mmu
230ENDPROC(tegra3_sleep_core)
231
232/*
233 * tegra3_sleep_cpu_secondary(unsigned long v2p)
234 *
235 * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
236 */
237ENTRY(tegra3_sleep_cpu_secondary)
238 mov r12, pc @ return here is via r12
239 b tegra_cpu_save
240
241 /* Powergate this CPU. */
242 mov r0, #0 @ power mode flags (!hotplug)
243 bl tegra3_cpu_reset
244 b . @ should never get here
245ENDPROC(tegra3_sleep_cpu_secondary)
246
247/*
248 * tegra3_tear_down_cpu
249 *
250 * Switches the CPU cluster to PLL-P and enters sleep.
251 */
252ENTRY(tegra3_tear_down_cpu)
253 mov32 r4, TEGRA_PMC_BASE
254 mov32 r5, TEGRA_CLK_RESET_BASE
255 mov32 r6, TEGRA_FLOW_CTRL_BASE
256 mov32 r7, TEGRA_TMRUS_BASE
257#if USE_PLLP_ON_SLEEP_ENTRY
258 bl tegra_cpu_pllp
259#endif
260 b tegra3_enter_sleep
261ENDPROC(tegra3_tear_down_cpu)
262
263/* START OF ROUTINES COPIED TO IRAM */
264 .align L1_CACHE_SHIFT
265 .globl tegra3_iram_start
266tegra3_iram_start:
267
268/*
269 * tegra3_lp1_reset
270 *
271 * reset vector for LP1 restore; copied into IRAM during suspend.
272 * brings the system back up to a safe starting point (SDRAM out of
273 * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
274 * system clock running on the same PLL that it suspended at), and
275 * jumps to tegra_lp2_startup to restore PLLX and virtual addressing.
276 * physical address of tegra_lp2_startup expected to be stored in
277 * PMC_SCRATCH41
278 *
279 * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA AND MUST BE FIRST.
280 */
281.macro pll_enable, rd, car, base, misc
282 ldr \rd, [\car, #\base]
283 tst \rd, #(1<<30)
284 orreq \rd, \rd, #(1<<30)
285 streq \rd, [\car, #\base]
286#if USE_PLL_LOCK_BITS
287 ldr \rd, [\car, #\misc]
288 orr \rd, \rd, #(1<<18)
289 str \rd, [\car, #\misc]
290#endif
291.endm
292
293.macro pll_locked, rd, car, base
294#if USE_PLL_LOCK_BITS
2951:
296 ldr \rd, [\car, #\base]
297 tst \rd, #(1<<27)
298 beq 1b
299#endif
300.endm
301
302ENTRY(tegra3_lp1_reset)
303 /* the CPU and system bus are running at 32KHz and executing from
304 * IRAM when this code is executed; immediately switch to CLKM and
305 * enable PLLP, PLLM, PLLC, PLLA and PLLX. */
306 mov32 r0, TEGRA_CLK_RESET_BASE
307#ifndef CONFIG_TRUSTED_FOUNDATIONS
308 /* secure code handles 32KHz to CLKM/OSC clock switch */
309 mov r1, #(1<<28)
310 str r1, [r0, #CLK_RESET_SCLK_BURST]
311 str r1, [r0, #CLK_RESET_CCLK_BURST]
312 mov r1, #0
313 str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
314 str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
315#endif
316 /* enable PLLM via PMC */
317 mov32 r2, TEGRA_PMC_BASE
318 ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
319 orr r1, r1, #(1<<12)
320 str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
321
322 pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC
323 pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC
324 pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC
325 pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC
326 pll_enable r1, r0, CLK_RESET_PLLX_BASE, CLK_RESET_PLLX_MISC
327
328 pll_locked r1, r0, CLK_RESET_PLLM_BASE
329 pll_locked r1, r0, CLK_RESET_PLLP_BASE
330 pll_locked r1, r0, CLK_RESET_PLLA_BASE
331 pll_locked r1, r0, CLK_RESET_PLLC_BASE
332 pll_locked r1, r0, CLK_RESET_PLLX_BASE
333
334 mov32 r7, TEGRA_TMRUS_BASE
335 ldr r1, [r7]
336 add r1, r1, #LOCK_DELAY
337 wait_until r1, r7, r3
338
339 add r5, pc, #tegra3_sdram_pad_save-(.+8) @ r5 reserved for pad base
340
341 ldr r4, [r5, #0x18]
342 str r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
343
344 ldr r4, [r5, #0x1C]
345 str r4, [r0, #CLK_RESET_SCLK_BURST]
346
347 mov32 r4, ((1<<28) | (8)) @ burst policy is PLLX
348 str r4, [r0, #CLK_RESET_CCLK_BURST]
349
350#if defined (CONFIG_CACHE_L2X0)
351 /* power up L2 */
352 ldr r0, [r2, #PMC_PWRGATE_STATUS]
353 tst r0, #(1<<PMC_PWRGATE_PARTID_L2C)
354 bne powerup_l2_done
355 movw r0, #(1<<8) | PMC_PWRGATE_PARTID_L2C
356 str r0, [r2, #PMC_PWRGATE_TOGGLE]
357powerup_l2_wait:
358 ldr r0, [r2, #PMC_PWRGATE_STATUS]
359 tst r0, #(1<<PMC_PWRGATE_PARTID_L2C)
360 beq powerup_l2_wait
361powerup_l2_done:
362 mov r0, #PMC_PWRGATE_PARTID_L2C
363 str r0, [r2, #PMC_REMOVE_CLAMPING_CMD]
364#endif
365
366 mov32 r0, TEGRA_EMC_BASE @ r0 reserved for emc base
367
368 ldr r1, [r5, #0x14] @ PMC_IO_DPD_STATUS
369 mvn r1, r1
370 bic r1, r1, #(0x1<<31)
371 orr r1, r1, #(0x1<<30)
372 str r1, [r2, #PMC_IO_DPD_REQ]
373 ldr r1, [r5, #0xC]
374 str r1, [r0, #EMC_XM2VTTGENPADCTRL]
375 ldr r1, [r5, #0x10]
376 str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
377 ldr r1, [r5, #0x8]
378 str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
379
380 ldr r1, [r0, #EMC_CFG_DIG_DLL]
381 orr r1, r1, #(0x1<<30) @ set DLL_RESET
382 str r1, [r0, #EMC_CFG_DIG_DLL]
383
384 emc_timing_update r1, r0
385
386 ldr r1, [r0, #EMC_AUTO_CAL_CONFIG]
387 orr r1, r1, #(0x1<<31) @ set AUTO_CAL_ACTIVE
388 str r1, [r0, #EMC_AUTO_CAL_CONFIG]
389
390emc_wait_audo_cal_onetime:
391 ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
392 tst r1, #(0x1<<31) @ wait until AUTO_CAL_ACTIVE is clear
393 bne emc_wait_audo_cal_onetime
394
395 ldr r1, [r0, #EMC_CFG]
396 bic r1, r1, #(1<<31) @ disable DRAM_CLK_STOP
397 str r1, [r0, #EMC_CFG]
398
399 mov r1, #0
400 str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
401 mov r1, #1
402 str r1, [r0, #EMC_NOP]
403 str r1, [r0, #EMC_NOP]
404 str r1, [r0, #EMC_REFRESH]
405
406 emc_device_mask r1, r0
407
408exit_selfrefresh_loop:
409 ldr r2, [r0, #EMC_EMC_STATUS]
410 ands r2, r2, r1
411 bne exit_selfrefresh_loop
412
413 lsr r1, r1, #8 @ devSel, bit0:dev0 bit1:dev1
414
415 mov32 r7, TEGRA_TMRUS_BASE
416 ldr r2, [r0, #EMC_FBIO_CFG5]
417
418 and r2, r2, #3
419 cmp r2, #2
420 beq emc_lpddr2
421
422 mov32 r2, 0x80000011
423 str r2, [r0, #EMC_ZQ_CAL]
424 ldr r2, [r7]
425 add r2, r2, #10
426 wait_until r2, r7, r3
427
428 tst r1, #2
429 beq zcal_done
430
431 mov32 r2, 0x40000011
432 str r2, [r0, #EMC_ZQ_CAL]
433 ldr r2, [r7]
434 add r2, r2, #10
435 wait_until r2, r7, r3
436 b zcal_done
437
438emc_lpddr2:
439
440 mov32 r2, 0x800A00AB
441 str r2, [r0, #EMC_MRW]
442 ldr r2, [r7]
443 add r2, r2, #1
444 wait_until r2, r7, r3
445
446 tst r1, #2
447 beq zcal_done
448
449 mov32 r2, 0x400A00AB
450 str r2, [r0, #EMC_MRW]
451 ldr r2, [r7]
452 add r2, r2, #1
453 wait_until r2, r7, r3
454
455zcal_done:
456
457 mov r1, #0
458 str r1, [r0, #EMC_REQ_CTRL]
459 ldr r1, [r5, #0x4]
460 str r1, [r0, #EMC_ZCAL_INTERVAL]
461 ldr r1, [r5, #0x0]
462 str r1, [r0, #EMC_CFG]
463
464 mov32 r0, TEGRA_PMC_BASE
465 ldr r0, [r0, #PMC_SCRATCH41]
466 mov pc, r0
467ENDPROC(tegra3_lp1_reset)
468
469 .align L1_CACHE_SHIFT
470 .type tegra3_sdram_pad_save, %object
471tegra3_sdram_pad_save:
472 .word 0
473 .word 0
474 .word 0
475 .word 0
476 .word 0
477 .word 0
478 .word 0
479 .word 0
480
481tegra3_sdram_pad_address:
482 .word TEGRA_EMC_BASE + EMC_CFG @0x0
483 .word TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
484 .word TEGRA_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
485 .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
486 .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
487 .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
488 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
489 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
490
491tegra3_sdram_pad_size:
492 .word tegra3_sdram_pad_address - tegra3_sdram_pad_save
493
494/*
495 * tegra3_tear_down_core
496 *
497 * copied into and executed from IRAM
498 * puts memory in self-refresh for LP0 and LP1
499 */
500tegra3_tear_down_core:
501 bl tegra3_sdram_self_refresh
502 bl tegra3_cpu_clk32k
503 b tegra3_enter_sleep
504
505/*
506 * tegra3_cpu_clk32k
507 *
508 * In LP0 and LP1 all plls will be turned off. Switch the CPU and system clock
509 * to the 32khz clock (clks)
510 * r4 = TEGRA_PMC_BASE
511 * r5 = TEGRA_CLK_RESET_BASE
512 * r6 = TEGRA_FLOW_CTRL_BASE
513 * r7 = TEGRA_TMRUS_BASE
514 */
515tegra3_cpu_clk32k:
516 ldr r0, [r4, #PMC_CTRL]
517 tst r0, #PMC_CTRL_SIDE_EFFECT_LP0
518 beq lp1_clocks_prepare
519
520 /* enable PLLM via PMC in LP0 */
521 ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
522 orr r0, r0, #((1<<12) | (1 << 11))
523 str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
524 mov pc, lr
525
526 /* start by jumping to clkm to safely disable PLLs, then jump
527 * to clks */
528lp1_clocks_prepare:
529 mov r0, #(1 << 28)
530 str r0, [r5, #CLK_RESET_SCLK_BURST]
531 str r0, [r5, #CLK_RESET_CCLK_BURST]
532 mov r0, #0
533 str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
534 str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
535
536 /* switch the clock source for mselect to be CLK_M */
537 ldr r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
538 orr r0, r0, #MSELECT_CLKM
539 str r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
540
541 /* 2 us delay between changing sclk and disabling PLLs */
542 wait_for_us r1, r7, r9
543 add r1, r1, #2
544 wait_until r1, r7, r9
545
546#if 1
547 /* switch to CLKS */
548 mov r0, #0 /* burst policy = 32KHz */
549 str r0, [r5, #CLK_RESET_SCLK_BURST]
550#endif
551
552 /* disable PLLM via PMC in LP1 */
553 ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
554 bic r0, r0, #(1<<12)
555 str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
556 b powerdown_pll_pcx
557
558powerdown_pll_pcx:
559 /* disable PLLP, PLLA, PLLC, and PLLX in LP0 and LP1 states */
560 ldr r0, [r4, #PMC_CTRL]
561 tst r0, #PMC_CTRL_SIDE_EFFECT_LP0
562 beq powerdown_pll_cx
563 ldr r0, [r5, #CLK_RESET_PLLP_BASE]
564 bic r0, r0, #(1<<30)
565 str r0, [r5, #CLK_RESET_PLLP_BASE]
566 ldr r0, [r5, #CLK_RESET_PLLA_BASE]
567 bic r0, r0, #(1<<30)
568 str r0, [r5, #CLK_RESET_PLLA_BASE]
569powerdown_pll_cx:
570 ldr r0, [r5, #CLK_RESET_PLLC_BASE]
571 bic r0, r0, #(1<<30)
572 str r0, [r5, #CLK_RESET_PLLC_BASE]
573 ldr r0, [r5, #CLK_RESET_PLLX_BASE]
574 bic r0, r0, #(1<<30)
575 str r0, [r5, #CLK_RESET_PLLX_BASE]
576
577 mov pc, lr
578
579/*
580 * tegra3_enter_sleep
581 *
582 * uses flow controller to enter sleep state
583 * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
584 * executes from SDRAM with target state is LP2
585 * r4 = TEGRA_PMC_BASE
586 * r5 = TEGRA_CLK_RESET_BASE
587 * r6 = TEGRA_FLOW_CTRL_BASE
588 * r7 = TEGRA_TMRUS_BASE
589 */
590tegra3_enter_sleep:
591 ldr r1, [r7]
592 str r1, [r4, #PMC_SCRATCH38]
593 dsb
594 cpu_id r1
595
596 cpu_to_csr_reg r2, r1
597 ldr r0, [r6, r2]
598 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
599 orr r0, r0, #FLOW_CTRL_CSR_ENABLE
600 str r0, [r6, r2]
601
602 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
603 orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
604 cpu_to_halt_reg r2, r1
605 str r0, [r6, r2]
606 dsb
607 ldr r0, [r6, r2] /* memory barrier */
608
609halted:
610 isb
611 dsb
612 wfi /* CPU should be power gated here */
613
614 /* !!!FIXME!!! Implement halt failure handler */
615 b halted
616
617/*
618 * tegra3_sdram_self_refresh
619 *
620 * called with MMU off and caches disabled
621 /* puts sdram in self refresh
622 * must execute from IRAM
623 * r4 = TEGRA_PMC_BASE
624 * r5 = TEGRA_CLK_RESET_BASE
625 * r6 = TEGRA_FLOW_CTRL_BASE
626 * r7 = TEGRA_TMRUS_BASE
627 */
628
629tegra3_sdram_self_refresh:
630
631 adr r2, tegra3_sdram_pad_address
632 adr r8, tegra3_sdram_pad_save
633 mov r9, #0
634
635padsave:
636 ldr r0, [r2, r9] @ r0 is emc register address
637
638 ldr r1, [r0]
639 str r1, [r8, r9] @ save emc register
640
641 add r9, r9, #4
642 ldr r0, tegra3_sdram_pad_size
643 cmp r0, r9
644 bne padsave
645padsave_done:
646
647 dsb
648
649 mov32 r0, TEGRA_EMC_BASE @ r0 reserved for emc base
650
651 mov r1, #0
652 str r1, [r0, #EMC_ZCAL_INTERVAL]
653 str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
654 ldr r1, [r0, #EMC_CFG]
655 bic r1, r1, #(1<<28)
656 str r1, [r0, #EMC_CFG] @ disable DYN_SELF_REF
657
658 emc_timing_update r1, r0
659
660 ldr r1, [r7]
661 add r1, r1, #5
662 wait_until r1, r7, r2
663
664emc_wait_audo_cal:
665 ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
666 tst r1, #(0x1<<31) @ wait until AUTO_CAL_ACTIVE is clear
667 bne emc_wait_audo_cal
668
669 mov r1, #3
670 str r1, [r0, #EMC_REQ_CTRL] @ stall incoming DRAM requests
671
672emcidle:
673 ldr r1, [r0, #EMC_EMC_STATUS]
674 tst r1, #4
675 beq emcidle
676
677 mov r1, #1
678 str r1, [r0, #EMC_SELF_REF]
679
680 emc_device_mask r1, r0
681
682emcself:
683 ldr r2, [r0, #EMC_EMC_STATUS]
684 and r2, r2, r1
685 cmp r2, r1
686 bne emcself @ loop until DDR in self-refresh
687
688 ldr r1, [r0, #EMC_XM2VTTGENPADCTRL]
689 mov32 r2, 0xF8F8FFFF @ clear XM2VTTGEN_DRVUP and XM2VTTGEN_DRVDN
690 and r1, r1, r2
691 str r1, [r0, #EMC_XM2VTTGENPADCTRL]
692 ldr r1, [r0, #EMC_XM2VTTGENPADCTRL2]
693 orr r1, r1, #7 @ set E_NO_VTTGEN
694 str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
695
696 emc_timing_update r1, r0
697
698 ldr r1, [r4, #PMC_CTRL]
699 tst r1, #PMC_CTRL_SIDE_EFFECT_LP0
700 bne pmc_io_dpd_skip
701 mov32 r1, 0x8EC00000
702 str r1, [r4, #PMC_IO_DPD_REQ]
703pmc_io_dpd_skip:
704
705 dsb
706
707 mov pc, lr
708
709 .ltorg
710/* dummy symbol for end of IRAM */
711 .align L1_CACHE_SHIFT
712 .globl tegra3_iram_end
713tegra3_iram_end:
714 b .
715#endif
diff --git a/arch/arm/mach-tegra/syncpt.c b/arch/arm/mach-tegra/syncpt.c
new file mode 100644
index 00000000000..8ebab3801a8
--- /dev/null
+++ b/arch/arm/mach-tegra/syncpt.c
@@ -0,0 +1,100 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 *
4 * Author:
5 * Erik Gilling <konkers@google.com>
6 *
7 * Copyright (C) 2010, NVIDIA Corporation
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/io.h>
25
26#include <asm/mach/irq.h>
27
28#include <mach/iomap.h>
29#include <mach/irqs.h>
30
31#define HOST1X_SYNC_OFFSET 0x3000
32#define HOST1X_SYNC_SIZE 0x800
33enum {
34 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS = 0x40,
35 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE = 0x60
36};
37
38static void syncpt_thresh_mask(struct irq_data *data)
39{
40 (void)data;
41}
42
43static void syncpt_thresh_unmask(struct irq_data *data)
44{
45 (void)data;
46}
47
48static void syncpt_thresh_cascade(unsigned int irq, struct irq_desc *desc)
49{
50 void __iomem *sync_regs = irq_desc_get_handler_data(desc);
51 unsigned long reg;
52 int id;
53 struct irq_chip *chip = irq_desc_get_chip(desc);
54
55 chained_irq_enter(chip, desc);
56
57 reg = readl(sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
58
59 for_each_set_bit(id, &reg, 32)
60 generic_handle_irq(id + INT_SYNCPT_THRESH_BASE);
61
62 chained_irq_exit(chip, desc);
63}
64
65static struct irq_chip syncpt_thresh_irq = {
66 .name = "syncpt",
67 .irq_mask = syncpt_thresh_mask,
68 .irq_unmask = syncpt_thresh_unmask
69};
70
71static int __init syncpt_init_irq(void)
72{
73 void __iomem *sync_regs;
74 unsigned int i;
75 int irq;
76
77 sync_regs = ioremap(TEGRA_HOST1X_BASE + HOST1X_SYNC_OFFSET,
78 HOST1X_SYNC_SIZE);
79 BUG_ON(!sync_regs);
80
81 writel(0xffffffffUL,
82 sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
83 writel(0xffffffffUL,
84 sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
85
86 for (i = 0; i < INT_SYNCPT_THRESH_NR; i++) {
87 irq = INT_SYNCPT_THRESH_BASE + i;
88 irq_set_chip_and_handler(irq, &syncpt_thresh_irq,
89 handle_simple_irq);
90 irq_set_chip_data(irq, sync_regs);
91 set_irq_flags(irq, IRQF_VALID);
92 }
93 irq_set_chained_handler(INT_HOST1X_MPCORE_SYNCPT,
94 syncpt_thresh_cascade);
95 irq_set_handler_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs);
96
97 return 0;
98}
99
100core_initcall(syncpt_init_irq);
diff --git a/arch/arm/mach-tegra/sysfs-cluster.c b/arch/arm/mach-tegra/sysfs-cluster.c
new file mode 100644
index 00000000000..49c3abcf32b
--- /dev/null
+++ b/arch/arm/mach-tegra/sysfs-cluster.c
@@ -0,0 +1,461 @@
1/*
2 * Copyright (c) 2010-2011 NVIDIA Corporation.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * Neither the name of the NVIDIA Corporation nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33/*
34 * This driver creates the /sys/kernel/cluster node and attributes for CPU
35 * switch testing. Node attributes:
36 *
37 * active: currently active CPU (G or LP)
38 * write: 'g' = switch to G CPU
39 * 'lp' = switch to LP CPU
40 * 'toggle' = switch to the other CPU
41 * read: returns the currently active CPU (g or lp)
42 *
43 * force: force switch even if already on target CPU
44 * write: '0' = do not perform switch if
45 * active CPU == target CPU (default)
46 * '1' = force switch regardless of
47 * currently active CPU
48 * read: returns the current status of the force flag
49 *
50 * immediate: request immediate wake-up from switch request
51 * write: '0' = non-immediate wake-up on next interrupt (default)
52 * '1' = immediate wake-up
53 * read: returns the current status of the immediate flag
54 *
55 * power_mode: power mode to use for switch (LP1 or LP2)
56 * write: '1' = use LP1 power mode
57 * '2' = use LP2 power mode (default)
58 * read: returns the current status of the immediate flag
59 *
60 * wake_ms: wake time (in milliseconds) -- ignored if immediate==1
61 * write: '0' = wake up at the next non-timer interrupt
62 * 'n' = (n > 0) wake-up after 'n' milliseconds or the
63 * next non-timer interrupt (whichever comes first)
64 * read: returns the current wake_ms value
65 *
66 * Writing the force, immediate and wake_ms attributes simply updates the
67 * state of internal variables that will be used for the next switch request.
68 * Writing to the active attribute initates a switch request using the
69 * current values of the force, immediate, and wake_ms attributes.
70 *
71 * The OS tick timer is not a valid interrupt source for waking up following
72 * a switch request. This is because the kernel uses local timers that are
73 * part of the CPU complex. These get shut down when the CPU complex is
74 * placed into reset by the switch request. If you want a timed wake up
75 * from a switch, you must specify a positive wake_ms value. This will
76 * ensure that a non-local timer is programmed to fire an interrupt
77 * after the desired interval.
78 *
79 */
80
81#include <linux/module.h>
82#include <linux/kernel.h>
83#include <linux/sysfs.h>
84#include <linux/kobject.h>
85#include <linux/smp.h>
86#include <linux/io.h>
87#include <linux/clk.h>
88
89#include <mach/iomap.h>
90#include "clock.h"
91#include "sleep.h"
92#include "pm.h"
93
94#define SYSFS_CLUSTER_PRINTS 1 /* Nonzero: enable status prints */
95#define SYSFS_CLUSTER_TRACE_PRINTS 0 /* Nonzero: enable trace prints */
96#define SYSFS_CLUSTER_POWER_MODE 1 /* Nonzero: use power modes other than LP2*/
97
98#if SYSFS_CLUSTER_TRACE_PRINTS
99#define TRACE_CLUSTER(x) printk x
100#else
101#define TRACE_CLUSTER(x)
102#endif
103
104#if SYSFS_CLUSTER_PRINTS
105#define PRINT_CLUSTER(x) printk x
106#else
107#define PRINT_CLUSTER(x)
108#endif
109
110static struct kobject *cluster_kobj;
111static spinlock_t cluster_lock;
112static unsigned int flags = 0;
113static unsigned int wake_ms = 0;
114
115static ssize_t sysfscluster_show(struct kobject *kobj,
116 struct kobj_attribute *attr, char *buf);
117
118static ssize_t sysfscluster_store(struct kobject *kobj,
119 struct kobj_attribute *attr, const char *buf, size_t count);
120
121/* Active CPU: "G", "LP", "toggle" */
122static struct kobj_attribute cluster_active_attr =
123 __ATTR(active, 0640, sysfscluster_show, sysfscluster_store);
124
125/* Immediate wake-up when performing switch: 0, 1 */
126static struct kobj_attribute cluster_immediate_attr =
127 __ATTR(immediate, 0640, sysfscluster_show, sysfscluster_store);
128
129/* Force power transition even if already on the desired CPU: 0, 1 */
130static struct kobj_attribute cluster_force_attr =
131 __ATTR(force, 0640, sysfscluster_show, sysfscluster_store);
132
133/* Wake time (in milliseconds) */
134static struct kobj_attribute cluster_wake_ms_attr =
135 __ATTR(wake_ms, 0640, sysfscluster_show, sysfscluster_store);
136
137#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
138/* LPx power mode to use when switching CPUs: 1=LP1, 2=LP2 */
139static unsigned int power_mode = 2;
140static struct kobj_attribute cluster_powermode_attr =
141 __ATTR(power_mode, 0640, sysfscluster_show, sysfscluster_store);
142#endif
143
144#if DEBUG_CLUSTER_SWITCH
145unsigned int tegra_cluster_debug = 0;
146static struct kobj_attribute cluster_debug_attr =
147 __ATTR(debug, 0640, sysfscluster_show, sysfscluster_store);
148#endif
149
150typedef enum
151{
152 ClusterAttr_Invalid = 0,
153 ClusterAttr_Active,
154 ClusterAttr_Immediate,
155 ClusterAttr_Force,
156 ClusterAttr_WakeMs,
157#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
158 ClusterAttr_PowerMode,
159#endif
160#if DEBUG_CLUSTER_SWITCH
161 ClusterAttr_Debug
162#endif
163} ClusterAttr;
164
165static ClusterAttr GetClusterAttr(const char *name)
166{
167 if (!strcmp(name, "active"))
168 return ClusterAttr_Active;
169 if (!strcmp(name, "immediate"))
170 return ClusterAttr_Immediate;
171 if (!strcmp(name, "force"))
172 return ClusterAttr_Force;
173 if (!strcmp(name, "wake_ms"))
174 return ClusterAttr_WakeMs;
175#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
176 if (!strcmp(name, "power_mode"))
177 return ClusterAttr_PowerMode;
178#endif
179#if DEBUG_CLUSTER_SWITCH
180 if (!strcmp(name, "debug"))
181 return ClusterAttr_Debug;
182#endif
183 TRACE_CLUSTER(("GetClusterAttr(%s): invalid\n", name));
184 return ClusterAttr_Invalid;
185}
186
187static ssize_t sysfscluster_show(struct kobject *kobj,
188 struct kobj_attribute *attr, char *buf)
189{
190 ClusterAttr type;
191 ssize_t len;
192
193 TRACE_CLUSTER(("+sysfscluster_show\n"));
194
195 type = GetClusterAttr(attr->attr.name);
196 switch (type) {
197 case ClusterAttr_Active:
198 len = sprintf(buf, "%s\n", is_lp_cluster() ? "LP" : "G");
199 break;
200
201 case ClusterAttr_Immediate:
202 len = sprintf(buf, "%d\n",
203 ((flags & TEGRA_POWER_CLUSTER_IMMEDIATE) != 0));
204 break;
205
206 case ClusterAttr_Force:
207 len = sprintf(buf, "%d\n",
208 ((flags & TEGRA_POWER_CLUSTER_FORCE) != 0));
209 break;
210
211 case ClusterAttr_WakeMs:
212 len = sprintf(buf, "%d\n", wake_ms);
213 break;
214
215#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
216 case ClusterAttr_PowerMode:
217 len = sprintf(buf, "%d\n", power_mode);
218 break;
219#endif
220
221#if DEBUG_CLUSTER_SWITCH
222 case ClusterAttr_Debug:
223 len = sprintf(buf, "%d\n", tegra_cluster_debug);
224 break;
225#endif
226
227 default:
228 len = sprintf(buf, "invalid\n");
229 break;
230 }
231
232 TRACE_CLUSTER(("-sysfscluster_show\n"));
233 return len;
234}
235
236static ssize_t sysfscluster_store(struct kobject *kobj,
237 struct kobj_attribute *attr, const char *buf, size_t count)
238{
239 ClusterAttr type;
240 ssize_t ret = count--;
241 unsigned request;
242 int e;
243 int tmp;
244 int cnt;
245 struct clk *cpu_clk = tegra_get_clock_by_name("cpu");
246 struct clk *cpu_g_clk = tegra_get_clock_by_name("cpu_g");
247 struct clk *cpu_lp_clk = tegra_get_clock_by_name("cpu_lp");
248 struct clk *new_parent = NULL;
249
250 if (!cpu_clk || !cpu_g_clk || !cpu_lp_clk) {
251 ret = -ENOSYS;
252 goto fail;
253 }
254
255 TRACE_CLUSTER(("+sysfscluster_store: %p, %d\n", buf, count));
256
257 /* The count includes data bytes follow by a line feed character. */
258 if (!buf || (count < 1)) {
259 ret = -EINVAL;
260 goto fail;
261 }
262
263 type = GetClusterAttr(attr->attr.name);
264
265 spin_lock(&cluster_lock);
266
267 switch (type) {
268 case ClusterAttr_Active:
269 if (!strncasecmp(buf, "g", count)) {
270 flags &= ~TEGRA_POWER_CLUSTER_MASK;
271 flags |= TEGRA_POWER_CLUSTER_G;
272 } else if (!strncasecmp(buf, "lp", count)) {
273 flags &= ~TEGRA_POWER_CLUSTER_MASK;
274 flags |= TEGRA_POWER_CLUSTER_LP;
275 } else if (!strncasecmp(buf, "toggle", count)) {
276 flags &= ~TEGRA_POWER_CLUSTER_MASK;
277 if (is_lp_cluster())
278 flags |= TEGRA_POWER_CLUSTER_G;
279 else
280 flags |= TEGRA_POWER_CLUSTER_LP;
281 } else {
282 PRINT_CLUSTER(("cluster/active: '%*.*s' invalid, "
283 " must be g, lp, or toggle\n",
284 count, count, buf));
285 ret = -EINVAL;
286 break;
287 }
288 PRINT_CLUSTER(("cluster/active -> %s\n",
289 (flags & TEGRA_POWER_CLUSTER_G) ? "G" : "LP"));
290
291 request = flags;
292#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
293 if (power_mode == 1) {
294 request |= TEGRA_POWER_SDRAM_SELFREFRESH;
295 }
296#endif
297 tegra_cluster_switch_set_parameters(wake_ms * 1000, request);
298 new_parent = (flags & TEGRA_POWER_CLUSTER_LP) ?
299 cpu_lp_clk : cpu_g_clk;
300 break;
301
302 case ClusterAttr_Immediate:
303 if ((count == 1) && (*buf == '0'))
304 flags &= ~TEGRA_POWER_CLUSTER_IMMEDIATE;
305 else if ((count == 1) && *buf == '1')
306 flags |= TEGRA_POWER_CLUSTER_IMMEDIATE;
307 else {
308 PRINT_CLUSTER(("cluster/immediate: '%*.*s' invalid, "
309 "must be 0 or 1\n", count, count, buf));
310 ret = -EINVAL;
311 break;
312 }
313 PRINT_CLUSTER(("cluster/immediate -> %c\n",
314 (flags & TEGRA_POWER_CLUSTER_IMMEDIATE) ? '1' : '0'));
315 break;
316
317 case ClusterAttr_Force:
318 if ((count == 1) && (*buf == '0'))
319 flags &= ~TEGRA_POWER_CLUSTER_FORCE;
320 else if ((count == 1) && (*buf == '1'))
321 flags |= TEGRA_POWER_CLUSTER_FORCE;
322 else {
323 PRINT_CLUSTER(("cluster/force: '%*.*s' invalid, "
324 "must be 0 or 1\n", count, count, buf));
325 ret = -EINVAL;
326 break;
327 }
328 PRINT_CLUSTER(("cluster/force -> %c\n",
329 (flags & TEGRA_POWER_CLUSTER_FORCE) ? '1' : '0'));
330 break;
331
332 case ClusterAttr_WakeMs:
333 tmp = 0;
334 cnt = sscanf(buf, "%d\n", &tmp);
335 if ((cnt != 1) || (tmp < 0)) {
336 PRINT_CLUSTER(("cluster/wake_ms: '%*.*s' is invalid\n",
337 count, count, buf));
338 ret = -EINVAL;
339 break;
340 }
341 wake_ms = tmp;
342 PRINT_CLUSTER(("cluster/wake_ms -> %d\n", wake_ms));
343 break;
344
345#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
346 case ClusterAttr_PowerMode:
347 if ((count == 1) && (*buf == '2'))
348 power_mode = 2;
349 else if ((count == 1) && *buf == '1')
350 power_mode = 1;
351 else {
352 PRINT_CLUSTER(("cluster/power_mode: '%*.*s' invalid, "
353 "must be 2 or 1\n", count, count, buf));
354 ret = -EINVAL;
355 break;
356 }
357 PRINT_CLUSTER(("cluster/power_mode -> %d\n", power_mode));
358 break;
359#endif
360
361#if DEBUG_CLUSTER_SWITCH
362 case ClusterAttr_Debug:
363 if ((count == 1) && (*buf == '0'))
364 tegra_cluster_debug = 0;
365 else if ((count == 1) && (*buf == '1'))
366 tegra_cluster_debug = 1;
367 else {
368 PRINT_CLUSTER(("cluster/debug: '%*.*s' invalid, "
369 "must be 0 or 1\n", count, count, buf));
370 ret = -EINVAL;
371 break;
372 }
373 PRINT_CLUSTER(("cluster/debug -> %d\n",tegra_cluster_debug));
374 break;
375#endif
376
377 default:
378 ret = -ENOENT;
379 break;
380 }
381
382 spin_unlock(&cluster_lock);
383
384 if (new_parent) {
385 e = clk_set_parent(cpu_clk, new_parent);
386 if (e) {
387 PRINT_CLUSTER(("cluster/active: request failed (%d)\n",
388 e));
389 ret = e;
390 }
391 }
392fail:
393 TRACE_CLUSTER(("-sysfscluster_store: %d\n", count));
394 return ret;
395}
396
397#define CREATE_FILE(x) \
398 do { \
399 e = sysfs_create_file(cluster_kobj, &cluster_##x##_attr.attr); \
400 if (e) { \
401 TRACE_CLUSTER(("cluster/" __stringify(x) \
402 ": sysfs_create_file failed!\n")); \
403 goto fail; \
404 } \
405 } while (0)
406
407static int __init sysfscluster_init(void)
408{
409 int e;
410
411 TRACE_CLUSTER(("+sysfscluster_init\n"));
412
413 spin_lock_init(&cluster_lock);
414 cluster_kobj = kobject_create_and_add("cluster", kernel_kobj);
415
416 CREATE_FILE(active);
417 CREATE_FILE(immediate);
418 CREATE_FILE(force);
419 CREATE_FILE(wake_ms);
420#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
421 CREATE_FILE(powermode);
422#endif
423#if DEBUG_CLUSTER_SWITCH
424 CREATE_FILE(debug);
425#endif
426
427 spin_lock(&cluster_lock);
428 if (is_lp_cluster())
429 flags |= TEGRA_POWER_CLUSTER_LP;
430 else
431 flags |= TEGRA_POWER_CLUSTER_G;
432 spin_unlock(&cluster_lock);
433
434fail:
435 TRACE_CLUSTER(("-sysfscluster_init\n"));
436 return e;
437}
438
439#define REMOVE_FILE(x) \
440 sysfs_remove_file(cluster_kobj, &cluster_##x##_attr.attr)
441
442static void __exit sysfscluster_exit(void)
443{
444 TRACE_CLUSTER(("+sysfscluster_exit\n"));
445#if DEBUG_CLUSTER_SWITCH
446 REMOVE_FILE(debug);
447#endif
448#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
449 REMOVE_FILE(powermode);
450#endif
451 REMOVE_FILE(wake_ms);
452 REMOVE_FILE(force);
453 REMOVE_FILE(immediate);
454 REMOVE_FILE(active);
455 kobject_del(cluster_kobj);
456 TRACE_CLUSTER(("-sysfscluster_exit\n"));
457}
458
459module_init(sysfscluster_init);
460module_exit(sysfscluster_exit);
461MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-tegra/sysfs-dcc.c b/arch/arm/mach-tegra/sysfs-dcc.c
new file mode 100644
index 00000000000..a4dc9a72135
--- /dev/null
+++ b/arch/arm/mach-tegra/sysfs-dcc.c
@@ -0,0 +1,249 @@
1/*
2 * Copyright (c) 2010-2011 NVIDIA Corporation.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * Neither the name of the NVIDIA Corporation nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33#include <linux/module.h>
34#include <linux/kernel.h>
35#include <linux/spinlock.h>
36#include <linux/sysfs.h>
37#include <linux/workqueue.h>
38#include <linux/kobject.h>
39#include <linux/hrtimer.h>
40#include <linux/slab.h>
41
42#define DCC_TIMEOUT_US 100000 /* Delay time for DCC timeout (in uS) */
43#define CP14_DSCR_WDTRFULL 0x20000000 /* Write Data Transfer Register Full */
44#define SYSFS_DCC_DEBUG_PRINTS 0 /* Set non-zero to enable debug prints */
45
46#if SYSFS_DCC_DEBUG_PRINTS
47#define DEBUG_DCC(x) printk x
48#else
49#define DEBUG_DCC(x)
50#endif
51
52static int DebuggerConnected = 0; /* -1=not connected, 0=unknown, 1=connected */
53static struct kobject *nvdcc_kobj;
54static spinlock_t dcc_lock;
55static struct list_head dcc_list;
56
57static ssize_t sysfsdcc_show(struct kobject *kobj,
58 struct kobj_attribute *attr, char *buf);
59
60static ssize_t sysfsdcc_store(struct kobject *kobj,
61 struct kobj_attribute *attr, const char *buf, size_t count);
62
63
64static struct kobj_attribute nvdcc_attr =
65 __ATTR(dcc0, 0222, sysfsdcc_show, sysfsdcc_store);
66
67static int write_to_dcc(u32 c)
68{
69 volatile u32 dscr;
70
71 /* Have we already determined that there is no debugger connected? */
72 if (DebuggerConnected < 0)
73 {
74 return -ENXIO;
75 }
76
77 /* Read the DSCR. */
78 asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (dscr) : : "cc");
79
80 /* If DSCR Bit 29 (wDTRFull) is set there is data in the write
81 * register. If it stays there for than the DCC_TIMEOUT_US
82 * period, ignore this write and disable further DCC accesses. */
83 if (dscr & CP14_DSCR_WDTRFULL)
84 {
85 ktime_t end = ktime_add_ns(ktime_get(), DCC_TIMEOUT_US * 1000);
86 ktime_t now;
87
88 for (;;)
89 {
90 /* Re-read the DSCR. */
91 asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (dscr) : : "cc");
92
93 /* Previous data still there? */
94 if (dscr & CP14_DSCR_WDTRFULL)
95 {
96 now = ktime_get();
97
98 if (ktime_to_ns(now) >= ktime_to_ns(end))
99 {
100 goto fail;
101 }
102 }
103 else
104 {
105 if (DebuggerConnected == 0) {
106 /* Debugger connected */
107 spin_lock(&dcc_lock);
108 DebuggerConnected = 1;
109 spin_unlock(&dcc_lock);
110 }
111 break;
112 }
113 }
114 }
115
116 // Write the data into the DCC output register
117 asm volatile ("mcr p14, 0, %0, c0, c5, 0" : : "r" (c) : "cc");
118 return 0;
119
120fail:
121 /* No debugged connected -- disable DCC */
122 spin_lock(&dcc_lock);
123 DebuggerConnected = -1;
124 spin_unlock(&dcc_lock);
125 return -ENXIO;
126}
127
128
129struct tegra_dcc_req {
130 struct list_head node;
131
132 const char *pBuf;
133 unsigned int size;
134};
135
136struct dcc_action {
137 struct tegra_dcc_req req;
138 struct work_struct work;
139 struct list_head node;
140};
141
142
143static void dcc_writer(struct work_struct *work)
144{
145 struct dcc_action *action = container_of(work, struct dcc_action, work);
146 const char *p;
147
148 DEBUG_DCC(("+dcc_writer\n"));
149
150 spin_lock(&dcc_lock);
151 list_del(&action->req.node);
152 spin_unlock(&dcc_lock);
153
154 p = action->req.pBuf;
155 if (p)
156 while ((p < &(action->req.pBuf[action->req.size])) && (*p))
157 if (write_to_dcc(*p++))
158 break;
159
160 kfree(action->req.pBuf);
161 kfree(action);
162
163 DEBUG_DCC(("-dcc_writer\n"));
164}
165
166static ssize_t sysfsdcc_show(struct kobject *kobj,
167 struct kobj_attribute *attr, char *buf)
168{
169 DEBUG_DCC(("!sysfsdcc_show\n"));
170 return -EACCES;
171}
172
173static ssize_t sysfsdcc_store(struct kobject *kobj,
174 struct kobj_attribute *attr, const char *buf, size_t count)
175{
176 struct dcc_action *action;
177 char *pBuf;
178 ssize_t ret = count;
179
180 DEBUG_DCC(("+sysfsdcc_store: %p, %d\n", buf, count));
181
182 if (!buf || !count) {
183 ret = -EINVAL;
184 goto fail;
185 }
186
187 pBuf = kmalloc(count+1, GFP_KERNEL);
188 if (!pBuf) {
189 pr_debug("%s: insufficient memory\n", __func__);
190 ret = -ENOMEM;
191 goto fail;
192 }
193
194 action = kzalloc(sizeof(*action), GFP_KERNEL);
195 if (!action) {
196 kfree(pBuf);
197 pr_debug("%s: insufficient memory\n", __func__);
198 ret = -ENOMEM;
199 goto fail;
200 }
201
202 strncpy(pBuf, buf, count);
203 pBuf[count] = '\0';
204 action->req.pBuf = pBuf;
205 action->req.size = count;
206
207 INIT_WORK(&action->work, dcc_writer);
208
209 spin_lock(&dcc_lock);
210 list_add_tail(&action->req.node, &dcc_list);
211 spin_unlock(&dcc_lock);
212
213 /* DCC writes can only be performed from CPU0 */
214 schedule_work_on(0, &action->work);
215
216fail:
217 DEBUG_DCC(("-sysfsdcc_store: %d\n", count));
218 return ret;
219}
220
221static int __init sysfsdcc_init(void)
222{
223 spin_lock_init(&dcc_lock);
224 INIT_LIST_HEAD(&dcc_list);
225
226 DEBUG_DCC(("+sysfsdcc_init\n"));
227 nvdcc_kobj = kobject_create_and_add("dcc", kernel_kobj);
228
229 if (sysfs_create_file(nvdcc_kobj, &nvdcc_attr.attr))
230 {
231 DEBUG_DCC(("DCC: sysfs_create_file failed!\n"));
232 return -ENXIO;
233 }
234
235 DEBUG_DCC(("-sysfsdcc_init\n"));
236 return 0;
237}
238
239static void __exit sysfsdcc_exit(void)
240{
241 DEBUG_DCC(("+sysfsdcc_exit\n"));
242 sysfs_remove_file(nvdcc_kobj, &nvdcc_attr.attr);
243 kobject_del(nvdcc_kobj);
244 DEBUG_DCC(("-sysfsdcc_exit\n"));
245}
246
247module_init(sysfsdcc_init);
248module_exit(sysfsdcc_exit);
249MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
new file mode 100644
index 00000000000..126a1d56591
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -0,0 +1,2930 @@
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 * Copyright (C) 2010-2012 NVIDIA Corporation
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/list.h>
25#include <linux/spinlock.h>
26#include <linux/delay.h>
27#include <linux/io.h>
28#include <linux/clkdev.h>
29#include <linux/clk.h>
30#include <linux/syscore_ops.h>
31#include <linux/cpufreq.h>
32
33#include <mach/iomap.h>
34#include <mach/pinmux.h>
35
36#include "clock.h"
37#include "fuse.h"
38#include "tegra2_emc.h"
39#include "tegra2_statmon.h"
40
41#define RST_DEVICES 0x004
42#define RST_DEVICES_SET 0x300
43#define RST_DEVICES_CLR 0x304
44#define RST_DEVICES_NUM 3
45
46#define CLK_OUT_ENB 0x010
47#define CLK_OUT_ENB_SET 0x320
48#define CLK_OUT_ENB_CLR 0x324
49#define CLK_OUT_ENB_NUM 3
50
51#define CLK_MASK_ARM 0x44
52#define MISC_CLK_ENB 0x48
53
54#define OSC_CTRL 0x50
55#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
56#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
57#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
58#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
59#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
60#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
61
62#define PERIPH_CLK_SOURCE_I2S1 0x100
63#define PERIPH_CLK_SOURCE_EMC 0x19c
64#define PERIPH_CLK_SOURCE_OSC 0x1fc
65#define PERIPH_CLK_SOURCE_NUM \
66 ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
67
68#define PERIPH_CLK_SOURCE_MASK (3<<30)
69#define PERIPH_CLK_SOURCE_SHIFT 30
70#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
71#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
72#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
73#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
74
75#define SDMMC_CLK_INT_FB_SEL (1 << 23)
76#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
77#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
78
79#define PLL_BASE 0x0
80#define PLL_BASE_BYPASS (1<<31)
81#define PLL_BASE_ENABLE (1<<30)
82#define PLL_BASE_REF_ENABLE (1<<29)
83#define PLL_BASE_OVERRIDE (1<<28)
84#define PLL_BASE_DIVP_MASK (0x7<<20)
85#define PLL_BASE_DIVP_SHIFT 20
86#define PLL_BASE_DIVN_MASK (0x3FF<<8)
87#define PLL_BASE_DIVN_SHIFT 8
88#define PLL_BASE_DIVM_MASK (0x1F)
89#define PLL_BASE_DIVM_SHIFT 0
90
91#define PLL_OUT_RATIO_MASK (0xFF<<8)
92#define PLL_OUT_RATIO_SHIFT 8
93#define PLL_OUT_OVERRIDE (1<<2)
94#define PLL_OUT_CLKEN (1<<1)
95#define PLL_OUT_RESET_DISABLE (1<<0)
96
97#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
98
99#define PLL_MISC_DCCON_SHIFT 20
100#define PLL_MISC_CPCON_SHIFT 8
101#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
102#define PLL_MISC_LFCON_SHIFT 4
103#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
104#define PLL_MISC_VCOCON_SHIFT 0
105#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
106
107#define PLLU_BASE_POST_DIV (1<<20)
108
109#define PLLD_MISC_CLKENABLE (1<<30)
110#define PLLD_MISC_DIV_RST (1<<23)
111#define PLLD_MISC_DCCON_SHIFT 12
112
113#define PLLE_MISC_READY (1 << 15)
114
115#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
116#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
117#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
118
119#define SUPER_CLK_MUX 0x00
120#define SUPER_STATE_SHIFT 28
121#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
122#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
123#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
124#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
125#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
126#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
127#define SUPER_SOURCE_MASK 0xF
128#define SUPER_FIQ_SOURCE_SHIFT 12
129#define SUPER_IRQ_SOURCE_SHIFT 8
130#define SUPER_RUN_SOURCE_SHIFT 4
131#define SUPER_IDLE_SOURCE_SHIFT 0
132
133#define SUPER_CLK_DIVIDER 0x04
134
135#define BUS_CLK_DISABLE (1<<3)
136#define BUS_CLK_DIV_MASK 0x3
137
138#define PMC_CTRL 0x0
139 #define PMC_CTRL_BLINK_ENB (1 << 7)
140
141#define PMC_DPD_PADS_ORIDE 0x1c
142 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
143
144#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
145#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
146#define PMC_BLINK_TIMER_ENB (1 << 15)
147#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
148#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
149
150#define AP25_EMC_BRIDGE_RATE 380000000
151#define AP25_EMC_INTERMEDIATE_RATE 760000000
152#define AP25_EMC_SCALING_STEP 600000000
153
154static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
155static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
156static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
157
158#define MISC_GP_HIDREV 0x804
159#define PLLDU_LFCON_SET_DIVN 600
160
161static int tegra2_clk_shared_bus_update(struct clk *bus);
162
163/*
164 * Some clocks share a register with other clocks. Any clock op that
165 * non-atomically modifies a register used by another clock must lock
166 * clock_register_lock first.
167 */
168static DEFINE_SPINLOCK(clock_register_lock);
169
170/*
171 * Some peripheral clocks share an enable bit, so refcount the enable bits
172 * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
173 */
174static int tegra_periph_clk_enable_refcount[3 * 32];
175
176#define clk_writel(value, reg) \
177 __raw_writel(value, (u32)reg_clk_base + (reg))
178#define clk_readl(reg) \
179 __raw_readl((u32)reg_clk_base + (reg))
180#define pmc_writel(value, reg) \
181 __raw_writel(value, (u32)reg_pmc_base + (reg))
182#define pmc_readl(reg) \
183 __raw_readl((u32)reg_pmc_base + (reg))
184#define chipid_readl() \
185 __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
186
187static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
188{
189 s64 divider_u71 = parent_rate * 2;
190 divider_u71 += rate - 1;
191 do_div(divider_u71, rate);
192
193 if (divider_u71 - 2 < 0)
194 return 0;
195
196 if (divider_u71 - 2 > 255)
197 return -EINVAL;
198
199 return divider_u71 - 2;
200}
201
202static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
203{
204 s64 divider_u16;
205
206 divider_u16 = parent_rate;
207 divider_u16 += rate - 1;
208 do_div(divider_u16, rate);
209
210 if (divider_u16 - 1 < 0)
211 return 0;
212
213 if (divider_u16 - 1 > 0xFFFF)
214 return -EINVAL;
215
216 return divider_u16 - 1;
217}
218
219static inline int clk_set_div(struct clk *c, int n)
220{
221 return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
222}
223
224/* clk_m functions */
225static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
226{
227 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
228
229 c->rate = tegra_clk_measure_input_freq();
230 switch (c->rate) {
231 case 12000000:
232 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
233 break;
234 case 13000000:
235 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
236 break;
237 case 19200000:
238 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
239 break;
240 case 26000000:
241 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
242 break;
243 default:
244 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
245 BUG();
246 }
247 clk_writel(auto_clock_control, OSC_CTRL);
248 return c->rate;
249}
250
251static void tegra2_clk_m_init(struct clk *c)
252{
253 pr_debug("%s on clock %s\n", __func__, c->name);
254 tegra2_clk_m_autodetect_rate(c);
255}
256
257static int tegra2_clk_m_enable(struct clk *c)
258{
259 pr_debug("%s on clock %s\n", __func__, c->name);
260 return 0;
261}
262
263static void tegra2_clk_m_disable(struct clk *c)
264{
265 pr_debug("%s on clock %s\n", __func__, c->name);
266 BUG();
267}
268
269static struct clk_ops tegra_clk_m_ops = {
270 .init = tegra2_clk_m_init,
271 .enable = tegra2_clk_m_enable,
272 .disable = tegra2_clk_m_disable,
273};
274
275/* super clock functions */
276/* "super clocks" on tegra have two-stage muxes and a clock skipping
277 * super divider. We will ignore the clock skipping divider, since we
278 * can't lower the voltage when using the clock skip, but we can if we
279 * lower the PLL frequency.
280 */
281static void tegra2_super_clk_init(struct clk *c)
282{
283 u32 val;
284 int source;
285 int shift;
286 const struct clk_mux_sel *sel;
287 val = clk_readl(c->reg + SUPER_CLK_MUX);
288 c->state = ON;
289 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
290 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
291 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
292 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
293 source = (val >> shift) & SUPER_SOURCE_MASK;
294 for (sel = c->inputs; sel->input != NULL; sel++) {
295 if (sel->value == source)
296 break;
297 }
298 BUG_ON(sel->input == NULL);
299 c->parent = sel->input;
300}
301
302static int tegra2_super_clk_enable(struct clk *c)
303{
304 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
305 return 0;
306}
307
308static void tegra2_super_clk_disable(struct clk *c)
309{
310 pr_debug("%s on clock %s\n", __func__, c->name);
311
312 /* oops - don't disable the CPU clock! */
313 BUG();
314}
315
316static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
317{
318 u32 val;
319 const struct clk_mux_sel *sel;
320 int shift;
321
322 val = clk_readl(c->reg + SUPER_CLK_MUX);
323 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
324 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
325 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
326 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
327 for (sel = c->inputs; sel->input != NULL; sel++) {
328 if (sel->input == p) {
329 val &= ~(SUPER_SOURCE_MASK << shift);
330 val |= sel->value << shift;
331
332 if (c->refcnt)
333 clk_enable(p);
334
335 clk_writel(val, c->reg);
336
337 if (c->refcnt && c->parent)
338 clk_disable(c->parent);
339
340 clk_reparent(c, p);
341 return 0;
342 }
343 }
344 return -EINVAL;
345}
346
347/*
348 * Super clocks have "clock skippers" instead of dividers. Dividing using
349 * a clock skipper does not allow the voltage to be scaled down, so instead
350 * adjust the rate of the parent clock. This requires that the parent of a
351 * super clock have no other children, otherwise the rate will change
352 * underneath the other children.
353 */
354static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate)
355{
356 return clk_set_rate(c->parent, rate);
357}
358
359static struct clk_ops tegra_super_ops = {
360 .init = tegra2_super_clk_init,
361 .enable = tegra2_super_clk_enable,
362 .disable = tegra2_super_clk_disable,
363 .set_parent = tegra2_super_clk_set_parent,
364 .set_rate = tegra2_super_clk_set_rate,
365};
366
367static int tegra2_twd_clk_set_rate(struct clk *c, unsigned long rate)
368{
369 /* The input value 'rate' is the clock rate of the CPU complex. */
370 c->rate = (rate * c->mul) / c->div;
371 return 0;
372}
373
374static struct clk_ops tegra2_twd_ops = {
375 .set_rate = tegra2_twd_clk_set_rate,
376};
377
378static struct clk tegra2_clk_twd = {
379 /* NOTE: The twd clock must have *NO* parent. It's rate is directly
380 updated by tegra3_cpu_cmplx_clk_set_rate() because the
381 frequency change notifer for the twd is called in an
382 atomic context which cannot take a mutex. */
383 .name = "twd",
384 .ops = &tegra2_twd_ops,
385 .max_rate = 1000000000, /* Same as tegra_clk_virtual_cpu.max_rate */
386 .mul = 1,
387 .div = 4,
388};
389
390/* virtual cpu clock functions */
391/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
392 To change the frequency of these clocks, the parent pll may need to be
393 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
394 and then the clock moved back to the pll. To hide this sequence, a virtual
395 clock handles it.
396 */
397static void tegra2_cpu_clk_init(struct clk *c)
398{
399}
400
401static int tegra2_cpu_clk_enable(struct clk *c)
402{
403 return 0;
404}
405
406static void tegra2_cpu_clk_disable(struct clk *c)
407{
408 pr_debug("%s on clock %s\n", __func__, c->name);
409
410 /* oops - don't disable the CPU clock! */
411 BUG();
412}
413
414static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
415{
416 int ret;
417 /*
418 * Take an extra reference to the main pll so it doesn't turn
419 * off when we move the cpu off of it
420 */
421 clk_enable(c->u.cpu.main);
422
423 ret = clk_set_parent(c->parent, c->u.cpu.backup);
424 if (ret) {
425 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
426 goto out;
427 }
428
429 if (rate == clk_get_rate(c->u.cpu.backup))
430 goto out;
431
432 ret = clk_set_rate(c->u.cpu.main, rate);
433 if (ret) {
434 pr_err("Failed to change cpu pll to %lu\n", rate);
435 goto out;
436 }
437
438 ret = clk_set_parent(c->parent, c->u.cpu.main);
439 if (ret) {
440 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
441 goto out;
442 }
443
444out:
445 /* We can't parent the twd to directly to the CPU complex because
446 the TWD frequency update notifier is called in an atomic context
447 and the CPU frequency update requires a mutex. Update the twd
448 clock rate with the new CPU complex rate. */
449 clk_set_rate(&tegra2_clk_twd, clk_get_rate_locked(c));
450
451 clk_disable(c->u.cpu.main);
452 return ret;
453}
454
455static struct clk_ops tegra_cpu_ops = {
456 .init = tegra2_cpu_clk_init,
457 .enable = tegra2_cpu_clk_enable,
458 .disable = tegra2_cpu_clk_disable,
459 .set_rate = tegra2_cpu_clk_set_rate,
460};
461
462static void tegra2_virtual_sclk_init(struct clk *c)
463{
464 c->max_rate = c->parent->max_rate;
465 c->min_rate = c->parent->min_rate;
466}
467
468static long tegra2_virtual_sclk_round_rate(struct clk *c, unsigned long rate)
469{
470 long new_rate = rate;
471 return new_rate;
472}
473
474static int tegra2_virtual_sclk_set_rate(struct clk *c, unsigned long rate)
475{
476 int ret;
477
478 if (rate >= c->u.system.pclk->min_rate * 2) {
479 ret = clk_set_div(c->u.system.pclk, 2);
480 if (ret) {
481 pr_err("Failed to set 1 : 2 pclk divider\n");
482 return ret;
483 }
484 }
485
486 ret = clk_set_rate(c->parent, rate);
487 if (ret) {
488 pr_err("Failed to set sclk source %s to %lu\n",
489 c->parent->name, rate);
490 return ret;
491 }
492
493 if (rate < c->u.system.pclk->min_rate * 2) {
494 ret = clk_set_div(c->u.system.pclk, 1);
495 if (ret) {
496 pr_err("Failed to set 1 : 1 pclk divider\n");
497 return ret;
498 }
499 }
500
501 return 0;
502}
503
504static struct clk_ops tegra_virtual_sclk_ops = {
505 .init = tegra2_virtual_sclk_init,
506 .set_rate = tegra2_virtual_sclk_set_rate,
507 .round_rate = tegra2_virtual_sclk_round_rate,
508 .shared_bus_update = tegra2_clk_shared_bus_update,
509};
510
511/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
512 * reset the COP block (i.e. AVP) */
513static void tegra2_cop_clk_reset(struct clk *c, bool assert)
514{
515 unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
516
517 pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
518 clk_writel(1 << 1, reg);
519}
520
521static struct clk_ops tegra_cop_ops = {
522 .reset = tegra2_cop_clk_reset,
523};
524
525/* bus clock functions */
526static void tegra2_bus_clk_init(struct clk *c)
527{
528 u32 val = clk_readl(c->reg);
529 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
530 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
531 c->mul = 1;
532}
533
534static int tegra2_bus_clk_enable(struct clk *c)
535{
536 u32 val;
537 unsigned long flags;
538
539 spin_lock_irqsave(&clock_register_lock, flags);
540
541 val = clk_readl(c->reg);
542 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
543 clk_writel(val, c->reg);
544
545 spin_unlock_irqrestore(&clock_register_lock, flags);
546
547 return 0;
548}
549
550static void tegra2_bus_clk_disable(struct clk *c)
551{
552 u32 val;
553 unsigned long flags;
554
555 spin_lock_irqsave(&clock_register_lock, flags);
556
557 val = clk_readl(c->reg);
558 val |= BUS_CLK_DISABLE << c->reg_shift;
559 clk_writel(val, c->reg);
560
561 spin_unlock_irqrestore(&clock_register_lock, flags);
562}
563
564static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
565{
566 u32 val;
567 unsigned long parent_rate = clk_get_rate(c->parent);
568 unsigned long flags;
569 int ret = -EINVAL;
570 int i;
571
572 spin_lock_irqsave(&clock_register_lock, flags);
573
574 val = clk_readl(c->reg);
575 for (i = 1; i <= 4; i++) {
576 if (rate >= parent_rate / i) {
577 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
578 val |= (i - 1) << c->reg_shift;
579 clk_writel(val, c->reg);
580 c->div = i;
581 c->mul = 1;
582 ret = 0;
583 break;
584 }
585 }
586
587 spin_unlock_irqrestore(&clock_register_lock, flags);
588
589 return ret;
590}
591
592static struct clk_ops tegra_bus_ops = {
593 .init = tegra2_bus_clk_init,
594 .enable = tegra2_bus_clk_enable,
595 .disable = tegra2_bus_clk_disable,
596 .set_rate = tegra2_bus_clk_set_rate,
597};
598
599/* Blink output functions */
600
601static void tegra2_blink_clk_init(struct clk *c)
602{
603 u32 val;
604
605 val = pmc_readl(PMC_CTRL);
606 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
607 c->mul = 1;
608 val = pmc_readl(c->reg);
609
610 if (val & PMC_BLINK_TIMER_ENB) {
611 unsigned int on_off;
612
613 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
614 PMC_BLINK_TIMER_DATA_ON_MASK;
615 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
616 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
617 on_off += val;
618 /* each tick in the blink timer is 4 32KHz clocks */
619 c->div = on_off * 4;
620 } else {
621 c->div = 1;
622 }
623}
624
625static int tegra2_blink_clk_enable(struct clk *c)
626{
627 u32 val;
628
629 val = pmc_readl(PMC_DPD_PADS_ORIDE);
630 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
631
632 val = pmc_readl(PMC_CTRL);
633 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
634
635 return 0;
636}
637
638static void tegra2_blink_clk_disable(struct clk *c)
639{
640 u32 val;
641
642 val = pmc_readl(PMC_CTRL);
643 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
644
645 val = pmc_readl(PMC_DPD_PADS_ORIDE);
646 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
647}
648
649static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
650{
651 unsigned long parent_rate = clk_get_rate(c->parent);
652 if (rate >= parent_rate) {
653 c->div = 1;
654 pmc_writel(0, c->reg);
655 } else {
656 unsigned int on_off;
657 u32 val;
658
659 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
660 c->div = on_off * 8;
661
662 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
663 PMC_BLINK_TIMER_DATA_ON_SHIFT;
664 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
665 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
666 val |= on_off;
667 val |= PMC_BLINK_TIMER_ENB;
668 pmc_writel(val, c->reg);
669 }
670
671 return 0;
672}
673
674static struct clk_ops tegra_blink_clk_ops = {
675 .init = &tegra2_blink_clk_init,
676 .enable = &tegra2_blink_clk_enable,
677 .disable = &tegra2_blink_clk_disable,
678 .set_rate = &tegra2_blink_clk_set_rate,
679};
680
681/* PLL Functions */
682static int tegra2_pll_clk_wait_for_lock(struct clk *c)
683{
684 udelay(c->u.pll.lock_delay);
685
686 return 0;
687}
688
689static void tegra2_pll_clk_init(struct clk *c)
690{
691 u32 val = clk_readl(c->reg + PLL_BASE);
692
693 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
694
695 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
696 pr_warning("Clock %s has unknown fixed frequency\n", c->name);
697 c->mul = 1;
698 c->div = 1;
699 } else if (val & PLL_BASE_BYPASS) {
700 c->mul = 1;
701 c->div = 1;
702 } else {
703 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
704 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
705 if (c->flags & PLLU)
706 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
707 else
708 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
709 }
710}
711
712static int tegra2_pll_clk_enable(struct clk *c)
713{
714 u32 val;
715 pr_debug("%s on clock %s\n", __func__, c->name);
716
717 val = clk_readl(c->reg + PLL_BASE);
718 val &= ~PLL_BASE_BYPASS;
719 val |= PLL_BASE_ENABLE;
720 clk_writel(val, c->reg + PLL_BASE);
721
722 if (c->flags & PLLD) {
723 val = clk_readl(c->reg + PLL_MISC(c) + PLL_BASE);
724 val |= PLLD_MISC_CLKENABLE;
725 clk_writel(val, c->reg + PLL_MISC(c) + PLL_BASE);
726 }
727
728 tegra2_pll_clk_wait_for_lock(c);
729
730 return 0;
731}
732
733static void tegra2_pll_clk_disable(struct clk *c)
734{
735 u32 val;
736 pr_debug("%s on clock %s\n", __func__, c->name);
737
738 val = clk_readl(c->reg);
739 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
740 clk_writel(val, c->reg);
741
742 if (c->flags & PLLD) {
743 val = clk_readl(c->reg + PLL_MISC(c) + PLL_BASE);
744 val &= ~PLLD_MISC_CLKENABLE;
745 clk_writel(val, c->reg + PLL_MISC(c) + PLL_BASE);
746 }
747}
748
749static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
750{
751 u32 val;
752 u32 p_div = 0;
753 u32 old_base = 0;
754 unsigned long input_rate;
755 const struct clk_pll_freq_table *sel;
756
757 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
758
759 input_rate = clk_get_rate(c->parent);
760 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
761 if (sel->input_rate == input_rate && sel->output_rate == rate) {
762 if (c->flags & PLLU) {
763 BUG_ON(sel->p < 1 || sel->p > 2);
764 if (sel->p == 1)
765 p_div = PLLU_BASE_POST_DIV;
766 } else {
767 BUG_ON(sel->p < 1);
768 for (val = sel->p;
769 val > 1; val >>= 1, p_div++)
770 ;
771 p_div <<= PLL_BASE_DIVP_SHIFT;
772 }
773 break;
774 }
775 }
776
777 /*If required rate is not available in pll's frequency table, prepare
778 parameters manually */
779
780 if (sel->input_rate == 0) {
781 unsigned long cfreq;
782 BUG_ON(c->flags & PLLU);
783 struct clk_pll_freq_table cfg;
784 sel = &cfg;
785
786 switch (input_rate) {
787 case 12000000:
788 case 26000000:
789 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
790 break;
791 case 13000000:
792 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
793 break;
794 case 16800000:
795 case 19200000:
796 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
797 break;
798 default:
799 if (c->parent->flags & DIV_U71_FIXED) {
800 /* PLLP_OUT1 rate is not in PLLA table */
801 pr_warn("%s: failed %s ref/out rates %lu/%lu\n",
802 __func__, c->name, input_rate, rate);
803 cfreq = input_rate/(input_rate/1000000);
804 break;
805 }
806 pr_err("%s: Unexpected reference rate %lu\n",
807 __func__, input_rate);
808 BUG();
809 }
810
811 /* Raise VCO to guarantee 0.5% accuracy */
812 for (cfg.output_rate = rate;
813 cfg.output_rate < 200 * cfreq;
814 cfg.output_rate <<= 1, p_div++)
815 ;
816
817 cfg.p = 0x1 << p_div;
818 cfg.m = input_rate / cfreq;
819 cfg.n = cfg.output_rate / cfreq;
820 cfg.cpcon = 0x08; /* OUT_OF_TABLE_CPCON */
821
822 if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
823 (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
824 (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
825 (cfg.output_rate > c->u.pll.vco_max)) {
826 pr_err("%s: Failed to set %s out-of-table rate %lu\n",
827 __func__, c->name, rate);
828 return -EINVAL;
829 }
830 p_div <<= PLL_BASE_DIVP_SHIFT;
831 }
832
833 /*Setup multipliers and divisors, then setup rate*/
834
835 c->mul = sel->n;
836 c->div = sel->m * sel->p;
837
838 old_base = val = clk_readl(c->reg + PLL_BASE);
839 if (c->flags & PLL_FIXED)
840 val |= PLL_BASE_OVERRIDE;
841 val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
842 ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
843 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
844 (sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
845 if (val == old_base)
846 return 0;
847
848 if (c->state == ON) {
849 tegra2_pll_clk_disable(c);
850 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
851 }
852 clk_writel(val, c->reg + PLL_BASE);
853
854 if (c->flags & PLL_HAS_CPCON) {
855 val = clk_readl(c->reg + PLL_MISC(c));
856 val &= ~PLL_MISC_CPCON_MASK;
857 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
858 if (c->flags & (PLLU | PLLD)) {
859 val &= ~PLL_MISC_LFCON_MASK;
860 if (sel->n >= PLLDU_LFCON_SET_DIVN)
861 val |= 0x1 << PLL_MISC_LFCON_SHIFT;
862 } else if (c->flags & (PLLX | PLLM)) {
863 val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
864 if (rate >= (c->u.pll.vco_max >> 1))
865 val |= 0x1 << PLL_MISC_DCCON_SHIFT;
866 }
867 clk_writel(val, c->reg + PLL_MISC(c));
868 }
869
870 if (c->state == ON)
871 tegra2_pll_clk_enable(c);
872
873 return 0;
874
875}
876
877static struct clk_ops tegra_pll_ops = {
878 .init = tegra2_pll_clk_init,
879 .enable = tegra2_pll_clk_enable,
880 .disable = tegra2_pll_clk_disable,
881 .set_rate = tegra2_pll_clk_set_rate,
882};
883
884static int tegra2_plle_clk_enable(struct clk *c)
885{
886 u32 val;
887
888 pr_debug("%s on clock %s\n", __func__, c->name);
889
890 mdelay(1);
891
892 val = clk_readl(c->reg + PLL_BASE);
893 if (!(val & PLLE_MISC_READY))
894 return -EBUSY;
895
896 val = clk_readl(c->reg + PLL_BASE);
897 val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
898 clk_writel(val, c->reg + PLL_BASE);
899
900 return 0;
901}
902
903static struct clk_ops tegra_plle_ops = {
904 .init = tegra2_pll_clk_init,
905 .enable = tegra2_plle_clk_enable,
906 .set_rate = tegra2_pll_clk_set_rate,
907};
908
909/* Clock divider ops */
910static void tegra2_pll_div_clk_init(struct clk *c)
911{
912 u32 val = clk_readl(c->reg);
913 u32 divu71;
914 val >>= c->reg_shift;
915 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
916 if (!(val & PLL_OUT_RESET_DISABLE))
917 c->state = OFF;
918
919 if (c->flags & DIV_U71) {
920 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
921 c->div = (divu71 + 2);
922 c->mul = 2;
923 } else if (c->flags & DIV_2) {
924 c->div = 2;
925 c->mul = 1;
926 } else {
927 c->div = 1;
928 c->mul = 1;
929 }
930}
931
932static int tegra2_pll_div_clk_enable(struct clk *c)
933{
934 u32 val;
935 u32 new_val;
936 unsigned long flags;
937
938 pr_debug("%s: %s\n", __func__, c->name);
939 if (c->flags & DIV_U71) {
940 spin_lock_irqsave(&clock_register_lock, flags);
941 val = clk_readl(c->reg);
942 new_val = val >> c->reg_shift;
943 new_val &= 0xFFFF;
944
945 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
946
947 val &= ~(0xFFFF << c->reg_shift);
948 val |= new_val << c->reg_shift;
949 clk_writel(val, c->reg);
950 spin_unlock_irqrestore(&clock_register_lock, flags);
951 return 0;
952 } else if (c->flags & DIV_2) {
953 BUG_ON(!(c->flags & PLLD));
954 spin_lock_irqsave(&clock_register_lock, flags);
955 val = clk_readl(c->reg);
956 val &= ~PLLD_MISC_DIV_RST;
957 clk_writel(val, c->reg);
958 spin_unlock_irqrestore(&clock_register_lock, flags);
959 return 0;
960 }
961 return -EINVAL;
962}
963
964static void tegra2_pll_div_clk_disable(struct clk *c)
965{
966 u32 val;
967 u32 new_val;
968 unsigned long flags;
969
970 pr_debug("%s: %s\n", __func__, c->name);
971 if (c->flags & DIV_U71) {
972 spin_lock_irqsave(&clock_register_lock, flags);
973 val = clk_readl(c->reg);
974 new_val = val >> c->reg_shift;
975 new_val &= 0xFFFF;
976
977 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
978
979 val &= ~(0xFFFF << c->reg_shift);
980 val |= new_val << c->reg_shift;
981 clk_writel(val, c->reg);
982 spin_unlock_irqrestore(&clock_register_lock, flags);
983 } else if (c->flags & DIV_2) {
984 BUG_ON(!(c->flags & PLLD));
985 spin_lock_irqsave(&clock_register_lock, flags);
986 val = clk_readl(c->reg);
987 val |= PLLD_MISC_DIV_RST;
988 clk_writel(val, c->reg);
989 spin_unlock_irqrestore(&clock_register_lock, flags);
990 }
991}
992
993static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
994{
995 u32 val;
996 u32 new_val;
997 int divider_u71;
998 unsigned long parent_rate = clk_get_rate(c->parent);
999 unsigned long flags;
1000
1001 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1002 if (c->flags & DIV_U71) {
1003 divider_u71 = clk_div71_get_divider(parent_rate, rate);
1004 if (divider_u71 >= 0) {
1005 spin_lock_irqsave(&clock_register_lock, flags);
1006 val = clk_readl(c->reg);
1007 new_val = val >> c->reg_shift;
1008 new_val &= 0xFFFF;
1009 if (c->flags & DIV_U71_FIXED)
1010 new_val |= PLL_OUT_OVERRIDE;
1011 new_val &= ~PLL_OUT_RATIO_MASK;
1012 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
1013
1014 val &= ~(0xFFFF << c->reg_shift);
1015 val |= new_val << c->reg_shift;
1016 clk_writel(val, c->reg);
1017 c->div = divider_u71 + 2;
1018 c->mul = 2;
1019 spin_unlock_irqrestore(&clock_register_lock, flags);
1020 return 0;
1021 }
1022 } else if (c->flags & DIV_2) {
1023 if (parent_rate == rate * 2)
1024 return 0;
1025 }
1026 return -EINVAL;
1027}
1028
1029static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
1030{
1031 int divider;
1032 unsigned long parent_rate = clk_get_rate(c->parent);
1033 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1034
1035 if (c->flags & DIV_U71) {
1036 divider = clk_div71_get_divider(parent_rate, rate);
1037 if (divider < 0)
1038 return divider;
1039 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1040 } else if (c->flags & DIV_2) {
1041 return DIV_ROUND_UP(parent_rate, 2);
1042 }
1043 return -EINVAL;
1044}
1045
1046static struct clk_ops tegra_pll_div_ops = {
1047 .init = tegra2_pll_div_clk_init,
1048 .enable = tegra2_pll_div_clk_enable,
1049 .disable = tegra2_pll_div_clk_disable,
1050 .set_rate = tegra2_pll_div_clk_set_rate,
1051 .round_rate = tegra2_pll_div_clk_round_rate,
1052};
1053
1054/* Periph clk ops */
1055
1056static void tegra2_periph_clk_init(struct clk *c)
1057{
1058 u32 val = clk_readl(c->reg);
1059 const struct clk_mux_sel *mux = 0;
1060 const struct clk_mux_sel *sel;
1061 if (c->flags & MUX) {
1062 for (sel = c->inputs; sel->input != NULL; sel++) {
1063 if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
1064 mux = sel;
1065 }
1066 BUG_ON(!mux);
1067
1068 c->parent = mux->input;
1069 } else {
1070 c->parent = c->inputs[0].input;
1071 }
1072
1073 if (c->flags & DIV_U71) {
1074 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
1075 c->div = divu71 + 2;
1076 c->mul = 2;
1077 } else if (c->flags & DIV_U16) {
1078 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
1079 c->div = divu16 + 1;
1080 c->mul = 1;
1081 } else {
1082 c->div = 1;
1083 c->mul = 1;
1084 }
1085
1086 c->state = ON;
1087 if (c->flags & PERIPH_NO_ENB)
1088 return;
1089
1090 if (!c->u.periph.clk_num)
1091 return;
1092
1093 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1094 PERIPH_CLK_TO_ENB_BIT(c)))
1095 c->state = OFF;
1096
1097 if (!(c->flags & PERIPH_NO_RESET))
1098 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
1099 PERIPH_CLK_TO_ENB_BIT(c))
1100 c->state = OFF;
1101}
1102
1103static int tegra2_periph_clk_enable(struct clk *c)
1104{
1105 u32 val;
1106 unsigned long flags;
1107 int refcount;
1108 pr_debug("%s on clock %s\n", __func__, c->name);
1109
1110 if (c->flags & PERIPH_NO_ENB)
1111 return 0;
1112
1113 if (!c->u.periph.clk_num)
1114 return 0;
1115
1116 spin_lock_irqsave(&clock_register_lock, flags);
1117
1118 refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
1119
1120 if (refcount > 1)
1121 goto out;
1122
1123 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1124 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1125 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
1126 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1127 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1128 if (c->flags & PERIPH_EMC_ENB) {
1129 /* The EMC peripheral clock has 2 extra enable bits */
1130 /* FIXME: Do they need to be disabled? */
1131 val = clk_readl(c->reg);
1132 val |= 0x3 << 24;
1133 clk_writel(val, c->reg);
1134 }
1135
1136out:
1137 spin_unlock_irqrestore(&clock_register_lock, flags);
1138
1139 return 0;
1140}
1141
1142static void tegra2_periph_clk_disable(struct clk *c)
1143{
1144 unsigned long flags;
1145 unsigned long val;
1146
1147 pr_debug("%s on clock %s\n", __func__, c->name);
1148
1149 if (c->flags & PERIPH_NO_ENB)
1150 return;
1151
1152 if (!c->u.periph.clk_num)
1153 return;
1154
1155 spin_lock_irqsave(&clock_register_lock, flags);
1156
1157 if (c->refcnt)
1158 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
1159
1160 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
1161 /* If peripheral is in the APB bus then read the APB bus to
1162 * flush the write operation in apb bus. This will avoid the
1163 * peripheral access after disabling clock*/
1164 if (c->flags & PERIPH_ON_APB)
1165 val = chipid_readl();
1166
1167 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1168 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1169 }
1170
1171 spin_unlock_irqrestore(&clock_register_lock, flags);
1172}
1173
1174static void tegra2_periph_clk_reset(struct clk *c, bool assert)
1175{
1176 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
1177 unsigned long val;
1178
1179 pr_debug("%s %s on clock %s\n", __func__,
1180 assert ? "assert" : "deassert", c->name);
1181
1182 if (c->flags & PERIPH_NO_ENB)
1183 return;
1184
1185 BUG_ON(!c->u.periph.clk_num);
1186
1187 if (!(c->flags & PERIPH_NO_RESET)) {
1188 /* If peripheral is in the APB bus then read the APB bus to
1189 * flush the write operation in apb bus. This will avoid the
1190 * peripheral access after disabling clock*/
1191 if (c->flags & PERIPH_ON_APB)
1192 val = chipid_readl();
1193
1194 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1195 base + PERIPH_CLK_TO_ENB_SET_REG(c));
1196 }
1197}
1198
1199static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
1200{
1201 u32 val;
1202 const struct clk_mux_sel *sel;
1203 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
1204 for (sel = c->inputs; sel->input != NULL; sel++) {
1205 if (sel->input == p) {
1206 val = clk_readl(c->reg);
1207 val &= ~((c->reg_shift >> 8) << (c->reg_shift & 0xFF));
1208 val |= (sel->value) << (c->reg_shift & 0xFF);
1209
1210 if (c->refcnt)
1211 clk_enable(p);
1212
1213 clk_writel(val, c->reg);
1214
1215 if (c->refcnt && c->parent)
1216 clk_disable(c->parent);
1217
1218 clk_reparent(c, p);
1219 return 0;
1220 }
1221 }
1222
1223 return -EINVAL;
1224}
1225
1226static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
1227{
1228 u32 val;
1229 int divider;
1230 unsigned long parent_rate = clk_get_rate(c->parent);
1231
1232 if (c->flags & DIV_U71) {
1233 divider = clk_div71_get_divider(parent_rate, rate);
1234 if (divider >= 0) {
1235 val = clk_readl(c->reg);
1236 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
1237 val |= divider;
1238 clk_writel(val, c->reg);
1239 c->div = divider + 2;
1240 c->mul = 2;
1241 return 0;
1242 }
1243 } else if (c->flags & DIV_U16) {
1244 divider = clk_div16_get_divider(parent_rate, rate);
1245 if (divider >= 0) {
1246 val = clk_readl(c->reg);
1247 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1248 val |= divider;
1249 clk_writel(val, c->reg);
1250 c->div = divider + 1;
1251 c->mul = 1;
1252 return 0;
1253 }
1254 } else if (parent_rate <= rate) {
1255 c->div = 1;
1256 c->mul = 1;
1257 return 0;
1258 }
1259 return -EINVAL;
1260}
1261
1262static long tegra2_periph_clk_round_rate(struct clk *c,
1263 unsigned long rate)
1264{
1265 int divider;
1266 unsigned long parent_rate = clk_get_rate(c->parent);
1267 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1268
1269 if (c->flags & DIV_U71) {
1270 divider = clk_div71_get_divider(parent_rate, rate);
1271 if (divider < 0)
1272 return divider;
1273
1274 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1275 } else if (c->flags & DIV_U16) {
1276 divider = clk_div16_get_divider(parent_rate, rate);
1277 if (divider < 0)
1278 return divider;
1279 return DIV_ROUND_UP(parent_rate, divider + 1);
1280 }
1281 return -EINVAL;
1282}
1283
1284static struct clk_ops tegra_periph_clk_ops = {
1285 .init = &tegra2_periph_clk_init,
1286 .enable = &tegra2_periph_clk_enable,
1287 .disable = &tegra2_periph_clk_disable,
1288 .set_parent = &tegra2_periph_clk_set_parent,
1289 .set_rate = &tegra2_periph_clk_set_rate,
1290 .round_rate = &tegra2_periph_clk_round_rate,
1291 .reset = &tegra2_periph_clk_reset,
1292};
1293
1294/* The SDMMC controllers have extra bits in the clock source register that
1295 * adjust the delay between the clock and data to compenstate for delays
1296 * on the PCB. */
1297void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1298{
1299 u32 reg;
1300
1301 delay = clamp(delay, 0, 15);
1302 reg = clk_readl(c->reg);
1303 reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
1304 reg |= SDMMC_CLK_INT_FB_SEL;
1305 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
1306 clk_writel(reg, c->reg);
1307}
1308
1309/* External memory controller clock ops */
1310static void tegra2_emc_clk_init(struct clk *c)
1311{
1312 tegra2_periph_clk_init(c);
1313 c->max_rate = clk_get_rate_locked(c);
1314}
1315
1316static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1317{
1318 long new_rate = rate;
1319
1320 new_rate = tegra_emc_round_rate(new_rate);
1321 if (new_rate < 0)
1322 return c->max_rate;
1323
1324 return new_rate;
1325}
1326
1327static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
1328{
1329 int ret;
1330 int divider;
1331 struct clk *p = NULL;
1332 unsigned long inp_rate;
1333 unsigned long new_rate;
1334 const struct clk_mux_sel *sel;
1335
1336 for (sel = c->inputs; sel->input != NULL; sel++) {
1337 inp_rate = clk_get_rate(sel->input);
1338
1339 divider = clk_div71_get_divider(inp_rate, rate);
1340 if (divider < 0)
1341 return divider;
1342
1343 new_rate = DIV_ROUND_UP(inp_rate * 2, divider + 2);
1344 if ((abs(rate - new_rate)) < 2000) {
1345 p = sel->input;
1346 break;
1347 }
1348 }
1349
1350 BUG_ON(!p);
1351 BUG_ON(divider & 0x1);
1352
1353 /*
1354 * The Tegra2 memory controller has an interlock with the clock
1355 * block that allows memory shadowed registers to be updated,
1356 * and then transfer them to the main registers at the same
1357 * time as the clock update without glitches.
1358 */
1359 ret = tegra_emc_set_rate(rate);
1360 if (ret < 0)
1361 return ret;
1362
1363 if (c->parent != p) {
1364 BUG_ON(divider != 0);
1365 ret = clk_set_parent_locked(c, p);
1366 udelay(1);
1367 return ret;
1368 }
1369
1370 ret = tegra2_periph_clk_set_rate(c, rate);
1371 udelay(1);
1372
1373 return ret;
1374}
1375
1376static struct clk_ops tegra_emc_clk_ops = {
1377 .init = &tegra2_emc_clk_init,
1378 .enable = &tegra2_periph_clk_enable,
1379 .disable = &tegra2_periph_clk_disable,
1380 .set_parent = &tegra2_periph_clk_set_parent,
1381 .set_rate = &tegra2_emc_clk_set_rate,
1382 .round_rate = &tegra2_emc_clk_round_rate,
1383 .reset = &tegra2_periph_clk_reset,
1384 .shared_bus_update = &tegra2_clk_shared_bus_update,
1385};
1386
1387/* Clock doubler ops */
1388static void tegra2_clk_double_init(struct clk *c)
1389{
1390 c->mul = 2;
1391 c->div = 1;
1392 c->state = ON;
1393
1394 if (!c->u.periph.clk_num)
1395 return;
1396
1397 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1398 PERIPH_CLK_TO_ENB_BIT(c)))
1399 c->state = OFF;
1400};
1401
1402static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
1403{
1404 if (rate != 2 * clk_get_rate(c->parent))
1405 return -EINVAL;
1406 c->mul = 2;
1407 c->div = 1;
1408 return 0;
1409}
1410
1411static struct clk_ops tegra_clk_double_ops = {
1412 .init = &tegra2_clk_double_init,
1413 .enable = &tegra2_periph_clk_enable,
1414 .disable = &tegra2_periph_clk_disable,
1415 .set_rate = &tegra2_clk_double_set_rate,
1416};
1417
1418/* Audio sync clock ops */
1419static void tegra2_audio_sync_clk_init(struct clk *c)
1420{
1421 int source;
1422 const struct clk_mux_sel *sel;
1423 u32 val = clk_readl(c->reg);
1424 c->state = (val & (1<<4)) ? OFF : ON;
1425 source = val & 0xf;
1426 for (sel = c->inputs; sel->input != NULL; sel++)
1427 if (sel->value == source)
1428 break;
1429 BUG_ON(sel->input == NULL);
1430 c->parent = sel->input;
1431}
1432
1433static int tegra2_audio_sync_clk_enable(struct clk *c)
1434{
1435 clk_writel(0, c->reg);
1436 return 0;
1437}
1438
1439static void tegra2_audio_sync_clk_disable(struct clk *c)
1440{
1441 clk_writel(1, c->reg);
1442}
1443
1444static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
1445{
1446 u32 val;
1447 const struct clk_mux_sel *sel;
1448 for (sel = c->inputs; sel->input != NULL; sel++) {
1449 if (sel->input == p) {
1450 val = clk_readl(c->reg);
1451 val &= ~0xf;
1452 val |= sel->value;
1453
1454 if (c->refcnt)
1455 clk_enable(p);
1456
1457 clk_writel(val, c->reg);
1458
1459 if (c->refcnt && c->parent)
1460 clk_disable(c->parent);
1461
1462 clk_reparent(c, p);
1463 return 0;
1464 }
1465 }
1466
1467 return -EINVAL;
1468}
1469
1470static struct clk_ops tegra_audio_sync_clk_ops = {
1471 .init = tegra2_audio_sync_clk_init,
1472 .enable = tegra2_audio_sync_clk_enable,
1473 .disable = tegra2_audio_sync_clk_disable,
1474 .set_parent = tegra2_audio_sync_clk_set_parent,
1475};
1476
1477/* call this function after pinmux configuration */
1478static void tegra2_cdev_clk_set_parent(struct clk *c)
1479{
1480 const struct clk_mux_sel *mux = 0;
1481 const struct clk_mux_sel *sel;
1482 enum tegra_pingroup pg = TEGRA_PINGROUP_CDEV1;
1483 int val;
1484
1485 /* Get pinmux setting for cdev1 and cdev2 from APB_MISC register */
1486 if (!strcmp(c->name, "cdev2"))
1487 pg = TEGRA_PINGROUP_CDEV2;
1488
1489 val = tegra_pinmux_get_func(pg);
1490 for (sel = c->inputs; sel->input != NULL; sel++) {
1491 if (val == sel->value)
1492 mux = sel;
1493 }
1494 BUG_ON(!mux);
1495
1496 c->parent = mux->input;
1497}
1498
1499/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1500static void tegra2_cdev_clk_init(struct clk *c)
1501{
1502 const struct clk_mux_sel *sel;
1503
1504 /* Find max rate from inputs */
1505 for (sel = c->inputs; sel->input != NULL; sel++) {
1506 c->max_rate = max(sel->input->max_rate, c->max_rate);
1507 }
1508
1509 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1510 * currently done in the pinmux code. */
1511 c->state = ON;
1512
1513 BUG_ON(!c->u.periph.clk_num);
1514
1515 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1516 PERIPH_CLK_TO_ENB_BIT(c)))
1517 c->state = OFF;
1518}
1519
1520static int tegra2_cdev_clk_enable(struct clk *c)
1521{
1522 BUG_ON(!c->u.periph.clk_num);
1523
1524 if (!c->parent) {
1525 /* Set parent from inputs */
1526 tegra2_cdev_clk_set_parent(c);
1527 clk_enable(c->parent);
1528 }
1529
1530 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1531 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1532 return 0;
1533}
1534
1535static void tegra2_cdev_clk_disable(struct clk *c)
1536{
1537 BUG_ON(!c->u.periph.clk_num);
1538
1539 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1540 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1541}
1542
1543static struct clk_ops tegra_cdev_clk_ops = {
1544 .init = &tegra2_cdev_clk_init,
1545 .enable = &tegra2_cdev_clk_enable,
1546 .disable = &tegra2_cdev_clk_disable,
1547};
1548
1549/* shared bus ops */
1550/*
1551 * Some clocks may have multiple downstream users that need to request a
1552 * higher clock rate. Shared bus clocks provide a unique shared_bus_user
1553 * clock to each user. The frequency of the bus is set to the highest
1554 * enabled shared_bus_user clock, with a minimum value set by the
1555 * shared bus.
1556 */
1557static int tegra2_clk_shared_bus_update(struct clk *bus)
1558{
1559 struct clk *c;
1560 unsigned long old_rate;
1561 unsigned long rate = bus->min_rate;
1562 int sku_id = tegra_sku_id();
1563
1564 list_for_each_entry(c, &bus->shared_bus_list,
1565 u.shared_bus_user.node) {
1566 if (c->u.shared_bus_user.enabled)
1567 rate = max(c->u.shared_bus_user.rate, rate);
1568 }
1569
1570 old_rate = clk_get_rate_locked(bus);
1571
1572 if (rate == old_rate)
1573 return 0;
1574
1575 /* WAR: For AP25 EMC scaling */
1576 if ((sku_id == 0x17) && (bus->flags & PERIPH_EMC_ENB)) {
1577 if (old_rate == AP25_EMC_SCALING_STEP &&
1578 rate != AP25_EMC_INTERMEDIATE_RATE)
1579 clk_set_rate_locked(bus, AP25_EMC_INTERMEDIATE_RATE);
1580
1581 if (((old_rate > AP25_EMC_BRIDGE_RATE) &&
1582 (rate < AP25_EMC_BRIDGE_RATE)) ||
1583 ((old_rate < AP25_EMC_BRIDGE_RATE) &&
1584 (rate > AP25_EMC_BRIDGE_RATE)))
1585 clk_set_rate_locked(bus, AP25_EMC_BRIDGE_RATE);
1586
1587 if (rate == AP25_EMC_SCALING_STEP &&
1588 old_rate != AP25_EMC_INTERMEDIATE_RATE)
1589 clk_set_rate_locked(bus, AP25_EMC_INTERMEDIATE_RATE);
1590 }
1591
1592 return clk_set_rate_locked(bus, rate);
1593};
1594
1595static void tegra_clk_shared_bus_init(struct clk *c)
1596{
1597 unsigned long flags;
1598
1599 c->max_rate = c->parent->max_rate;
1600 c->u.shared_bus_user.rate = c->parent->max_rate;
1601 c->state = OFF;
1602 c->set = true;
1603
1604 clk_lock_save(c->parent, &flags);
1605
1606 list_add_tail(&c->u.shared_bus_user.node,
1607 &c->parent->shared_bus_list);
1608
1609 clk_unlock_restore(c->parent, &flags);
1610}
1611
1612static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
1613{
1614 int ret;
1615 long new_rate = rate;
1616
1617 new_rate = clk_round_rate(c->parent, new_rate);
1618 if (new_rate < 0)
1619 return new_rate;
1620
1621 c->u.shared_bus_user.rate = new_rate;
1622 ret = tegra_clk_shared_bus_update(c->parent);
1623
1624 return ret;
1625}
1626
1627static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
1628{
1629 return clk_round_rate(c->parent, rate);
1630}
1631
1632static int tegra_clk_shared_bus_enable(struct clk *c)
1633{
1634 int ret;
1635
1636 c->u.shared_bus_user.enabled = true;
1637 ret = tegra_clk_shared_bus_update(c->parent);
1638 if (strcmp(c->name, "avp.sclk") == 0)
1639 tegra2_statmon_start();
1640
1641 return ret;
1642}
1643
1644static void tegra_clk_shared_bus_disable(struct clk *c)
1645{
1646 int ret;
1647
1648 if (strcmp(c->name, "avp.sclk") == 0)
1649 tegra2_statmon_stop();
1650 c->u.shared_bus_user.enabled = false;
1651 ret = tegra_clk_shared_bus_update(c->parent);
1652 WARN_ON_ONCE(ret);
1653}
1654
1655static struct clk_ops tegra_clk_shared_bus_ops = {
1656 .init = tegra_clk_shared_bus_init,
1657 .enable = tegra_clk_shared_bus_enable,
1658 .disable = tegra_clk_shared_bus_disable,
1659 .set_rate = tegra_clk_shared_bus_set_rate,
1660 .round_rate = tegra_clk_shared_bus_round_rate,
1661};
1662
1663
1664/* Clock definitions */
1665static struct clk tegra_clk_32k = {
1666 .name = "clk_32k",
1667 .rate = 32768,
1668 .ops = NULL,
1669 .max_rate = 32768,
1670};
1671
1672static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
1673 {32768, 12000000, 366, 1, 1, 0},
1674 {32768, 13000000, 397, 1, 1, 0},
1675 {32768, 19200000, 586, 1, 1, 0},
1676 {32768, 26000000, 793, 1, 1, 0},
1677 {0, 0, 0, 0, 0, 0},
1678};
1679
1680static struct clk tegra_pll_s = {
1681 .name = "pll_s",
1682 .flags = PLL_ALT_MISC_REG,
1683 .ops = &tegra_pll_ops,
1684 .parent = &tegra_clk_32k,
1685 .max_rate = 26000000,
1686 .reg = 0xf0,
1687 .u.pll = {
1688 .input_min = 32768,
1689 .input_max = 32768,
1690 .cf_min = 0, /* FIXME */
1691 .cf_max = 0, /* FIXME */
1692 .vco_min = 12000000,
1693 .vco_max = 26000000,
1694 .freq_table = tegra_pll_s_freq_table,
1695 .lock_delay = 300,
1696 },
1697};
1698
1699static struct clk_mux_sel tegra_clk_m_sel[] = {
1700 { .input = &tegra_clk_32k, .value = 0},
1701 { .input = &tegra_pll_s, .value = 1},
1702 { 0, 0},
1703};
1704
1705static struct clk tegra_clk_m = {
1706 .name = "clk_m",
1707 .flags = ENABLE_ON_INIT,
1708 .ops = &tegra_clk_m_ops,
1709 .inputs = tegra_clk_m_sel,
1710 .reg = 0x1fc,
1711 .reg_shift = 28,
1712 .max_rate = 26000000,
1713};
1714
1715static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
1716 { 12000000, 522000000, 348, 8, 1, 8},
1717 { 13000000, 522000000, 522, 13, 1, 8},
1718 { 19200000, 522000000, 435, 16, 1, 8},
1719 { 26000000, 522000000, 522, 26, 1, 8},
1720 { 12000000, 598000000, 598, 12, 1, 8},
1721 { 13000000, 598000000, 598, 13, 1, 8},
1722 { 19200000, 598000000, 375, 12, 1, 6},
1723 { 26000000, 598000000, 598, 26, 1, 8},
1724 { 0, 0, 0, 0, 0, 0 },
1725};
1726
1727static struct clk tegra_pll_c = {
1728 .name = "pll_c",
1729 .flags = PLL_HAS_CPCON,
1730 .ops = &tegra_pll_ops,
1731 .reg = 0x80,
1732 .parent = &tegra_clk_m,
1733 .max_rate = 600000000,
1734 .u.pll = {
1735 .input_min = 2000000,
1736 .input_max = 31000000,
1737 .cf_min = 1000000,
1738 .cf_max = 6000000,
1739 .vco_min = 20000000,
1740 .vco_max = 1400000000,
1741 .freq_table = tegra_pll_c_freq_table,
1742 .lock_delay = 300,
1743 },
1744};
1745
1746static struct clk tegra_pll_c_out1 = {
1747 .name = "pll_c_out1",
1748 .ops = &tegra_pll_div_ops,
1749 .flags = DIV_U71,
1750 .parent = &tegra_pll_c,
1751 .reg = 0x84,
1752 .reg_shift = 0,
1753 .max_rate = 600000000,
1754};
1755
1756static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
1757 { 12000000, 666000000, 666, 12, 1, 8},
1758 { 13000000, 666000000, 666, 13, 1, 8},
1759 { 19200000, 666000000, 555, 16, 1, 8},
1760 { 26000000, 666000000, 666, 26, 1, 8},
1761 { 12000000, 600000000, 600, 12, 1, 8},
1762 { 13000000, 600000000, 600, 13, 1, 8},
1763 { 19200000, 600000000, 375, 12, 1, 6},
1764 { 26000000, 600000000, 600, 26, 1, 8},
1765 { 0, 0, 0, 0, 0, 0 },
1766};
1767
1768static struct clk tegra_pll_m = {
1769 .name = "pll_m",
1770 .flags = PLL_HAS_CPCON,
1771 .ops = &tegra_pll_ops,
1772 .reg = 0x90,
1773 .parent = &tegra_clk_m,
1774 .max_rate = 800000000,
1775 .u.pll = {
1776 .input_min = 2000000,
1777 .input_max = 31000000,
1778 .cf_min = 1000000,
1779 .cf_max = 6000000,
1780 .vco_min = 20000000,
1781 .vco_max = 1200000000,
1782 .freq_table = tegra_pll_m_freq_table,
1783 .lock_delay = 300,
1784 },
1785};
1786
1787static struct clk tegra_pll_m_out1 = {
1788 .name = "pll_m_out1",
1789 .ops = &tegra_pll_div_ops,
1790 .flags = DIV_U71,
1791 .parent = &tegra_pll_m,
1792 .reg = 0x94,
1793 .reg_shift = 0,
1794 .max_rate = 600000000,
1795};
1796
1797static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
1798 { 12000000, 216000000, 432, 12, 2, 8},
1799 { 13000000, 216000000, 432, 13, 2, 8},
1800 { 19200000, 216000000, 90, 4, 2, 1},
1801 { 26000000, 216000000, 432, 26, 2, 8},
1802 { 12000000, 432000000, 432, 12, 1, 8},
1803 { 13000000, 432000000, 432, 13, 1, 8},
1804 { 19200000, 432000000, 90, 4, 1, 1},
1805 { 26000000, 432000000, 432, 26, 1, 8},
1806 { 0, 0, 0, 0, 0, 0 },
1807};
1808
1809static struct clk tegra_pll_p = {
1810 .name = "pll_p",
1811 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
1812 .ops = &tegra_pll_ops,
1813 .reg = 0xa0,
1814 .parent = &tegra_clk_m,
1815 .max_rate = 432000000,
1816 .u.pll = {
1817 .input_min = 2000000,
1818 .input_max = 31000000,
1819 .cf_min = 1000000,
1820 .cf_max = 6000000,
1821 .vco_min = 20000000,
1822 .vco_max = 1400000000,
1823 .freq_table = tegra_pll_p_freq_table,
1824 .lock_delay = 300,
1825 },
1826};
1827
1828static struct clk tegra_pll_p_out1 = {
1829 .name = "pll_p_out1",
1830 .ops = &tegra_pll_div_ops,
1831 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1832 .parent = &tegra_pll_p,
1833 .reg = 0xa4,
1834 .reg_shift = 0,
1835 .max_rate = 432000000,
1836};
1837
1838static struct clk tegra_pll_p_out2 = {
1839 .name = "pll_p_out2",
1840 .ops = &tegra_pll_div_ops,
1841 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1842 .parent = &tegra_pll_p,
1843 .reg = 0xa4,
1844 .reg_shift = 16,
1845 .max_rate = 432000000,
1846};
1847
1848static struct clk tegra_pll_p_out3 = {
1849 .name = "pll_p_out3",
1850 .ops = &tegra_pll_div_ops,
1851 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1852 .parent = &tegra_pll_p,
1853 .reg = 0xa8,
1854 .reg_shift = 0,
1855 .max_rate = 432000000,
1856};
1857
1858static struct clk tegra_pll_p_out4 = {
1859 .name = "pll_p_out4",
1860 .ops = &tegra_pll_div_ops,
1861 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1862 .parent = &tegra_pll_p,
1863 .reg = 0xa8,
1864 .reg_shift = 16,
1865 .max_rate = 432000000,
1866};
1867
1868static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
1869 { 28800000, 56448000, 49, 25, 1, 1},
1870 { 28800000, 73728000, 64, 25, 1, 1},
1871 { 28800000, 24000000, 5, 6, 1, 1},
1872 { 0, 0, 0, 0, 0, 0 },
1873};
1874
1875static struct clk tegra_pll_a = {
1876 .name = "pll_a",
1877 .flags = PLL_HAS_CPCON,
1878 .ops = &tegra_pll_ops,
1879 .reg = 0xb0,
1880 .parent = &tegra_pll_p_out1,
1881 .max_rate = 73728000,
1882 .u.pll = {
1883 .input_min = 2000000,
1884 .input_max = 31000000,
1885 .cf_min = 1000000,
1886 .cf_max = 6000000,
1887 .vco_min = 20000000,
1888 .vco_max = 1400000000,
1889 .freq_table = tegra_pll_a_freq_table,
1890 .lock_delay = 300,
1891 },
1892};
1893
1894static struct clk tegra_pll_a_out0 = {
1895 .name = "pll_a_out0",
1896 .ops = &tegra_pll_div_ops,
1897 .flags = DIV_U71,
1898 .parent = &tegra_pll_a,
1899 .reg = 0xb4,
1900 .reg_shift = 0,
1901 .max_rate = 73728000,
1902};
1903
1904static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
1905 { 12000000, 216000000, 216, 12, 1, 4},
1906 { 13000000, 216000000, 216, 13, 1, 4},
1907 { 19200000, 216000000, 135, 12, 1, 3},
1908 { 26000000, 216000000, 216, 26, 1, 4},
1909
1910 { 12000000, 5000000, 10, 24, 1, 4},
1911 { 12000000, 10000000, 10, 12, 1, 4},
1912 { 12000000, 161500000, 323, 24, 1, 4},
1913 { 12000000, 162000000, 162, 12, 1, 4},
1914
1915 { 12000000, 594000000, 594, 12, 1, 8},
1916 { 13000000, 594000000, 594, 13, 1, 8},
1917 { 19200000, 594000000, 495, 16, 1, 8},
1918 { 26000000, 594000000, 594, 26, 1, 8},
1919
1920 { 12000000, 1000000000, 1000, 12, 1, 12},
1921 { 13000000, 1000000000, 1000, 13, 1, 12},
1922 { 19200000, 1000000000, 625, 12, 1, 8},
1923 { 26000000, 1000000000, 1000, 26, 1, 12},
1924
1925 { 12000000, 504000000, 504, 12, 1, 8},
1926 { 13000000, 504000000, 504, 13, 1, 8},
1927 { 19200000, 504000000, 420, 16, 1, 8},
1928 { 26000000, 504000000, 504, 26, 1, 8},
1929
1930 { 0, 0, 0, 0, 0, 0 },
1931};
1932
1933static struct clk tegra_pll_d = {
1934 .name = "pll_d",
1935 .flags = PLL_HAS_CPCON | PLLD,
1936 .ops = &tegra_pll_ops,
1937 .reg = 0xd0,
1938 .parent = &tegra_clk_m,
1939 .max_rate = 1000000000,
1940 .u.pll = {
1941 .input_min = 2000000,
1942 .input_max = 40000000,
1943 .cf_min = 1000000,
1944 .cf_max = 6000000,
1945 .vco_min = 40000000,
1946 .vco_max = 1000000000,
1947 .freq_table = tegra_pll_d_freq_table,
1948 .lock_delay = 1000,
1949 },
1950};
1951
1952static struct clk tegra_pll_d_out0 = {
1953 .name = "pll_d_out0",
1954 .ops = &tegra_pll_div_ops,
1955 .flags = DIV_2 | PLLD,
1956 .parent = &tegra_pll_d,
1957 .max_rate = 500000000,
1958};
1959
1960static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
1961 { 12000000, 480000000, 960, 12, 2, 0},
1962 { 13000000, 480000000, 960, 13, 2, 0},
1963 { 19200000, 480000000, 200, 4, 2, 0},
1964 { 26000000, 480000000, 960, 26, 2, 0},
1965 { 0, 0, 0, 0, 0, 0 },
1966};
1967
1968static struct clk tegra_pll_u = {
1969 .name = "pll_u",
1970 .flags = PLLU,
1971 .ops = &tegra_pll_ops,
1972 .reg = 0xc0,
1973 .parent = &tegra_clk_m,
1974 .max_rate = 480000000,
1975 .u.pll = {
1976 .input_min = 2000000,
1977 .input_max = 40000000,
1978 .cf_min = 1000000,
1979 .cf_max = 6000000,
1980 .vco_min = 480000000,
1981 .vco_max = 960000000,
1982 .freq_table = tegra_pll_u_freq_table,
1983 .lock_delay = 1000,
1984 },
1985};
1986
1987static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
1988 /* 1.2 GHz */
1989 { 12000000, 1200000000, 600, 6, 1, 12},
1990 { 13000000, 1200000000, 923, 10, 1, 12},
1991 { 19200000, 1200000000, 750, 12, 1, 8},
1992 { 26000000, 1200000000, 600, 13, 1, 12},
1993
1994 /* 1 GHz */
1995 { 12000000, 1000000000, 1000, 12, 1, 12},
1996 { 13000000, 1000000000, 1000, 13, 1, 12},
1997 { 19200000, 1000000000, 625, 12, 1, 8},
1998 { 26000000, 1000000000, 1000, 26, 1, 12},
1999
2000 /* 912 MHz */
2001 { 12000000, 912000000, 912, 12, 1, 12},
2002 { 13000000, 912000000, 912, 13, 1, 12},
2003 { 19200000, 912000000, 760, 16, 1, 8},
2004 { 26000000, 912000000, 912, 26, 1, 12},
2005
2006 /* 816 MHz */
2007 { 12000000, 816000000, 816, 12, 1, 12},
2008 { 13000000, 816000000, 816, 13, 1, 12},
2009 { 19200000, 816000000, 680, 16, 1, 8},
2010 { 26000000, 816000000, 816, 26, 1, 12},
2011
2012 /* 760 MHz */
2013 { 12000000, 760000000, 760, 12, 1, 12},
2014 { 13000000, 760000000, 760, 13, 1, 12},
2015 { 19200000, 760000000, 950, 24, 1, 8},
2016 { 26000000, 760000000, 760, 26, 1, 12},
2017
2018 /* 750 MHz */
2019 { 12000000, 750000000, 750, 12, 1, 12},
2020 { 13000000, 750000000, 750, 13, 1, 12},
2021 { 19200000, 750000000, 625, 16, 1, 8},
2022 { 26000000, 750000000, 750, 26, 1, 12},
2023
2024 /* 608 MHz */
2025 { 12000000, 608000000, 608, 12, 1, 12},
2026 { 13000000, 608000000, 608, 13, 1, 12},
2027 { 19200000, 608000000, 380, 12, 1, 8},
2028 { 26000000, 608000000, 608, 26, 1, 12},
2029
2030 /* 456 MHz */
2031 { 12000000, 456000000, 456, 12, 1, 12},
2032 { 13000000, 456000000, 456, 13, 1, 12},
2033 { 19200000, 456000000, 380, 16, 1, 8},
2034 { 26000000, 456000000, 456, 26, 1, 12},
2035
2036 /* 312 MHz */
2037 { 12000000, 312000000, 312, 12, 1, 12},
2038 { 13000000, 312000000, 312, 13, 1, 12},
2039 { 19200000, 312000000, 260, 16, 1, 8},
2040 { 26000000, 312000000, 312, 26, 1, 12},
2041
2042 { 0, 0, 0, 0, 0, 0 },
2043};
2044
2045static struct clk tegra_pll_x = {
2046 .name = "pll_x",
2047 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
2048 .ops = &tegra_pll_ops,
2049 .reg = 0xe0,
2050 .parent = &tegra_clk_m,
2051 .max_rate = 1000000000,
2052 .u.pll = {
2053 .input_min = 2000000,
2054 .input_max = 31000000,
2055 .cf_min = 1000000,
2056 .cf_max = 6000000,
2057 .vco_min = 20000000,
2058 .vco_max = 1200000000,
2059 .freq_table = tegra_pll_x_freq_table,
2060 .lock_delay = 300,
2061 },
2062};
2063
2064static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
2065 { 12000000, 100000000, 200, 24, 1, 0 },
2066 { 0, 0, 0, 0, 0, 0 },
2067};
2068
2069static struct clk tegra_pll_e = {
2070 .name = "pll_e",
2071 .flags = PLL_ALT_MISC_REG,
2072 .ops = &tegra_plle_ops,
2073 .parent = &tegra_clk_m,
2074 .reg = 0xe8,
2075 .max_rate = 100000000,
2076 .u.pll = {
2077 .input_min = 12000000,
2078 .input_max = 12000000,
2079 .freq_table = tegra_pll_e_freq_table,
2080 },
2081};
2082
2083static struct clk tegra_clk_d = {
2084 .name = "clk_d",
2085 .flags = PERIPH_NO_RESET,
2086 .ops = &tegra_clk_double_ops,
2087 .reg = 0x34,
2088 .reg_shift = 12,
2089 .parent = &tegra_clk_m,
2090 .max_rate = 52000000,
2091 .u.periph = {
2092 .clk_num = 90,
2093 },
2094};
2095
2096/* initialized before peripheral clocks */
2097static struct clk_mux_sel mux_audio_sync_clk[8+1];
2098static const struct audio_sources {
2099 const char *name;
2100 int value;
2101} mux_audio_sync_clk_sources[] = {
2102 { .name = "spdif_in", .value = 0 },
2103 { .name = "i2s1", .value = 1 },
2104 { .name = "i2s2", .value = 2 },
2105 { .name = "pll_a_out0", .value = 4 },
2106#if 0 /* FIXME: not implemented */
2107 { .name = "ac97", .value = 3 },
2108 { .name = "ext_audio_clk2", .value = 5 },
2109 { .name = "ext_audio_clk1", .value = 6 },
2110 { .name = "ext_vimclk", .value = 7 },
2111#endif
2112 { 0, 0 }
2113};
2114
2115static struct clk tegra_clk_audio = {
2116 .name = "audio",
2117 .inputs = mux_audio_sync_clk,
2118 .reg = 0x38,
2119 .max_rate = 73728000,
2120 .ops = &tegra_audio_sync_clk_ops
2121};
2122
2123static struct clk tegra_clk_audio_2x = {
2124 .name = "audio_2x",
2125 .flags = PERIPH_NO_RESET,
2126 .max_rate = 48000000,
2127 .ops = &tegra_clk_double_ops,
2128 .reg = 0x34,
2129 .reg_shift = 8,
2130 .parent = &tegra_clk_audio,
2131 .u.periph = {
2132 .clk_num = 89,
2133 },
2134};
2135
2136struct clk_lookup tegra_audio_clk_lookups[] = {
2137 { .con_id = "audio", .clk = &tegra_clk_audio },
2138 { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
2139};
2140
2141/* This is called after peripheral clocks are initialized, as the
2142 * audio_sync clock depends on some of the peripheral clocks.
2143 */
2144
2145static void init_audio_sync_clock_mux(void)
2146{
2147 int i;
2148 struct clk_mux_sel *sel = mux_audio_sync_clk;
2149 const struct audio_sources *src = mux_audio_sync_clk_sources;
2150 struct clk_lookup *lookup;
2151
2152 for (i = 0; src->name; i++, sel++, src++) {
2153 sel->input = tegra_get_clock_by_name(src->name);
2154 if (!sel->input)
2155 pr_err("%s: could not find clk %s\n", __func__,
2156 src->name);
2157 sel->value = src->value;
2158 }
2159
2160 lookup = tegra_audio_clk_lookups;
2161 for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
2162 clk_init(lookup->clk);
2163 clkdev_add(lookup);
2164 }
2165}
2166
2167static struct clk_mux_sel mux_cclk[] = {
2168 { .input = &tegra_clk_m, .value = 0},
2169 { .input = &tegra_pll_c, .value = 1},
2170 { .input = &tegra_clk_32k, .value = 2},
2171 { .input = &tegra_pll_m, .value = 3},
2172 { .input = &tegra_pll_p, .value = 4},
2173 { .input = &tegra_pll_p_out4, .value = 5},
2174 { .input = &tegra_pll_p_out3, .value = 6},
2175 { .input = &tegra_clk_d, .value = 7},
2176 { .input = &tegra_pll_x, .value = 8},
2177 { 0, 0},
2178};
2179
2180static struct clk_mux_sel mux_sclk[] = {
2181 { .input = &tegra_clk_m, .value = 0},
2182 { .input = &tegra_pll_c_out1, .value = 1},
2183 { .input = &tegra_pll_p_out4, .value = 2},
2184 { .input = &tegra_pll_p_out3, .value = 3},
2185 { .input = &tegra_pll_p_out2, .value = 4},
2186 { .input = &tegra_clk_d, .value = 5},
2187 { .input = &tegra_clk_32k, .value = 6},
2188 { .input = &tegra_pll_m_out1, .value = 7},
2189 { 0, 0},
2190};
2191
2192static struct clk tegra_clk_cclk = {
2193 .name = "cclk",
2194 .inputs = mux_cclk,
2195 .reg = 0x20,
2196 .ops = &tegra_super_ops,
2197 .max_rate = 1000000000,
2198};
2199
2200static struct clk tegra_clk_sclk = {
2201 .name = "sclk",
2202 .inputs = mux_sclk,
2203 .reg = 0x28,
2204 .ops = &tegra_super_ops,
2205 .max_rate = 240000000,
2206 .min_rate = 40000000,
2207};
2208
2209static struct clk tegra_clk_virtual_cpu = {
2210 .name = "cpu",
2211 .parent = &tegra_clk_cclk,
2212 .ops = &tegra_cpu_ops,
2213 .max_rate = 1000000000,
2214 .u.cpu = {
2215 .main = &tegra_pll_x,
2216 .backup = &tegra_pll_p,
2217 },
2218};
2219
2220static struct clk tegra_clk_cop = {
2221 .name = "cop",
2222 .parent = &tegra_clk_sclk,
2223 .ops = &tegra_cop_ops,
2224 .max_rate = 240000000,
2225};
2226
2227static struct clk tegra_clk_hclk = {
2228 .name = "hclk",
2229 .flags = DIV_BUS,
2230 .parent = &tegra_clk_sclk,
2231 .reg = 0x30,
2232 .reg_shift = 4,
2233 .ops = &tegra_bus_ops,
2234 .max_rate = 240000000,
2235 .min_rate = 36000000,
2236};
2237
2238static struct clk tegra_clk_pclk = {
2239 .name = "pclk",
2240 .flags = DIV_BUS,
2241 .parent = &tegra_clk_hclk,
2242 .reg = 0x30,
2243 .reg_shift = 0,
2244 .ops = &tegra_bus_ops,
2245 .max_rate = 120000000,
2246 .min_rate = 36000000,
2247};
2248
2249static struct clk tegra_clk_virtual_sclk = {
2250 .name = "virt_sclk",
2251 .parent = &tegra_clk_sclk,
2252 .ops = &tegra_virtual_sclk_ops,
2253 .u.system = {
2254 .pclk = &tegra_clk_pclk,
2255 },
2256};
2257
2258static struct clk tegra_clk_blink = {
2259 .name = "blink",
2260 .parent = &tegra_clk_32k,
2261 .reg = 0x40,
2262 .ops = &tegra_blink_clk_ops,
2263 .max_rate = 32768,
2264};
2265static struct clk_mux_sel mux_dev1_clk[] = {
2266 { .input = &tegra_clk_m, .value = 0 },
2267 { .input = &tegra_pll_a_out0, .value = 1 },
2268 { .input = &tegra_pll_m_out1, .value = 2 },
2269 { .input = &tegra_clk_audio, .value = 3 },
2270 { 0, 0 }
2271};
2272
2273static struct clk_mux_sel mux_dev2_clk[] = {
2274 { .input = &tegra_clk_m, .value = 0 },
2275 { .input = &tegra_clk_hclk, .value = 1 },
2276 { .input = &tegra_clk_pclk, .value = 2 },
2277 { .input = &tegra_pll_p_out4, .value = 3 },
2278 { 0, 0 }
2279};
2280
2281/* dap_mclk1, belongs to the cdev1 pingroup. */
2282static struct clk tegra_clk_cdev1 = {
2283 .name = "cdev1",
2284 .ops = &tegra_cdev_clk_ops,
2285 .inputs = mux_dev1_clk,
2286 .u.periph = {
2287 .clk_num = 94,
2288 },
2289 .flags = MUX,
2290};
2291
2292/* dap_mclk2, belongs to the cdev2 pingroup. */
2293static struct clk tegra_clk_cdev2 = {
2294 .name = "cdev2",
2295 .ops = &tegra_cdev_clk_ops,
2296 .inputs = mux_dev2_clk,
2297 .u.periph = {
2298 .clk_num = 93,
2299 },
2300 .flags = MUX,
2301};
2302
2303static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
2304 { .input = &tegra_pll_m, .value = 0},
2305 { .input = &tegra_pll_c, .value = 1},
2306 { .input = &tegra_pll_p, .value = 2},
2307 { .input = &tegra_pll_a_out0, .value = 3},
2308 { 0, 0},
2309};
2310
2311static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
2312 { .input = &tegra_pll_m, .value = 0},
2313 { .input = &tegra_pll_c, .value = 1},
2314 { .input = &tegra_pll_p, .value = 2},
2315 { .input = &tegra_clk_m, .value = 3},
2316 { 0, 0},
2317};
2318
2319static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
2320 { .input = &tegra_pll_p, .value = 0},
2321 { .input = &tegra_pll_c, .value = 1},
2322 { .input = &tegra_pll_m, .value = 2},
2323 { .input = &tegra_clk_m, .value = 3},
2324 { 0, 0},
2325};
2326
2327static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
2328 {.input = &tegra_pll_a_out0, .value = 0},
2329 {.input = &tegra_clk_audio_2x, .value = 1},
2330 {.input = &tegra_pll_p, .value = 2},
2331 {.input = &tegra_clk_m, .value = 3},
2332 { 0, 0},
2333};
2334
2335static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
2336 {.input = &tegra_pll_p, .value = 0},
2337 {.input = &tegra_pll_d_out0, .value = 1},
2338 {.input = &tegra_pll_c, .value = 2},
2339 {.input = &tegra_clk_m, .value = 3},
2340 { 0, 0},
2341};
2342
2343static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
2344 {.input = &tegra_pll_p, .value = 0},
2345 {.input = &tegra_pll_c, .value = 1},
2346 {.input = &tegra_clk_audio, .value = 2},
2347 {.input = &tegra_clk_m, .value = 3},
2348 {.input = &tegra_clk_32k, .value = 4},
2349 { 0, 0},
2350};
2351
2352static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
2353 {.input = &tegra_pll_p, .value = 0},
2354 {.input = &tegra_pll_c, .value = 1},
2355 {.input = &tegra_pll_m, .value = 2},
2356 { 0, 0},
2357};
2358
2359static struct clk_mux_sel mux_clk_m[] = {
2360 { .input = &tegra_clk_m, .value = 0},
2361 { 0, 0},
2362};
2363
2364static struct clk_mux_sel mux_pllp_out3[] = {
2365 { .input = &tegra_pll_p_out3, .value = 0},
2366 { 0, 0},
2367};
2368
2369static struct clk_mux_sel mux_plld_out0[] = {
2370 { .input = &tegra_pll_d_out0, .value = 0},
2371 { 0, 0},
2372};
2373
2374static struct clk_mux_sel mux_clk_32k[] = {
2375 { .input = &tegra_clk_32k, .value = 0},
2376 { 0, 0},
2377};
2378
2379static struct clk_mux_sel mux_pclk[] = {
2380 { .input = &tegra_clk_pclk, .value = 0},
2381 { 0, 0},
2382};
2383
2384static struct clk tegra_clk_emc = {
2385 .name = "emc",
2386 .ops = &tegra_emc_clk_ops,
2387 .reg = 0x19c,
2388 .max_rate = 800000000,
2389 .inputs = mux_pllm_pllc_pllp_clkm,
2390 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
2391 .u.periph = {
2392 .clk_num = 57,
2393 },
2394};
2395
2396#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _reg_shift, _max, _inputs, _flags) \
2397 { \
2398 .name = _name, \
2399 .lookup = { \
2400 .dev_id = _dev, \
2401 .con_id = _con, \
2402 }, \
2403 .ops = &tegra_periph_clk_ops, \
2404 .reg = _reg, \
2405 .reg_shift = _reg_shift, \
2406 .inputs = _inputs, \
2407 .flags = _flags, \
2408 .max_rate = _max, \
2409 .u.periph = { \
2410 .clk_num = _clk_num, \
2411 }, \
2412 }
2413
2414#define SHARED_CLK(_name, _dev, _con, _parent) \
2415 { \
2416 .name = _name, \
2417 .lookup = { \
2418 .dev_id = _dev, \
2419 .con_id = _con, \
2420 }, \
2421 .ops = &tegra_clk_shared_bus_ops, \
2422 .parent = _parent, \
2423 }
2424
2425struct clk tegra_list_periph_clks[] = {
2426 PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 0x31E, 108000000, mux_pclk, 0),
2427 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 0x31E, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB),
2428 PERIPH_CLK("kbc", "tegra-kbc", NULL, 36, 0, 0x31E, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB),
2429 PERIPH_CLK("timer", "timer", NULL, 5, 0, 0x31E, 26000000, mux_clk_m, 0),
2430 PERIPH_CLK("i2s1", "tegra20-i2s.0", NULL, 11, 0x100, 0x31E, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2431 PERIPH_CLK("i2s2", "tegra20-i2s.1", NULL, 18, 0x104, 0x31E, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2432 PERIPH_CLK("fuse", "fuse-tegra", "fuse", 39, 0, 0x31E, 26000000, mux_clk_m, PERIPH_ON_APB),
2433 PERIPH_CLK("fuse_burn", "fuse-tegra", "fuse_burn", 39, 0, 0x31E, 26000000, mux_clk_m, PERIPH_ON_APB),
2434 PERIPH_CLK("kfuse", "kfuse-tegra", NULL, 40, 0, 0x31E, 26000000, mux_clk_m, 0),
2435 PERIPH_CLK("spdif_out", "tegra20-spdif", "spdif_out", 10, 0x108, 0x31E, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2436 PERIPH_CLK("spdif_in", "tegra20-spdif", "spdif_in", 10, 0x10c, 0x31E, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71 | PERIPH_ON_APB),
2437 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 0x71C, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71 | PERIPH_ON_APB),
2438 PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 0x31E, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2439 PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 0x31E, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2440 PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 0x31E, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2441 PERIPH_CLK("sbc1", "spi_tegra.0", "spi", 41, 0x134, 0x31E, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2442 PERIPH_CLK("sbc2", "spi_tegra.1", "spi", 44, 0x118, 0x31E, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2443 PERIPH_CLK("sbc3", "spi_tegra.2", "spi", 46, 0x11c, 0x31E, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2444 PERIPH_CLK("sbc4", "spi_tegra.3", "spi", 68, 0x1b4, 0x31E, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2445 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 0x31E, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2446 PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 0x31E, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2447 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 0x31E, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2448 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 0x31E, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2449 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 0x31E, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2450 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 0x31E, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2451 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 0x31E, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2452 PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 0x31E, 250000000, mux_clk_m, 0),
2453 PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 0x31E, 250000000, mux_clk_m, 0),
2454 PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 0x31E, 250000000, mux_clk_m, 0),
2455 PERIPH_CLK("vde", "tegra-avp", "vde", 61, 0x1c8, 0x31E, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
2456 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 0x31E, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
2457 /* FIXME: what is la? */
2458 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 0x31E, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2459 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 0x31E, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2460 PERIPH_CLK("nor", "tegra-nor", NULL, 42, 0x1d0, 0x31E, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2461 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 0x31E, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */
2462 PERIPH_CLK("i2c1", "tegra-i2c.0", "i2c-div", 12, 0x124, 0x31E, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2463 PERIPH_CLK("i2c2", "tegra-i2c.1", "i2c-div", 54, 0x198, 0x31E, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2464 PERIPH_CLK("i2c3", "tegra-i2c.2", "i2c-div", 67, 0x1b8, 0x31E, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2465 PERIPH_CLK("dvc", "tegra-i2c.3", "i2c-div", 47, 0x128, 0x31E, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2466 PERIPH_CLK("i2c1-fast", "tegra-i2c.0", "i2c-fast", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
2467 PERIPH_CLK("i2c2-fast", "tegra-i2c.1", "i2c-fast", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
2468 PERIPH_CLK("i2c3-fast", "tegra-i2c.2", "i2c-fast", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
2469 PERIPH_CLK("dvc-fast", "tegra-i2c.3", "i2c-fast", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
2470 PERIPH_CLK("uarta", "tegra_uart.0", NULL, 6, 0x178, 0x31E, 600000000, mux_pllp_pllc_pllm_clkm, MUX | PERIPH_ON_APB),
2471 PERIPH_CLK("uartb", "tegra_uart.1", NULL, 7, 0x17c, 0x31E, 600000000, mux_pllp_pllc_pllm_clkm, MUX | PERIPH_ON_APB),
2472 PERIPH_CLK("uartc", "tegra_uart.2", NULL, 55, 0x1a0, 0x31E, 600000000, mux_pllp_pllc_pllm_clkm, MUX | PERIPH_ON_APB),
2473 PERIPH_CLK("uartd", "tegra_uart.3", NULL, 65, 0x1c0, 0x31E, 600000000, mux_pllp_pllc_pllm_clkm, MUX | PERIPH_ON_APB),
2474 PERIPH_CLK("uarte", "tegra_uart.4", NULL, 66, 0x1c4, 0x31E, 600000000, mux_pllp_pllc_pllm_clkm, MUX | PERIPH_ON_APB),
2475 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 0x31E, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */
2476 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 0x31E, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2477 PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 0x31E, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2478 PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 0x31E, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
2479 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 0x31E, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2480 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 0x31E, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2481 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 0x31E, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2482 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 0x31E, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2483 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 0x31E, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2484 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2485 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 0x31E, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2486 PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */
2487 PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */
2488 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
2489 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
2490 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
2491 PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 0x31E, 500000000, mux_plld_out0, 0), /* scales with voltage */
2492 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 0x31E, 72000000, mux_pllp_out3, 0),
2493 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 0x31E, 150000000, mux_clk_m, 0), /* same frequency as VI */
2494 PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 0x31E, 150000000, mux_clk_m, PERIPH_NO_RESET),
2495 PERIPH_CLK("pex", NULL, "pex", 70, 0, 0x31E, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2496 PERIPH_CLK("afi", NULL, "afi", 72, 0, 0x31E, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2497 PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 0x31E, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2498 PERIPH_CLK("stat_mon", "tegra-stat-mon", NULL, 37, 0, 0x31E, 26000000, mux_clk_m, 0),
2499};
2500
2501struct clk tegra_list_shared_clks[] = {
2502 SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_virtual_sclk),
2503 SHARED_CLK("mon.sclk", "tegra-stat-mon", "sclk", &tegra_clk_virtual_sclk),
2504 SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_virtual_sclk),
2505 SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_virtual_sclk),
2506 SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_virtual_sclk),
2507 SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_virtual_sclk),
2508 SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_virtual_sclk),
2509 SHARED_CLK("sbc1.sclk", "spi_tegra.0", "sclk", &tegra_clk_virtual_sclk),
2510 SHARED_CLK("sbc2.sclk", "spi_tegra.1", "sclk", &tegra_clk_virtual_sclk),
2511 SHARED_CLK("sbc3.sclk", "spi_tegra.2", "sclk", &tegra_clk_virtual_sclk),
2512 SHARED_CLK("sbc4.sclk", "spi_tegra.3", "sclk", &tegra_clk_virtual_sclk),
2513 SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc),
2514 SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc),
2515 SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc),
2516 SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc),
2517 SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc),
2518 SHARED_CLK("3d.emc", "tegra_gr3d", "emc", &tegra_clk_emc),
2519 SHARED_CLK("2d.emc", "tegra_gr2d", "emc", &tegra_clk_emc),
2520 SHARED_CLK("mpe.emc", "tegra_mpe", "emc", &tegra_clk_emc),
2521 SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc),
2522 SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc),
2523 SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc),
2524 SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc),
2525 SHARED_CLK("camera.emc", "tegra_camera", "emc", &tegra_clk_emc),
2526};
2527
2528#define CLK_DUPLICATE(_name, _dev, _con) \
2529 { \
2530 .name = _name, \
2531 .lookup = { \
2532 .dev_id = _dev, \
2533 .con_id = _con, \
2534 }, \
2535 }
2536
2537/* Some clocks may be used by different drivers depending on the board
2538 * configuration. List those here to register them twice in the clock lookup
2539 * table under two names.
2540 */
2541struct clk_duplicate tegra_clk_duplicates[] = {
2542 CLK_DUPLICATE("uarta", "serial8250.0", "uarta"),
2543 CLK_DUPLICATE("uartb", "serial8250.0", "uartb"),
2544 CLK_DUPLICATE("uartc", "serial8250.0", "uartc"),
2545 CLK_DUPLICATE("uartd", "serial8250.0", "uartd"),
2546 CLK_DUPLICATE("uarte", "serial8250.0", "uarte"),
2547 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
2548 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
2549 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
2550 CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
2551 CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
2552 CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
2553 CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
2554 CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
2555 CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
2556 CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
2557 CLK_DUPLICATE("host1x", "tegra_host1x", "host1x"),
2558 CLK_DUPLICATE("2d", "tegra_gr2d", "gr2d"),
2559 CLK_DUPLICATE("3d", "tegra_gr3d", "gr3d"),
2560 CLK_DUPLICATE("epp", "tegra_gr2d", "epp"),
2561 CLK_DUPLICATE("mpe", "tegra_mpe", "mpe"),
2562 CLK_DUPLICATE("cop", "tegra-avp", "cop"),
2563 CLK_DUPLICATE("vde", "tegra-aes", "vde"),
2564 CLK_DUPLICATE("twd", "smp_twd", NULL),
2565 CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
2566};
2567
2568#define CLK(dev, con, ck) \
2569 { \
2570 .dev_id = dev, \
2571 .con_id = con, \
2572 .clk = ck, \
2573 }
2574
2575struct clk *tegra_ptr_clks[] = {
2576 &tegra_clk_32k,
2577 &tegra_pll_s,
2578 &tegra_clk_m,
2579 &tegra_pll_m,
2580 &tegra_pll_m_out1,
2581 &tegra_pll_c,
2582 &tegra_pll_c_out1,
2583 &tegra_pll_p,
2584 &tegra_pll_p_out1,
2585 &tegra_pll_p_out2,
2586 &tegra_pll_p_out3,
2587 &tegra_pll_p_out4,
2588 &tegra_pll_a,
2589 &tegra_pll_a_out0,
2590 &tegra_pll_d,
2591 &tegra_pll_d_out0,
2592 &tegra_pll_u,
2593 &tegra_pll_x,
2594 &tegra_pll_e,
2595 &tegra_clk_cclk,
2596 &tegra_clk_sclk,
2597 &tegra_clk_hclk,
2598 &tegra_clk_pclk,
2599 &tegra_clk_d,
2600 &tegra_clk_cdev1,
2601 &tegra_clk_cdev2,
2602 &tegra_clk_virtual_cpu,
2603 &tegra_clk_virtual_sclk,
2604 &tegra_clk_blink,
2605 &tegra_clk_cop,
2606 &tegra_clk_emc,
2607 &tegra2_clk_twd,
2608};
2609
2610/* For some clocks maximum rate limits depend on tegra2 SKU */
2611#define RATE_LIMIT(_name, _max_rate, _skus...) \
2612 { \
2613 .clk_name = _name, \
2614 .max_rate = _max_rate, \
2615 .sku_ids = {_skus} \
2616 }
2617
2618static struct tegra_sku_rate_limit sku_limits[] =
2619{
2620 RATE_LIMIT("cpu", 750000000, 0x07, 0x10),
2621 RATE_LIMIT("cclk", 750000000, 0x07, 0x10),
2622 RATE_LIMIT("pll_x", 750000000, 0x07, 0x10),
2623
2624 RATE_LIMIT("cpu", 1000000000, 0x04, 0x08, 0x0F),
2625 RATE_LIMIT("cclk", 1000000000, 0x04, 0x08, 0x0F),
2626 RATE_LIMIT("pll_x", 1000000000, 0x04, 0x08, 0x0F),
2627
2628 RATE_LIMIT("cpu", 1200000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2629 RATE_LIMIT("cclk", 1200000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2630 RATE_LIMIT("pll_x", 1200000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2631
2632 RATE_LIMIT("sclk", 240000000, 0x04, 0x7, 0x08, 0x0F, 0x10),
2633 RATE_LIMIT("hclk", 240000000, 0x04, 0x7, 0x08, 0x0F, 0x10),
2634 RATE_LIMIT("vde", 240000000, 0x04, 0x7, 0x08, 0x0F, 0x10),
2635 RATE_LIMIT("3d", 300000000, 0x04, 0x7, 0x08, 0x0F, 0x10),
2636
2637 RATE_LIMIT("host1x", 108000000, 0x0F),
2638
2639 RATE_LIMIT("sclk", 300000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2640 RATE_LIMIT("virt_sclk", 300000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2641 RATE_LIMIT("hclk", 300000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2642 RATE_LIMIT("pclk", 150000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2643 RATE_LIMIT("vde", 300000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2644 RATE_LIMIT("3d", 400000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2645
2646 RATE_LIMIT("uarta", 800000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2647 RATE_LIMIT("uartb", 800000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2648 RATE_LIMIT("uartc", 800000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2649 RATE_LIMIT("uartd", 800000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2650 RATE_LIMIT("uarte", 800000000, 0x14, 0x17, 0x18, 0x1B, 0x1C),
2651};
2652
2653static void tegra2_init_sku_limits(void)
2654{
2655 int i, j;
2656 struct clk *c;
2657 int sku_id = tegra_sku_id();
2658
2659 for (i = 0; i < ARRAY_SIZE(sku_limits); i++) {
2660 struct tegra_sku_rate_limit *limit = &sku_limits[i];
2661
2662 for (j = 0; (j < MAX_SAME_LIMIT_SKU_IDS) &&
2663 (limit->sku_ids[j] != 0); j++) {
2664 if (limit->sku_ids[j] == sku_id) {
2665 c = tegra_get_clock_by_name(limit->clk_name);
2666 if (!c) {
2667 pr_err("%s: Unknown sku clock %s\n",
2668 __func__, limit->clk_name);
2669 continue;
2670 }
2671 c->max_rate = limit->max_rate;
2672 }
2673 }
2674 }
2675}
2676
2677static void tegra2_init_one_clock(struct clk *c)
2678{
2679 clk_init(c);
2680 INIT_LIST_HEAD(&c->shared_bus_list);
2681 if (!c->lookup.dev_id && !c->lookup.con_id)
2682 c->lookup.con_id = c->name;
2683 c->lookup.clk = c;
2684 clkdev_add(&c->lookup);
2685}
2686
2687#ifdef CONFIG_CPU_FREQ
2688
2689/*
2690 * Frequency table index must be sequential starting at 0 and frequencies
2691 * must be ascending.
2692 */
2693
2694static struct cpufreq_frequency_table freq_table_750MHz[] = {
2695 { 0, 216000 },
2696 { 1, 312000 },
2697 { 2, 456000 },
2698 { 3, 608000 },
2699 { 4, 750000 },
2700 { 5, CPUFREQ_TABLE_END },
2701};
2702
2703static struct cpufreq_frequency_table freq_table_1p0GHz[] = {
2704 { 0, 216000 },
2705 { 1, 312000 },
2706 { 2, 456000 },
2707 { 3, 608000 },
2708 { 4, 760000 },
2709 { 5, 816000 },
2710 { 6, 912000 },
2711 { 7, 1000000 },
2712 { 8, CPUFREQ_TABLE_END },
2713};
2714
2715static struct cpufreq_frequency_table freq_table_1p2GHz[] = {
2716 { 0, 216000 },
2717 { 1, 312000 },
2718 { 2, 456000 },
2719 { 3, 608000 },
2720 { 4, 760000 },
2721 { 5, 816000 },
2722 { 6, 912000 },
2723 { 7, 1000000 },
2724 { 8, 1200000 },
2725 { 9, CPUFREQ_TABLE_END },
2726};
2727
2728static struct tegra_cpufreq_table_data cpufreq_tables[] = {
2729 { freq_table_750MHz, 1, 4 },
2730 { freq_table_1p0GHz, 2, 6 },
2731 { freq_table_1p2GHz, 2, 7 },
2732};
2733
2734struct tegra_cpufreq_table_data *tegra_cpufreq_table_get(void)
2735{
2736 int i, ret;
2737 struct clk *cpu_clk = tegra_get_clock_by_name("cpu");
2738
2739 for (i = 0; i < ARRAY_SIZE(cpufreq_tables); i++) {
2740 struct cpufreq_policy policy;
2741 ret = cpufreq_frequency_table_cpuinfo(
2742 &policy, cpufreq_tables[i].freq_table);
2743 BUG_ON(ret);
2744 if ((policy.max * 1000) == cpu_clk->max_rate)
2745 return &cpufreq_tables[i];
2746 }
2747 pr_err("%s: No cpufreq table matching cpu range", __func__);
2748 BUG();
2749 return &cpufreq_tables[0];
2750}
2751
2752unsigned long tegra_emc_to_cpu_ratio(unsigned long cpu_rate)
2753{
2754 /* Vote on memory bus frequency based on cpu frequency */
2755 if (cpu_rate > 1000000000)
2756 return 760000000;
2757 else if (cpu_rate >= 816000)
2758 return 600000000; /* cpu 816 MHz, emc max */
2759 else if (cpu_rate >= 608000)
2760 return 300000000; /* cpu 608 MHz, emc 150Mhz */
2761 else if (cpu_rate >= 456000)
2762 return 150000000; /* cpu 456 MHz, emc 75Mhz */
2763 else if (cpu_rate >= 312000)
2764 return 100000000; /* cpu 312 MHz, emc 50Mhz */
2765 else
2766 return 50000000; /* emc 25Mhz */
2767}
2768#endif
2769
2770#ifdef CONFIG_PM_SLEEP
2771static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
2772 PERIPH_CLK_SOURCE_NUM + 22];
2773
2774static int tegra_clk_suspend(void)
2775{
2776 unsigned long off, i;
2777 u32 *ctx = clk_rst_suspend;
2778
2779 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
2780 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
2781 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2782 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
2783 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
2784 *ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE);
2785 *ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
2786 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
2787 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
2788 *ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE);
2789 *ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
2790
2791 *ctx++ = clk_readl(tegra_pll_m_out1.reg);
2792 *ctx++ = clk_readl(tegra_pll_a_out0.reg);
2793 *ctx++ = clk_readl(tegra_pll_c_out1.reg);
2794
2795 *ctx++ = clk_readl(tegra_clk_cclk.reg);
2796 *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2797
2798 *ctx++ = clk_readl(tegra_clk_sclk.reg);
2799 *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2800 *ctx++ = clk_readl(tegra_clk_pclk.reg);
2801
2802 *ctx++ = clk_readl(tegra_clk_audio.reg);
2803
2804 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
2805 off += 4) {
2806 if (off == PERIPH_CLK_SOURCE_EMC)
2807 continue;
2808 *ctx++ = clk_readl(off);
2809 }
2810
2811 off = RST_DEVICES;
2812 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
2813 *ctx++ = clk_readl(off);
2814
2815 off = CLK_OUT_ENB;
2816 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
2817 *ctx++ = clk_readl(off);
2818
2819 *ctx++ = clk_readl(MISC_CLK_ENB);
2820 *ctx++ = clk_readl(CLK_MASK_ARM);
2821
2822 BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend));
2823
2824 return 0;
2825}
2826
2827static void tegra_clk_resume(void)
2828{
2829 unsigned long off, i;
2830 const u32 *ctx = clk_rst_suspend;
2831 u32 val;
2832
2833 val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
2834 val |= *ctx++;
2835 clk_writel(val, OSC_CTRL);
2836
2837 clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
2838 clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2839 clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
2840 clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
2841 clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE);
2842 clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
2843 clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE);
2844 clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
2845 clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE);
2846 clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
2847 udelay(1000);
2848
2849 clk_writel(*ctx++, tegra_pll_m_out1.reg);
2850 clk_writel(*ctx++, tegra_pll_a_out0.reg);
2851 clk_writel(*ctx++, tegra_pll_c_out1.reg);
2852
2853 clk_writel(*ctx++, tegra_clk_cclk.reg);
2854 clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2855
2856 clk_writel(*ctx++, tegra_clk_sclk.reg);
2857 clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2858 clk_writel(*ctx++, tegra_clk_pclk.reg);
2859
2860 clk_writel(*ctx++, tegra_clk_audio.reg);
2861
2862 /* enable all clocks before configuring clock sources */
2863 clk_writel(0xbffffff9ul, CLK_OUT_ENB);
2864 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
2865 clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
2866 wmb();
2867
2868 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
2869 off += 4) {
2870 if (off == PERIPH_CLK_SOURCE_EMC)
2871 continue;
2872 clk_writel(*ctx++, off);
2873 }
2874 wmb();
2875
2876 off = RST_DEVICES;
2877 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
2878 clk_writel(*ctx++, off);
2879 wmb();
2880
2881 off = CLK_OUT_ENB;
2882 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
2883 clk_writel(*ctx++, off);
2884 wmb();
2885
2886 clk_writel(*ctx++, MISC_CLK_ENB);
2887 clk_writel(*ctx++, CLK_MASK_ARM);
2888}
2889
2890#else
2891#define tegra_clk_suspend NULL
2892#define tegra_clk_resume NULL
2893#endif
2894
2895static struct syscore_ops tegra_clk_syscore_ops = {
2896 .suspend = tegra_clk_suspend,
2897 .resume = tegra_clk_resume,
2898};
2899
2900void __init tegra_soc_init_clocks(void)
2901{
2902 int i;
2903 struct clk *c;
2904
2905 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
2906 tegra2_init_one_clock(tegra_ptr_clks[i]);
2907
2908 for (i = 0; i < ARRAY_SIZE(tegra_list_periph_clks); i++)
2909 tegra2_init_one_clock(&tegra_list_periph_clks[i]);
2910
2911 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
2912 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
2913 if (!c) {
2914 pr_err("%s: Unknown duplicate clock %s\n", __func__,
2915 tegra_clk_duplicates[i].name);
2916 continue;
2917 }
2918
2919 tegra_clk_duplicates[i].lookup.clk = c;
2920 clkdev_add(&tegra_clk_duplicates[i].lookup);
2921 }
2922
2923 init_audio_sync_clock_mux();
2924 tegra2_init_sku_limits();
2925
2926 for (i = 0; i < ARRAY_SIZE(tegra_list_shared_clks); i++)
2927 tegra2_init_one_clock(&tegra_list_shared_clks[i]);
2928
2929 register_syscore_ops(&tegra_clk_syscore_ops);
2930}
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.c b/arch/arm/mach-tegra/tegra2_dvfs.c
new file mode 100644
index 00000000000..a53033b0099
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_dvfs.c
@@ -0,0 +1,349 @@
1/*
2 * arch/arm/mach-tegra/tegra2_dvfs.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * Copyright (C) 2010-2011 NVIDIA Corporation
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/string.h>
25#include <linux/module.h>
26
27#include "clock.h"
28#include "dvfs.h"
29#include "fuse.h"
30
31#ifdef CONFIG_TEGRA_CORE_DVFS
32static bool tegra_dvfs_core_disabled;
33#else
34static bool tegra_dvfs_core_disabled = true;
35#endif
36#ifdef CONFIG_TEGRA_CPU_DVFS
37static bool tegra_dvfs_cpu_disabled;
38#else
39static bool tegra_dvfs_cpu_disabled = true;
40#endif
41
42static const int core_millivolts[MAX_DVFS_FREQS] =
43 {950, 1000, 1100, 1200, 1225, 1275, 1300};
44static const int cpu_millivolts[MAX_DVFS_FREQS] =
45 {750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125};
46
47static const int cpu_speedo_nominal_millivolts[] =
48/* spedo_id 0, 1, 2 */
49 { 1100, 1025, 1125 };
50
51static const int core_speedo_nominal_millivolts[] =
52/* spedo_id 0, 1, 2 */
53 { 1225, 1225, 1300 };
54
55#define KHZ 1000
56#define MHZ 1000000
57
58static struct dvfs_rail tegra2_dvfs_rail_vdd_cpu = {
59 .reg_id = "vdd_cpu",
60 .max_millivolts = 1125,
61 .min_millivolts = 750,
62 .nominal_millivolts = 1125,
63};
64
65static struct dvfs_rail tegra2_dvfs_rail_vdd_core = {
66 .reg_id = "vdd_core",
67 .max_millivolts = 1300,
68 .min_millivolts = 950,
69 .nominal_millivolts = 1225,
70 .step = 150, /* step vdd_core by 150 mV to allow vdd_aon to follow */
71};
72
73static struct dvfs_rail tegra2_dvfs_rail_vdd_aon = {
74 .reg_id = "vdd_aon",
75 .max_millivolts = 1300,
76 .min_millivolts = 950,
77 .nominal_millivolts = 1225,
78#ifndef CONFIG_TEGRA_CORE_DVFS
79 .disabled = true,
80#endif
81};
82
83/* vdd_core and vdd_aon must be 120 mV higher than vdd_cpu */
84static int tegra2_dvfs_rel_vdd_cpu_vdd_core(struct dvfs_rail *vdd_cpu,
85 struct dvfs_rail *vdd_core)
86{
87 if (vdd_cpu->new_millivolts > vdd_cpu->millivolts &&
88 vdd_core->new_millivolts < vdd_cpu->new_millivolts + 120)
89 return vdd_cpu->new_millivolts + 120;
90
91 if (vdd_core->new_millivolts < vdd_cpu->millivolts + 120)
92 return vdd_cpu->millivolts + 120;
93
94 return vdd_core->new_millivolts;
95}
96
97/* vdd_aon must be within 170 mV of vdd_core */
98static int tegra2_dvfs_rel_vdd_core_vdd_aon(struct dvfs_rail *vdd_core,
99 struct dvfs_rail *vdd_aon)
100{
101 BUG_ON(abs(vdd_aon->millivolts - vdd_core->millivolts) >
102 vdd_aon->step);
103 return vdd_core->millivolts;
104}
105
106static struct dvfs_relationship tegra2_dvfs_relationships[] = {
107 {
108 /* vdd_core must be 120 mV higher than vdd_cpu */
109 .from = &tegra2_dvfs_rail_vdd_cpu,
110 .to = &tegra2_dvfs_rail_vdd_core,
111 .solve = tegra2_dvfs_rel_vdd_cpu_vdd_core,
112 },
113 {
114 /* vdd_aon must be 120 mV higher than vdd_cpu */
115 .from = &tegra2_dvfs_rail_vdd_cpu,
116 .to = &tegra2_dvfs_rail_vdd_aon,
117 .solve = tegra2_dvfs_rel_vdd_cpu_vdd_core,
118 },
119 {
120 /* vdd_aon must be within 170 mV of vdd_core */
121 .from = &tegra2_dvfs_rail_vdd_core,
122 .to = &tegra2_dvfs_rail_vdd_aon,
123 .solve = tegra2_dvfs_rel_vdd_core_vdd_aon,
124 },
125};
126
127static struct dvfs_rail *tegra2_dvfs_rails[] = {
128 &tegra2_dvfs_rail_vdd_cpu,
129 &tegra2_dvfs_rail_vdd_core,
130 &tegra2_dvfs_rail_vdd_aon,
131};
132
133#define CPU_DVFS(_clk_name, _speedo_id, _process_id, _mult, _freqs...) \
134 { \
135 .clk_name = _clk_name, \
136 .speedo_id = _speedo_id, \
137 .process_id = _process_id, \
138 .freqs = {_freqs}, \
139 .freqs_mult = _mult, \
140 .millivolts = cpu_millivolts, \
141 .auto_dvfs = true, \
142 .dvfs_rail = &tegra2_dvfs_rail_vdd_cpu, \
143 }
144
145#define CORE_DVFS(_clk_name, _process_id, _auto, _mult, _freqs...) \
146 { \
147 .clk_name = _clk_name, \
148 .speedo_id = -1, \
149 .process_id = _process_id, \
150 .freqs = {_freqs}, \
151 .freqs_mult = _mult, \
152 .millivolts = core_millivolts, \
153 .auto_dvfs = _auto, \
154 .dvfs_rail = &tegra2_dvfs_rail_vdd_core, \
155 }
156
157static struct dvfs dvfs_init[] = {
158 /* Cpu voltages (mV): 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125 */
159 CPU_DVFS("cpu", 0, 0, MHZ, 314, 314, 314, 456, 456, 456, 608, 608, 608, 760, 817, 817, 912, 1000),
160 CPU_DVFS("cpu", 0, 1, MHZ, 314, 314, 314, 456, 456, 456, 618, 618, 618, 770, 827, 827, 922, 1000),
161 CPU_DVFS("cpu", 0, 2, MHZ, 494, 494, 494, 675, 675, 817, 817, 922, 922, 1000),
162 CPU_DVFS("cpu", 0, 3, MHZ, 730, 760, 845, 845, 940, 1000),
163
164 CPU_DVFS("cpu", 1, 0, MHZ, 380, 380, 503, 503, 655, 655, 798, 798, 902, 902, 960, 1000),
165 CPU_DVFS("cpu", 1, 1, MHZ, 389, 389, 503, 503, 655, 760, 798, 798, 950, 950, 1000),
166 CPU_DVFS("cpu", 1, 2, MHZ, 598, 598, 750, 750, 893, 893, 1000),
167 CPU_DVFS("cpu", 1, 3, MHZ, 730, 760, 845, 845, 940, 1000),
168
169 CPU_DVFS("cpu", 2, 0, MHZ, 0, 0, 0, 0, 655, 655, 798, 798, 902, 902, 960, 1000, 1100, 1100, 1200),
170 CPU_DVFS("cpu", 2, 1, MHZ, 0, 0, 0, 0, 655, 760, 798, 798, 950, 950, 1015, 1015, 1100, 1200),
171 CPU_DVFS("cpu", 2, 2, MHZ, 0, 0, 0, 0, 769, 769, 902, 902, 1026, 1026, 1140, 1140, 1200),
172 CPU_DVFS("cpu", 2, 3, MHZ, 0, 0, 0, 0, 940, 1000, 1000, 1000, 1130, 1130, 1200),
173
174 /* Core voltages (mV): 950, 1000, 1100, 1200, 1225, 1275, 1300 */
175 CORE_DVFS("emc", -1, 1, KHZ, 57000, 333000, 380000, 666000, 666000, 666000, 760000),
176
177 CORE_DVFS("sdmmc1", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
178 CORE_DVFS("sdmmc2", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
179 CORE_DVFS("sdmmc3", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
180 CORE_DVFS("sdmmc4", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
181
182 CORE_DVFS("ndflash", -1, 1, KHZ, 130000, 150000, 158000, 164000, 164000, 164000, 164000),
183 CORE_DVFS("nor", -1, 1, KHZ, 0, 92000, 92000, 92000, 92000, 92000, 92000),
184 CORE_DVFS("ide", -1, 1, KHZ, 0, 0, 100000, 100000, 100000, 100000, 100000),
185 CORE_DVFS("mipi", -1, 1, KHZ, 0, 40000, 40000, 40000, 40000, 60000, 60000),
186 CORE_DVFS("usbd", -1, 1, KHZ, 0, 0, 480000, 480000, 480000, 480000, 480000),
187 CORE_DVFS("usb2", -1, 1, KHZ, 0, 0, 480000, 480000, 480000, 480000, 480000),
188 CORE_DVFS("usb3", -1, 1, KHZ, 0, 0, 480000, 480000, 480000, 480000, 480000),
189 CORE_DVFS("pcie", -1, 1, KHZ, 0, 0, 0, 250000, 250000, 250000, 250000),
190 CORE_DVFS("dsi", -1, 1, KHZ, 100000, 100000, 100000, 500000, 500000, 500000, 500000),
191 CORE_DVFS("tvo", -1, 1, KHZ, 0, 0, 0, 250000, 250000, 250000, 250000),
192
193 /*
194 * The clock rate for the display controllers that determines the
195 * necessary core voltage depends on a divider that is internal
196 * to the display block. Disable auto-dvfs on the display clocks,
197 * and let the display driver call tegra_dvfs_set_rate manually
198 */
199 CORE_DVFS("disp1", -1, 0, KHZ, 158000, 158000, 190000, 190000, 190000, 190000, 190000),
200 CORE_DVFS("disp2", -1, 0, KHZ, 158000, 158000, 190000, 190000, 190000, 190000, 190000),
201 CORE_DVFS("hdmi", -1, 0, KHZ, 0, 0, 0, 148500, 148500, 148500, 148500),
202
203 /*
204 * Clocks below depend on the core process id. Define per process_id
205 * tables for SCLK/VDE/3D clocks (maximum rate for these clocks is
206 * increased depending on tegra2 sku). Use the worst case value for
207 * other clocks for now.
208 */
209 CORE_DVFS("host1x", -1, 1, KHZ, 104500, 133000, 166000, 166000, 166000, 166000, 166000),
210 CORE_DVFS("epp", -1, 1, KHZ, 133000, 171000, 247000, 300000, 300000, 300000, 300000),
211 CORE_DVFS("2d", -1, 1, KHZ, 133000, 171000, 247000, 300000, 300000, 300000, 300000),
212
213 CORE_DVFS("3d", 0, 1, KHZ, 114000, 161500, 247000, 304000, 304000, 333500, 333500),
214 CORE_DVFS("3d", 1, 1, KHZ, 161500, 209000, 285000, 333500, 333500, 361000, 361000),
215 CORE_DVFS("3d", 2, 1, KHZ, 218500, 256500, 323000, 380000, 380000, 400000, 400000),
216 CORE_DVFS("3d", 3, 1, KHZ, 247000, 285000, 351500, 400000, 400000, 400000, 400000),
217
218 CORE_DVFS("mpe", 0, 1, KHZ, 104500, 152000, 228000, 300000, 300000, 300000, 300000),
219 CORE_DVFS("mpe", 1, 1, KHZ, 142500, 190000, 275500, 300000, 300000, 300000, 300000),
220 CORE_DVFS("mpe", 2, 1, KHZ, 190000, 237500, 300000, 300000, 300000, 300000, 300000),
221 CORE_DVFS("mpe", 3, 1, KHZ, 228000, 266000, 300000, 300000, 300000, 300000, 300000),
222
223 CORE_DVFS("vi", -1, 1, KHZ, 85000, 100000, 150000, 150000, 150000, 150000, 150000),
224
225 CORE_DVFS("sclk", 0, 1, KHZ, 95000, 133000, 190000, 222500, 240000, 247000, 262000),
226 CORE_DVFS("sclk", 1, 1, KHZ, 123500, 159500, 207000, 240000, 240000, 264000, 277500),
227 CORE_DVFS("sclk", 2, 1, KHZ, 152000, 180500, 229500, 260000, 260000, 285000, 300000),
228 CORE_DVFS("sclk", 3, 1, KHZ, 171000, 218500, 256500, 292500, 292500, 300000, 300000),
229
230 CORE_DVFS("vde", 0, 1, KHZ, 95000, 123500, 209000, 275500, 275500, 300000, 300000),
231 CORE_DVFS("vde", 1, 1, KHZ, 123500, 152000, 237500, 300000, 300000, 300000, 300000),
232 CORE_DVFS("vde", 2, 1, KHZ, 152000, 209000, 285000, 300000, 300000, 300000, 300000),
233 CORE_DVFS("vde", 3, 1, KHZ, 171000, 218500, 300000, 300000, 300000, 300000, 300000),
234 /* What is this? */
235 CORE_DVFS("NVRM_DEVID_CLK_SRC", -1, 1, MHZ, 480, 600, 800, 1067, 1067, 1067, 1067),
236};
237
238int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
239{
240 int ret;
241
242 ret = param_set_bool(arg, kp);
243 if (ret)
244 return ret;
245
246 if (tegra_dvfs_core_disabled)
247 tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core);
248 else
249 tegra_dvfs_rail_enable(&tegra2_dvfs_rail_vdd_core);
250
251 return 0;
252}
253
254int tegra_dvfs_disable_cpu_set(const char *arg, const struct kernel_param *kp)
255{
256 int ret;
257
258 ret = param_set_bool(arg, kp);
259 if (ret)
260 return ret;
261
262 if (tegra_dvfs_cpu_disabled)
263 tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu);
264 else
265 tegra_dvfs_rail_enable(&tegra2_dvfs_rail_vdd_cpu);
266
267 return 0;
268}
269
270int tegra_dvfs_disable_get(char *buffer, const struct kernel_param *kp)
271{
272 return param_get_bool(buffer, kp);
273}
274
275static struct kernel_param_ops tegra_dvfs_disable_core_ops = {
276 .set = tegra_dvfs_disable_core_set,
277 .get = tegra_dvfs_disable_get,
278};
279
280static struct kernel_param_ops tegra_dvfs_disable_cpu_ops = {
281 .set = tegra_dvfs_disable_cpu_set,
282 .get = tegra_dvfs_disable_get,
283};
284
285module_param_cb(disable_core, &tegra_dvfs_disable_core_ops,
286 &tegra_dvfs_core_disabled, 0644);
287module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops,
288 &tegra_dvfs_cpu_disabled, 0644);
289
290void __init tegra_soc_init_dvfs(void)
291{
292 int i;
293 struct clk *c;
294 struct dvfs *d;
295 int process_id;
296 int ret;
297 int cpu_process_id = tegra_cpu_process_id();
298 int core_process_id = tegra_core_process_id();
299 int speedo_id = tegra_soc_speedo_id();
300
301 BUG_ON(speedo_id >= ARRAY_SIZE(cpu_speedo_nominal_millivolts));
302 tegra2_dvfs_rail_vdd_cpu.nominal_millivolts =
303 cpu_speedo_nominal_millivolts[speedo_id];
304 BUG_ON(speedo_id >= ARRAY_SIZE(core_speedo_nominal_millivolts));
305 tegra2_dvfs_rail_vdd_core.nominal_millivolts =
306 core_speedo_nominal_millivolts[speedo_id];
307 tegra2_dvfs_rail_vdd_aon.nominal_millivolts =
308 core_speedo_nominal_millivolts[speedo_id];
309
310 tegra_dvfs_init_rails(tegra2_dvfs_rails, ARRAY_SIZE(tegra2_dvfs_rails));
311 tegra_dvfs_add_relationships(tegra2_dvfs_relationships,
312 ARRAY_SIZE(tegra2_dvfs_relationships));
313 /*
314 * VDD_CORE must always be at least 50 mV higher than VDD_CPU
315 * Fill out cpu_core_millivolts based on cpu_millivolts
316 */
317 for (i = 0; i < ARRAY_SIZE(dvfs_init); i++) {
318 d = &dvfs_init[i];
319
320 process_id = strcmp(d->clk_name, "cpu") ?
321 core_process_id : cpu_process_id;
322 if ((d->process_id != -1 && d->process_id != process_id) ||
323 (d->speedo_id != -1 && d->speedo_id != speedo_id)) {
324 pr_debug("tegra_dvfs: rejected %s speedo %d,"
325 " process %d\n", d->clk_name, d->speedo_id,
326 d->process_id);
327 continue;
328 }
329
330 c = tegra_get_clock_by_name(d->clk_name);
331
332 if (!c) {
333 pr_debug("tegra_dvfs: no clock found for %s\n",
334 d->clk_name);
335 continue;
336 }
337
338 ret = tegra_enable_dvfs_on_clk(c, d);
339 if (ret)
340 pr_err("tegra_dvfs: failed to enable dvfs on %s\n",
341 c->name);
342 }
343
344 if (tegra_dvfs_core_disabled)
345 tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core);
346
347 if (tegra_dvfs_cpu_disabled)
348 tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu);
349}
diff --git a/arch/arm/mach-tegra/tegra2_mc.c b/arch/arm/mach-tegra/tegra2_mc.c
new file mode 100644
index 00000000000..6df9c232c02
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_mc.c
@@ -0,0 +1,1017 @@
1/*
2 * arch/arm/mach-tegra/tegra2_mc.c
3 *
4 * Memory controller bandwidth profiling interface
5 *
6 * Copyright (c) 2009-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/slab.h>
24#include <linux/kobject.h>
25#include <linux/string.h>
26#include <linux/sysfs.h>
27#include <linux/sysdev.h>
28#include <linux/ktime.h>
29#include <linux/hrtimer.h>
30#include <linux/parser.h>
31#include <linux/io.h>
32#include <linux/module.h>
33#include <linux/init.h>
34#include <linux/clk.h>
35
36#include <mach/iomap.h>
37
38#include <asm/uaccess.h>
39
40#include "clock.h"
41#include "tegra2_mc.h"
42
43static void stat_start(void);
44static void stat_stop(void);
45static void stat_log(void);
46
47static struct hrtimer sample_timer;
48
49#define MC_COUNTER_INITIALIZER() \
50 { \
51 .enabled = false, \
52 .period = 10, \
53 .mode = FILTER_CLIENT, \
54 .address_low = 0, \
55 .address_length = 0xfffffffful, \
56 .sample_data = { \
57 .signature = 0xdeadbeef, \
58 } \
59 }
60
61static struct tegra_mc_counter mc_counter0 = MC_COUNTER_INITIALIZER();
62static struct tegra_mc_counter mc_counter1 = MC_COUNTER_INITIALIZER();
63static struct tegra_mc_counter emc_llp_counter = MC_COUNTER_INITIALIZER();
64
65/* /sys/devices/system/tegra_mc */
66static bool sample_enable = SAMPLE_ENABLE_DEFAULT;
67static u16 sample_quantum = SAMPLE_QUANTUM_DEFAULT;
68static u8 sample_log[SAMPLE_LOG_SIZE];
69
70static DEFINE_SPINLOCK(sample_enable_lock);
71static DEFINE_SPINLOCK(sample_log_lock);
72
73static u8 *sample_log_wptr = sample_log, *sample_log_rptr = sample_log;
74static int sample_log_size = SAMPLE_LOG_SIZE - 1;
75static struct clk *emc_clock = NULL;
76
77static bool sampling(void)
78{
79 bool ret;
80
81 spin_lock_bh(&sample_enable_lock);
82 ret = (sample_enable == true)? true : false;
83 spin_unlock_bh(&sample_enable_lock);
84
85 return ret;
86}
87
88static struct sysdev_class tegra_mc_sysclass = {
89 .name = "tegra_mc",
90};
91
92static ssize_t tegra_mc_enable_show(struct sysdev_class *class,
93 struct sysdev_class_attribute *attr, char *buf)
94{
95 return sprintf(buf, "%d\n", sample_enable);
96}
97
98static ssize_t tegra_mc_enable_store(struct sysdev_class *class,
99 struct sysdev_class_attribute *attr,
100 const char *buf, size_t count)
101{
102 int value, i;
103 struct tegra_mc_counter *counters[] = {
104 &mc_counter0,
105 &mc_counter1,
106 &emc_llp_counter
107 };
108
109 sscanf(buf, "%d", &value);
110
111 if (value == 0 || value == 1)
112 sample_enable = value;
113 else
114 return -EINVAL;
115
116 if (!sample_enable) {
117 stat_stop();
118 hrtimer_cancel(&sample_timer);
119 return count;
120 }
121
122 hrtimer_cancel(&sample_timer);
123
124 /* we need to initialize variables that change during sampling */
125 sample_log_wptr = sample_log_rptr = sample_log;
126 sample_log_size = SAMPLE_LOG_SIZE - 1;
127
128 for (i = 0; i < ARRAY_SIZE(counters); i++) {
129 struct tegra_mc_counter *c = counters[i];
130
131 if (!c->enabled)
132 continue;
133
134 c->current_client_index = 0;
135 }
136
137 stat_start();
138
139 hrtimer_start(&sample_timer,
140 ktime_add_ns(ktime_get(), (u64)sample_quantum * 1000000),
141 HRTIMER_MODE_ABS);
142
143 return count;
144}
145
146static ssize_t tegra_mc_log_show(struct sysdev_class *class,
147 struct sysdev_class_attribute *attr, char *buf)
148{
149 int index = 0, count = 0;
150 unsigned long flags;
151
152 spin_lock_irqsave(&sample_log_lock, flags);
153
154 while (sample_log_rptr != sample_log_wptr) {
155 if (sample_log_rptr < sample_log_wptr) {
156 count = sample_log_wptr - sample_log_rptr;
157 memcpy(buf + index, sample_log_rptr, count);
158 sample_log_rptr = sample_log_wptr;
159 sample_log_size += count;
160 } else {
161 count = SAMPLE_LOG_SIZE -
162 (sample_log_rptr - sample_log);
163 memcpy(buf + index, sample_log_rptr, count);
164 sample_log_rptr = sample_log;
165 sample_log_size += count;
166 }
167 index += count;
168 }
169
170 spin_unlock_irqrestore(&sample_log_lock, flags);
171
172 return index;
173}
174
175static ssize_t tegra_mc_log_store(struct sysdev_class *class,
176 struct sysdev_class_attribute *attr,
177 const char *buf, size_t count)
178{
179 return -EPERM;
180}
181
182static ssize_t tegra_mc_quantum_show(struct sysdev_class *class,
183 struct sysdev_class_attribute *attr, char *buf)
184{
185 return sprintf(buf, "%d\n", sample_quantum);
186}
187
188static ssize_t tegra_mc_quantum_store(struct sysdev_class *class,
189 struct sysdev_class_attribute *attr,
190 const char *buf, size_t count)
191{
192 int value;
193
194 if (sampling())
195 return -EINVAL;
196
197 sscanf(buf, "%d", &value);
198 sample_quantum = value;
199
200 return count;
201}
202
203#define TEGRA_MC_EXPAND(_attr,_mode) \
204 static SYSDEV_CLASS_ATTR( \
205 _attr, _mode, tegra_mc_##_attr##_show, tegra_mc_##_attr##_store);
206
207#define TEGRA_MC_ATTRIBUTES(_attr1,_mode1,_attr2,_mode2,_attr3,_mode3) \
208 TEGRA_MC_EXPAND(_attr1,_mode1) \
209 TEGRA_MC_EXPAND(_attr2,_mode2) \
210 TEGRA_MC_EXPAND(_attr3,_mode3)
211
212TEGRA_MC_ATTRIBUTES(enable,0666,log,0444,quantum,0666)
213
214#undef TEGRA_MC_EXPAND
215
216#define TEGRA_MC_EXPAND(_attr,_mode) \
217 &attr_##_attr,
218
219static struct sysdev_class_attribute *tegra_mc_attrs[] = {
220 TEGRA_MC_ATTRIBUTES(enable,0666,log,0444,quantum,0666)
221 NULL
222};
223
224/* /sys/devices/system/tegra_mc/client */
225static bool tegra_mc_client_0_enabled = CLIENT_ENABLED_DEFAULT;
226static u8 tegra_mc_client_0_on_schedule_buffer[CLIENT_ON_SCHEDULE_LENGTH];
227static struct kobject *tegra_mc_client_kobj, *tegra_mc_client_0_kobj;
228
229struct match_mode {
230 const char *name;
231 int mode;
232};
233
234static const struct match_mode mode_list[] = {
235 [0] = {
236 .name = "none",
237 .mode = FILTER_NONE,
238 },
239 [1] = {
240 .name = "address",
241 .mode = FILTER_ADDR,
242 },
243 [2] = {
244 .name = "client",
245 .mode = FILTER_CLIENT,
246 },
247};
248
249static int tegra_mc_parse_mode(const char* str) {
250 int i;
251
252 for (i = 0; i < ARRAY_SIZE(mode_list); i++) {
253 if (!strncmp(str, mode_list[i].name, strlen(mode_list[i].name)))
254 return mode_list[i].mode;
255 }
256 return -EINVAL;
257}
258
259static int tegra_mc_client_parse(const char *buf, size_t count,
260 tegra_mc_counter_t *counter0, tegra_mc_counter_t *counter1,
261 tegra_mc_counter_t *llp)
262{
263 char *options, *p, *ptr;
264 tegra_mc_counter_t *counter;
265 substring_t args[MAX_OPT_ARGS];
266 enum {
267 opt_period,
268 opt_mode,
269 opt_client,
270 opt_address_low,
271 opt_address_length,
272 opt_err,
273 };
274 const match_table_t tokens = {
275 {opt_period, "period=%s"},
276 {opt_mode, "mode=%s"},
277 {opt_client, "client=%s"},
278 {opt_address_low, "address_low=%s"},
279 {opt_address_length, "address_length=%s"},
280 {opt_err, NULL},
281 };
282 int ret = 0, i, token, index = 0;
283 bool aggregate = false;
284 int period, *client_ids, mode;
285 u64 address_low = 0;
286 u64 address_length = 1ull << 32;
287
288 client_ids = kmalloc(sizeof(int) * (MC_COUNTER_CLIENT_SIZE + 1),
289 GFP_KERNEL);
290 if (!client_ids)
291 return -ENOMEM;
292
293 memset(client_ids, -1, (sizeof(int) * (MC_COUNTER_CLIENT_SIZE + 1)));
294
295 options = kstrdup(buf, GFP_KERNEL);
296 if (!options) {
297 ret = -ENOMEM;
298 goto end;
299 }
300
301 while ((p = strsep(&options, " ")) != NULL) {
302 if (!*p)
303 continue;
304
305 pr_debug("\t %s\n", p);
306
307 token = match_token(p, tokens, args);
308 switch (token) {
309 case opt_period:
310 if (match_int(&args[0], &period) || period <= 0) {
311 ret = -EINVAL;
312 goto end;
313 }
314 break;
315
316 case opt_mode:
317 mode = tegra_mc_parse_mode(args[0].from);
318 if (mode < 0) {
319 ret = mode;
320 goto end;
321 }
322 break;
323
324 case opt_client:
325 ptr = get_options(args[0].from,
326 MC_COUNTER_CLIENT_SIZE + 1, client_ids);
327
328 if (client_ids[1] == MC_STAT_AGGREGATE) {
329 aggregate = true;
330 break;
331 }
332 break;
333
334 case opt_address_low:
335 address_low = simple_strtoull(args[0].from, NULL, 0);
336 break;
337
338 case opt_address_length:
339 address_length = simple_strtoull(args[0].from, NULL, 0);
340 break;
341
342 default:
343 ret = -EINVAL;
344 goto end;
345 }
346 }
347
348 address_low &= PAGE_MASK;
349 address_length += PAGE_SIZE - 1;
350 address_length &= ~((1ull << PAGE_SHIFT) - 1ull);
351
352 if (mode == FILTER_CLIENT) {
353 counter = counter0;
354 llp->enabled = false;
355 counter1->enabled = false;
356 } else if (mode == FILTER_ADDR || mode == FILTER_NONE) {
357 if (aggregate) {
358 counter = counter1;
359 llp->enabled = false;
360 counter0->enabled = false;
361 } else {
362 counter = counter0;
363 counter1->enabled = false;
364 llp->enabled = false;
365 }
366 } else {
367 ret = -EINVAL;
368 goto end;
369 }
370
371 counter->mode = mode;
372 counter->enabled = true;
373 counter->address_low = (u32)address_low;
374 counter->address_length = (u32)(address_length - 1);
375
376 for (i = 1; i < MC_COUNTER_CLIENT_SIZE; i++) {
377 if (client_ids[i] != -1)
378 counter->clients[index++] = client_ids[i];
379 }
380
381 counter->total_clients = index;
382
383 if (llp->enabled) {
384 llp->mode = counter->mode;
385 llp->period = counter->period;
386 llp->address_low = counter->address_low;
387 llp->address_length = counter->address_length;
388 }
389
390end:
391 if (options)
392 kfree(options);
393 if (client_ids)
394 kfree(client_ids);
395
396 return ret;
397}
398
399static ssize_t tegra_mc_client_0_show(struct kobject *kobj,
400 struct kobj_attribute *attr, char *buf)
401{
402 if (strcmp(attr->attr.name, "enable") == 0)
403 return sprintf(buf, "%d\n", tegra_mc_client_0_enabled);
404 else if (strcmp(attr->attr.name, "on_schedule") == 0)
405 return sprintf(buf, "%s", tegra_mc_client_0_on_schedule_buffer);
406 else
407 return -EINVAL;
408}
409
410static ssize_t tegra_mc_client_0_store(struct kobject *kobj,
411 struct kobj_attribute *attr, const char *buf, size_t count)
412{
413 int value;
414
415 if (sampling())
416 return -EINVAL;
417
418 if (strcmp(attr->attr.name, "enable") == 0) {
419 sscanf(buf, "%d\n", &value);
420 if (value == 0 || value == 1)
421 tegra_mc_client_0_enabled = value;
422 else
423 return -EINVAL;
424
425 return count;
426 } else if (strcmp(attr->attr.name, "on_schedule") == 0) {
427 if (tegra_mc_client_parse(buf, count,
428 &mc_counter0, &mc_counter1,
429 &emc_llp_counter) == 0) {
430
431 strncpy(tegra_mc_client_0_on_schedule_buffer,
432 buf, count);
433
434 return count;
435 } else
436 return -EINVAL;
437 } else
438 return -EINVAL;
439}
440
441static struct kobj_attribute tegra_mc_client_0_enable =
442 __ATTR(enable, 0660, tegra_mc_client_0_show, tegra_mc_client_0_store);
443
444static struct kobj_attribute tegra_mc_client_0_on_schedule =
445 __ATTR(on_schedule, 0660, tegra_mc_client_0_show, tegra_mc_client_0_store);
446
447static struct attribute *tegra_mc_client_0_attrs[] = {
448 &tegra_mc_client_0_enable.attr,
449 &tegra_mc_client_0_on_schedule.attr,
450 NULL,
451};
452
453static struct attribute_group tegra_mc_client_0_attr_group = {
454 .attrs = tegra_mc_client_0_attrs
455};
456
457/* /sys/devices/system/tegra_mc/dram */
458#define dram_counters(_x) \
459 _x(activate_cnt, ACTIVATE_CNT) \
460 _x(read_cnt, READ_CNT) \
461 _x(write_cnt, WRITE_CNT) \
462 _x(ref_cnt, REF_CNT) \
463 _x(cumm_banks_active_cke_eq1, CUMM_BANKS_ACTIVE_CKE_EQ1) \
464 _x(cumm_banks_active_cke_eq0, CUMM_BANKS_ACTIVE_CKE_EQ0) \
465 _x(cke_eq1_clks, CKE_EQ1_CLKS) \
466 _x(extclks_cke_eq1, EXTCLKS_CKE_EQ1) \
467 _x(extclks_cke_eq0, EXTCLKS_CKE_EQ0) \
468 _x(no_banks_active_cke_eq1, NO_BANKS_ACTIVE_CKE_EQ1) \
469 _x(no_banks_active_cke_eq0, NO_BANKS_ACTIVE_CKE_EQ0)
470
471#define DEFINE_COUNTER(_name, _val) { .enabled = false, .device_mask = 0, },
472
473static tegra_emc_dram_counter_t dram_counters[] = {
474 dram_counters(DEFINE_COUNTER)
475};
476
477#define DEFINE_SYSFS(_name, _val) \
478 \
479static struct kobject *tegra_mc_dram_##_name##_kobj; \
480 \
481static ssize_t tegra_mc_dram_##_name##_show(struct kobject *kobj, \
482 struct kobj_attribute *attr, char *buf) \
483{ \
484 return tegra_mc_dram_show(kobj, attr, buf, \
485 _val - EMC_DRAM_STAT_BEGIN); \
486} \
487 \
488static ssize_t tegra_mc_dram_##_name##_store(struct kobject *kobj, \
489 struct kobj_attribute *attr, const char *buf, size_t count) \
490{ \
491 if (sampling()) \
492 return 0; \
493 \
494 return tegra_mc_dram_store(kobj, attr, buf, count, \
495 _val - EMC_DRAM_STAT_BEGIN); \
496} \
497 \
498 \
499static struct kobj_attribute tegra_mc_dram_##_name##_enable = \
500 __ATTR(enable, 0660, tegra_mc_dram_##_name##_show, \
501 tegra_mc_dram_##_name##_store); \
502 \
503static struct kobj_attribute tegra_mc_dram_##_name##_device_mask = \
504 __ATTR(device_mask, 0660, tegra_mc_dram_##_name##_show, \
505 tegra_mc_dram_##_name##_store); \
506 \
507static struct attribute *tegra_mc_dram_##_name##_attrs[] = { \
508 &tegra_mc_dram_##_name##_enable.attr, \
509 &tegra_mc_dram_##_name##_device_mask.attr, \
510 NULL, \
511}; \
512 \
513static struct attribute_group tegra_mc_dram_##_name##_attr_group = { \
514 .attrs = tegra_mc_dram_##_name##_attrs, \
515};
516
517static struct kobject *tegra_mc_dram_kobj;
518
519static ssize_t tegra_mc_dram_show(struct kobject *kobj,
520 struct kobj_attribute *attr, char *buf, int index)
521{
522 if (index >= EMC_DRAM_STAT_END - EMC_DRAM_STAT_BEGIN)
523 return -EINVAL;
524
525 if (strcmp(attr->attr.name, "enable") == 0)
526 return sprintf(buf, "%d\n", dram_counters[index].enabled);
527 else if (strcmp(attr->attr.name, "device_mask") == 0)
528 return sprintf(buf, "%d\n", dram_counters[index].device_mask);
529 else
530 return -EINVAL;
531}
532static ssize_t tegra_mc_dram_store(struct kobject *kobj,
533 struct kobj_attribute *attr, const char *buf, size_t count, int index)
534{
535 int value;
536
537 if (index >= EMC_DRAM_STAT_END - EMC_DRAM_STAT_BEGIN)
538 return -EINVAL;
539
540 if (strcmp(attr->attr.name, "enable") == 0) {
541 sscanf(buf, "%d\n", &value);
542 if (value == 0 || value == 1)
543 dram_counters[index].enabled = value;
544 else
545 return -EINVAL;
546
547 return count;
548 } else if (strcmp(attr->attr.name, "device_mask") == 0) {
549 sscanf(buf, "%d\n", &value);
550 dram_counters[index].device_mask = (u8)value;
551
552 return count;
553 } else
554 return -EINVAL;
555}
556
557dram_counters(DEFINE_SYSFS)
558
559/* Tegra Statistics */
560typedef struct {
561 void __iomem *mmio;
562} tegra_device_t;
563
564static tegra_device_t mc = {
565 .mmio = IO_ADDRESS(TEGRA_MC_BASE),
566};
567
568static tegra_device_t emc = {
569 .mmio = IO_ADDRESS(TEGRA_EMC_BASE),
570};
571
572void mc_stat_start(tegra_mc_counter_t *counter0, tegra_mc_counter_t *counter1)
573{
574 struct tegra_mc_counter *c;
575 u32 filter_client = ARMC_STAT_CONTROL_FILTER_CLIENT_DISABLE;
576 u32 filter_addr = ARMC_STAT_CONTROL_FILTER_ADDR_DISABLE;
577
578 if (!tegra_mc_client_0_enabled)
579 return;
580
581 c = (counter0->enabled) ? counter0 : counter1;
582
583 /* disable statistics */
584 writel((MC_STAT_CONTROL_0_EMC_GATHER_DISABLE << MC_STAT_CONTROL_0_EMC_GATHER_SHIFT),
585 mc.mmio + MC_STAT_CONTROL_0);
586
587 if (c->enabled && c->mode == FILTER_ADDR)
588 filter_addr = ARMC_STAT_CONTROL_FILTER_ADDR_ENABLE;
589 else if (c->enabled && c->mode == FILTER_CLIENT)
590 filter_client = ARMC_STAT_CONTROL_FILTER_CLIENT_ENABLE;
591
592 filter_addr <<= ARMC_STAT_CONTROL_FILTER_ADDR_SHIFT;
593 filter_client <<= ARMC_STAT_CONTROL_FILTER_CLIENT_SHIFT;
594
595 if (c->enabled) {
596 u32 reg = 0;
597 reg |= (ARMC_STAT_CONTROL_MODE_BANDWIDTH <<
598 ARMC_STAT_CONTROL_MODE_SHIFT);
599 reg |= (ARMC_STAT_CONTROL_EVENT_QUALIFIED <<
600 ARMC_STAT_CONTROL_EVENT_SHIFT);
601 reg |= (ARMC_STAT_CONTROL_FILTER_PRI_DISABLE <<
602 ARMC_STAT_CONTROL_FILTER_PRI_SHIFT);
603 reg |= (ARMC_STAT_CONTROL_FILTER_COALESCED_DISABLE <<
604 ARMC_STAT_CONTROL_FILTER_COALESCED_SHIFT);
605 reg |= filter_client;
606 reg |= filter_addr;
607 reg |= (c->clients[c->current_client_index] <<
608 ARMC_STAT_CONTROL_CLIENT_ID_SHIFT);
609
610 /* note these registers are shared */
611 writel(c->address_low,
612 mc.mmio + MC_STAT_EMC_ADDR_LOW_0);
613 writel((c->address_low + c->address_length),
614 mc.mmio + MC_STAT_EMC_ADDR_HIGH_0);
615 writel(0xFFFFFFFF, mc.mmio + MC_STAT_EMC_CLOCK_LIMIT_0);
616
617 writel(reg, mc.mmio + MC_STAT_EMC_CONTROL_0_0);
618 }
619
620 /* reset then enable statistics */
621 writel((MC_STAT_CONTROL_0_EMC_GATHER_CLEAR << MC_STAT_CONTROL_0_EMC_GATHER_SHIFT),
622 mc.mmio + MC_STAT_CONTROL_0);
623
624 writel((MC_STAT_CONTROL_0_EMC_GATHER_ENABLE << MC_STAT_CONTROL_0_EMC_GATHER_SHIFT),
625 mc.mmio + MC_STAT_CONTROL_0);
626}
627
628void mc_stat_stop(tegra_mc_counter_t *counter0,
629 tegra_mc_counter_t *counter1)
630{
631 u32 total_counts = readl(mc.mmio + MC_STAT_EMC_CLOCKS_0);
632
633 /* Disable statistics */
634 writel((MC_STAT_CONTROL_0_EMC_GATHER_DISABLE << MC_STAT_CONTROL_0_EMC_GATHER_SHIFT),
635 mc.mmio + MC_STAT_CONTROL_0);
636
637 if (counter0->enabled) {
638 counter0->sample_data.client_counts = readl(mc.mmio + MC_STAT_EMC_COUNT_0_0);
639 counter0->sample_data.total_counts = total_counts;
640 counter0->sample_data.emc_clock_rate = clk_get_rate(emc_clock);
641 }
642 else {
643 counter1->sample_data.client_counts = readl(mc.mmio + MC_STAT_EMC_COUNT_1_0);
644 counter1->sample_data.total_counts = total_counts;
645 counter1->sample_data.emc_clock_rate = clk_get_rate(emc_clock);
646 }
647}
648
649void emc_stat_start(tegra_mc_counter_t *llp_counter,
650 tegra_emc_dram_counter_t *dram_counter)
651{
652 u32 llmc_stat = 0;
653 u32 llmc_ctrl =
654 (AREMC_STAT_CONTROL_MODE_BANDWIDTH <<
655 AREMC_STAT_CONTROL_MODE_SHIFT) |
656 (AREMC_STAT_CONTROL_CLIENT_TYPE_MPCORER <<
657 AREMC_STAT_CONTROL_CLIENT_TYPE_SHIFT) |
658 (AREMC_STAT_CONTROL_EVENT_QUALIFIED <<
659 AREMC_STAT_CONTROL_EVENT_SHIFT);
660
661 /* disable statistics */
662 llmc_stat |= (EMC_STAT_CONTROL_0_LLMC_GATHER_DISABLE <<
663 EMC_STAT_CONTROL_0_LLMC_GATHER_SHIFT);
664 llmc_stat |= (EMC_STAT_CONTROL_0_DRAM_GATHER_DISABLE <<
665 EMC_STAT_CONTROL_0_DRAM_GATHER_SHIFT);
666 writel(llmc_stat, emc.mmio + EMC_STAT_CONTROL_0);
667
668 if (tegra_mc_client_0_enabled && llp_counter->enabled) {
669 if (llp_counter->mode == FILTER_ADDR) {
670 llmc_ctrl |=
671 (AREMC_STAT_CONTROL_FILTER_ADDR_ENABLE <<
672 AREMC_STAT_CONTROL_FILTER_ADDR_SHIFT);
673 llmc_ctrl |=
674 (AREMC_STAT_CONTROL_FILTER_CLIENT_DISABLE <<
675 AREMC_STAT_CONTROL_FILTER_CLIENT_SHIFT);
676 } else if (llp_counter->mode == FILTER_CLIENT) {
677 /* not allow aggregate client in client mode */
678 llmc_ctrl |=
679 (AREMC_STAT_CONTROL_FILTER_ADDR_DISABLE <<
680 AREMC_STAT_CONTROL_FILTER_ADDR_SHIFT);
681 llmc_ctrl |=
682 (AREMC_STAT_CONTROL_FILTER_CLIENT_DISABLE <<
683 AREMC_STAT_CONTROL_FILTER_CLIENT_SHIFT);
684 } else if (llp_counter->mode == FILTER_NONE) {
685 llmc_ctrl |=
686 (AREMC_STAT_CONTROL_FILTER_ADDR_DISABLE <<
687 AREMC_STAT_CONTROL_FILTER_ADDR_SHIFT);
688 llmc_ctrl |=
689 (AREMC_STAT_CONTROL_FILTER_CLIENT_DISABLE <<
690 AREMC_STAT_CONTROL_FILTER_CLIENT_SHIFT);
691 }
692
693 writel(llp_counter->address_low,
694 emc.mmio + EMC_STAT_LLMC_ADDR_LOW_0);
695 writel( (llp_counter->address_low + llp_counter->address_length),
696 emc.mmio + EMC_STAT_LLMC_ADDR_HIGH_0);
697 writel(0xFFFFFFFF, emc.mmio + EMC_STAT_LLMC_CLOCK_LIMIT_0);
698 writel(llmc_ctrl, emc.mmio + EMC_STAT_LLMC_CONTROL_0_0);
699 }
700
701 writel(0xFFFFFFFF, emc.mmio + EMC_STAT_DRAM_CLOCK_LIMIT_LO_0);
702 writel(0xFF, emc.mmio + EMC_STAT_DRAM_CLOCK_LIMIT_HI_0);
703
704 llmc_stat = 0;
705 /* Reset then enable statistics */
706 llmc_stat |= (EMC_STAT_CONTROL_0_LLMC_GATHER_CLEAR <<
707 EMC_STAT_CONTROL_0_LLMC_GATHER_SHIFT);
708 llmc_stat |= (EMC_STAT_CONTROL_0_DRAM_GATHER_CLEAR <<
709 EMC_STAT_CONTROL_0_DRAM_GATHER_SHIFT);
710 writel(llmc_stat, emc.mmio + EMC_STAT_CONTROL_0);
711
712 llmc_stat = 0;
713 llmc_stat |= (EMC_STAT_CONTROL_0_LLMC_GATHER_ENABLE <<
714 EMC_STAT_CONTROL_0_LLMC_GATHER_SHIFT);
715 llmc_stat |= (EMC_STAT_CONTROL_0_DRAM_GATHER_ENABLE <<
716 EMC_STAT_CONTROL_0_DRAM_GATHER_SHIFT);
717 writel(llmc_stat, emc.mmio + EMC_STAT_CONTROL_0);
718}
719
720void emc_stat_stop(tegra_mc_counter_t *llp_counter,
721 tegra_emc_dram_counter_t *dram_counter)
722{
723 u32 llmc_stat = 0;
724 int i;
725 int dev0_offsets_lo[] = {
726 EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO_0,
727 EMC_STAT_DRAM_DEV0_READ_CNT_LO_0,
728 EMC_STAT_DRAM_DEV0_WRITE_CNT_LO_0,
729 EMC_STAT_DRAM_DEV0_REF_CNT_LO_0,
730 EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ1_LO_0,
731 EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ0_LO_0,
732 EMC_STAT_DRAM_DEV0_CKE_EQ1_CLKS_LO_0,
733 EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_LO_0,
734 EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_LO_0,
735 EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ1_LO_0,
736 EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ0_LO_0,
737 };
738 int dev0_offsets_hi[] = {
739 EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI_0,
740 EMC_STAT_DRAM_DEV0_READ_CNT_HI_0,
741 EMC_STAT_DRAM_DEV0_WRITE_CNT_HI_0,
742 EMC_STAT_DRAM_DEV0_REF_CNT_HI_0,
743 EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ1_HI_0,
744 EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ0_HI_0,
745 EMC_STAT_DRAM_DEV0_CKE_EQ1_CLKS_HI_0,
746 EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_HI_0,
747 EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_HI_0,
748 EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ1_HI_0,
749 EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ0_HI_0,
750 };
751 int dev1_offsets_lo[] = {
752 EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO_0,
753 EMC_STAT_DRAM_DEV1_READ_CNT_LO_0,
754 EMC_STAT_DRAM_DEV1_WRITE_CNT_LO_0,
755 EMC_STAT_DRAM_DEV1_REF_CNT_LO_0,
756 EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ1_LO_0,
757 EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ0_LO_0,
758 EMC_STAT_DRAM_DEV1_CKE_EQ1_CLKS_LO_0,
759 EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_LO_0,
760 EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_LO_0,
761 EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ1_LO_0,
762 EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ0_LO_0,
763 };
764 int dev1_offsets_hi[] = {
765 EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI_0,
766 EMC_STAT_DRAM_DEV1_READ_CNT_HI_0,
767 EMC_STAT_DRAM_DEV1_WRITE_CNT_HI_0,
768 EMC_STAT_DRAM_DEV1_REF_CNT_HI_0,
769 EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ1_HI_0,
770 EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ0_HI_0,
771 EMC_STAT_DRAM_DEV1_CKE_EQ1_CLKS_HI_0,
772 EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_HI_0,
773 EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_HI_0,
774 EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ1_HI_0,
775 EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ0_HI_0,
776 };
777
778 /* Disable statistics */
779 llmc_stat |= (EMC_STAT_CONTROL_0_LLMC_GATHER_DISABLE <<
780 EMC_STAT_CONTROL_0_LLMC_GATHER_SHIFT);
781 llmc_stat |= (EMC_STAT_CONTROL_0_DRAM_GATHER_DISABLE <<
782 EMC_STAT_CONTROL_0_DRAM_GATHER_SHIFT);
783 writel(llmc_stat, emc.mmio + EMC_STAT_CONTROL_0);
784
785 if (tegra_mc_client_0_enabled == true && llp_counter->enabled) {
786 u32 total_counts = readl(mc.mmio + MC_STAT_EMC_CLOCKS_0);
787 llp_counter->sample_data.client_counts = readl(emc.mmio + EMC_STAT_LLMC_COUNT_0_0);
788 llp_counter->sample_data.total_counts = total_counts;
789 llp_counter->sample_data.emc_clock_rate = clk_get_rate(emc_clock);
790 }
791
792 for (i = 0; i < EMC_DRAM_STAT_END - EMC_DRAM_STAT_BEGIN; i++) {
793 if (dram_counter[i].enabled) {
794
795 dram_counter[i].sample_data.client_counts = 0;
796 dram_counter[i].sample_data.emc_clock_rate = clk_get_rate(emc_clock);
797
798 if (!(dram_counter[i].device_mask & 0x1)) {
799 if (readl(emc.mmio + dev0_offsets_hi[i]) != 0) {
800 dram_counter[i].sample_data.client_counts = 0xFFFFFFFF;
801 continue;
802 }
803 dram_counter[i].sample_data.client_counts +=
804 readl(emc.mmio + dev0_offsets_lo[i]);
805 }
806
807 if (!(dram_counter[i].device_mask & 0x2)) {
808 if (readl(emc.mmio + dev1_offsets_hi[i]) != 0) {
809 dram_counter[i].sample_data.client_counts = 0xFFFFFFFF;
810 continue;
811 }
812 dram_counter[i].sample_data.client_counts +=
813 readl(emc.mmio + dev1_offsets_lo[i]);
814 }
815 }
816 }
817}
818
819static void stat_start(void)
820{
821 mc_stat_start(&mc_counter0, &mc_counter1);
822 emc_stat_start(&emc_llp_counter, dram_counters);
823}
824
825static void stat_stop(void)
826{
827 mc_stat_stop(&mc_counter0, &mc_counter1);
828 emc_stat_stop(&emc_llp_counter, dram_counters);
829}
830
831#define statcpy(_buf, _bufstart, _buflen, _elem) \
832 do { \
833 size_t s = sizeof(_elem); \
834 memcpy(_buf, &_elem, s); \
835 _buf += s; \
836 if (_buf >= _bufstart + _buflen) \
837 _buf = _bufstart; \
838 } while (0);
839
840static void stat_log(void)
841{
842 int i;
843 unsigned long flags;
844
845 struct tegra_mc_counter *counters[] = {
846 &mc_counter0,
847 &mc_counter1,
848 &emc_llp_counter
849 };
850
851 spin_lock_irqsave(&sample_log_lock, flags);
852
853 if (tegra_mc_client_0_enabled) {
854 for (i = 0; i < ARRAY_SIZE(counters); i++) {
855 struct tegra_mc_counter *c = counters[i];
856
857 if (!c->enabled)
858 continue;
859
860 c->sample_data.client_number = c->clients[c->current_client_index];
861
862 c->current_client_index++;
863 if (c->current_client_index == c->total_clients)
864 c->current_client_index = 0;
865
866 statcpy(sample_log_wptr, sample_log,
867 SAMPLE_LOG_SIZE, c->sample_data);
868 }
869 }
870
871 for (i = 0; i < EMC_DRAM_STAT_END - EMC_DRAM_STAT_BEGIN; i++) {
872 if (dram_counters[i].enabled) {
873 statcpy(sample_log_wptr, sample_log,
874 SAMPLE_LOG_SIZE, dram_counters[i].sample_data);
875 }
876 }
877
878 spin_unlock_irqrestore(&sample_log_lock, flags);
879}
880
881static enum hrtimer_restart sample_timer_function(struct hrtimer *handle)
882{
883 stat_stop();
884 stat_log();
885
886 if (!sample_enable)
887 return HRTIMER_NORESTART;
888
889 stat_start();
890
891 hrtimer_add_expires_ns(&sample_timer, (u64)sample_quantum * 1000000);
892 return HRTIMER_RESTART;
893}
894
895/* module init */
896#define REGISTER_SYSFS(_name, _val) \
897 tegra_mc_dram_##_name##_kobj = \
898 kobject_create_and_add(#_name, tegra_mc_dram_kobj); \
899 sysfs_create_group(tegra_mc_dram_##_name##_kobj, \
900 &tegra_mc_dram_##_name##_attr_group);
901
902static int tegra_mc_init(void)
903{
904 int i;
905 int rc;
906
907 /* /sys/devices/system/tegra_mc */
908 rc = sysdev_class_register(&tegra_mc_sysclass);
909 if(rc)
910 goto out;
911
912 for (i = 0; i < ARRAY_SIZE(tegra_mc_attrs)-1; i++) {
913 rc = sysdev_class_create_file(&tegra_mc_sysclass,
914 tegra_mc_attrs[i]);
915 if(rc) {
916 printk("\n sysdev_class_create_file : failed \n");
917 goto out_unreg_class;
918 }
919 }
920
921 /* /sys/devices/system/tegra_mc/client */
922 tegra_mc_client_kobj = kobject_create_and_add("client",
923 &tegra_mc_sysclass.kset.kobj);
924 if(!tegra_mc_client_kobj)
925 goto out_remove_sysdev_files;
926
927 tegra_mc_client_0_kobj = kobject_create_and_add("0",
928 tegra_mc_client_kobj);
929 if(!tegra_mc_client_0_kobj)
930 goto out_put_kobject_client;
931
932 rc = sysfs_create_group(tegra_mc_client_0_kobj,
933 &tegra_mc_client_0_attr_group);
934 if(rc)
935 goto out_put_kobject_client_0;
936
937 /* /sys/devices/system/tegra_mc/dram */
938 tegra_mc_dram_kobj = kobject_create_and_add("dram",
939 &tegra_mc_sysclass.kset.kobj);
940 if(!tegra_mc_dram_kobj)
941 goto out_remove_group_client_0;
942
943 dram_counters(REGISTER_SYSFS)
944
945 /* hrtimer */
946 hrtimer_init(&sample_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
947 sample_timer.function = sample_timer_function;
948
949 for (i = 0; i < EMC_DRAM_STAT_END - EMC_DRAM_STAT_BEGIN; i++) {
950 dram_counters[i].sample_data.client_number = EMC_DRAM_STAT_BEGIN + i;
951 dram_counters[i].sample_data.signature = 0xdeadbeef;
952 }
953
954 emc_clock = clk_get_sys(NULL, "emc");
955 if (!emc_clock) {
956 pr_err("Could not get EMC clock\n");
957 goto out_remove_group_client_0;
958 }
959
960 return 0;
961
962out_remove_group_client_0:
963 sysfs_remove_group(tegra_mc_client_0_kobj, &tegra_mc_client_0_attr_group);
964
965out_put_kobject_client_0:
966 kobject_put(tegra_mc_client_0_kobj);
967
968out_put_kobject_client:
969 kobject_put(tegra_mc_client_kobj);
970
971out_remove_sysdev_files:
972 for (i = 0; i < ARRAY_SIZE(tegra_mc_attrs)-1; i++) {
973 sysdev_class_remove_file(&tegra_mc_sysclass, tegra_mc_attrs[i]);
974 }
975
976out_unreg_class:
977 sysdev_class_unregister(&tegra_mc_sysclass);
978
979out:
980 return rc;
981}
982
983/* module deinit */
984#define REMOVE_SYSFS(_name, _val) \
985 sysfs_remove_group(tegra_mc_dram_##_name##_kobj, \
986 &tegra_mc_dram_##_name##_attr_group); \
987 kobject_put(tegra_mc_dram_##_name##_kobj);
988
989static void tegra_mc_exit(void)
990{
991 int i;
992
993 stat_stop();
994
995 /* hrtimer */
996 hrtimer_cancel(&sample_timer);
997
998 /* /sys/devices/system/tegra_mc/client */
999 sysfs_remove_group(tegra_mc_client_0_kobj,
1000 &tegra_mc_client_0_attr_group);
1001 kobject_put(tegra_mc_client_0_kobj);
1002 kobject_put(tegra_mc_client_kobj);
1003
1004 /* /sys/devices/system/tegra_mc/dram */
1005 dram_counters(REMOVE_SYSFS)
1006 kobject_put(tegra_mc_dram_kobj);
1007
1008 /* /sys/devices/system/tegra_mc */
1009 for (i = 0; i < ARRAY_SIZE(tegra_mc_attrs)-1; i++) {
1010 sysdev_class_remove_file(&tegra_mc_sysclass, tegra_mc_attrs[i]);
1011 }
1012 sysdev_class_unregister(&tegra_mc_sysclass);
1013}
1014
1015module_init(tegra_mc_init);
1016module_exit(tegra_mc_exit);
1017MODULE_LICENSE("Dual BSD/GPL");
diff --git a/arch/arm/mach-tegra/tegra2_mc.h b/arch/arm/mach-tegra/tegra2_mc.h
new file mode 100644
index 00000000000..211213c5f58
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_mc.h
@@ -0,0 +1,250 @@
1/*
2 * arch/arm/mach-tegra/tegra2_mc.c
3 *
4 * Memory controller bandwidth profiling interface
5 *
6 * Copyright (c) 2009-2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef _INCLUDE_TEGRA2_MC_H_
24#define _INCLUDE_TEGRA2_MC_H_
25
26#define SAMPLE_ENABLE_DEFAULT 0
27#define SAMPLE_LOG_SIZE 1024 /* need to be DWORD aligned */
28#define SAMPLE_QUANTUM_DEFAULT 1 /* in milliseconds */
29#define CLIENT_ENABLED_DEFAULT false
30#define CLIENT_ON_SCHEDULE_LENGTH 256
31#define SHIFT_4K 12
32
33typedef enum {
34 FILTER_NONE,
35 FILTER_ADDR,
36 FILTER_CLIENT,
37} FILTER_MODE;
38
39#define MC_COUNTER_CLIENT_SIZE 256
40
41#define MC_STAT_CONTROL_0 0x90
42#define MC_STAT_CONTROL_0_EMC_GATHER_SHIFT 8
43#define MC_STAT_CONTROL_0_EMC_GATHER_CLEAR 1
44#define MC_STAT_CONTROL_0_EMC_GATHER_DISABLE 2
45#define MC_STAT_CONTROL_0_EMC_GATHER_ENABLE 3
46
47#define MC_STAT_EMC_ADDR_LOW_0 0x98
48#define MC_STAT_EMC_ADDR_HIGH_0 0x9c
49#define MC_STAT_EMC_CLOCK_LIMIT_0 0xa0
50#define MC_STAT_EMC_CLOCKS_0 0xa4
51#define MC_STAT_EMC_CONTROL_0_0 0xa8
52#define MC_STAT_EMC_COUNT_0_0 0xb8
53#define MC_STAT_EMC_COUNT_1_0 0xbc
54
55#define ARMC_STAT_CONTROL_FILTER_ADDR_SHIFT 27
56#define ARMC_STAT_CONTROL_FILTER_ADDR_DISABLE 0
57#define ARMC_STAT_CONTROL_FILTER_ADDR_ENABLE 1
58#define ARMC_STAT_CONTROL_FILTER_CLIENT_SHIFT 26
59#define ARMC_STAT_CONTROL_FILTER_CLIENT_DISABLE 0
60#define ARMC_STAT_CONTROL_FILTER_CLIENT_ENABLE 1
61#define ARMC_STAT_CONTROL_FILTER_PRI_SHIFT 28
62#define ARMC_STAT_CONTROL_FILTER_PRI_DISABLE 0
63#define ARMC_STAT_CONTROL_FILTER_COALESCED_SHIFT 30
64#define ARMC_STAT_CONTROL_FILTER_COALESCED_DISABLE 0
65#define ARMC_STAT_CONTROL_CLIENT_ID_SHIFT 8
66#define ARMC_STAT_CONTROL_MODE_SHIFT 0
67#define ARMC_STAT_CONTROL_MODE_BANDWIDTH 0
68#define ARMC_STAT_CONTROL_EVENT_SHIFT 16
69#define ARMC_STAT_CONTROL_EVENT_QUALIFIED 0
70
71#define EMC_STAT_CONTROL_0 0x160
72#define EMC_STAT_CONTROL_0_LLMC_GATHER_SHIFT 0
73#define EMC_STAT_CONTROL_0_LLMC_GATHER_CLEAR 1
74#define EMC_STAT_CONTROL_0_LLMC_GATHER_DISABLE 2
75#define EMC_STAT_CONTROL_0_LLMC_GATHER_ENABLE 3
76#define EMC_STAT_CONTROL_0_DRAM_GATHER_SHIFT 16
77#define EMC_STAT_CONTROL_0_DRAM_GATHER_CLEAR 1
78#define EMC_STAT_CONTROL_0_DRAM_GATHER_DISABLE 2
79#define EMC_STAT_CONTROL_0_DRAM_GATHER_ENABLE 3
80
81#define AREMC_STAT_CONTROL_MODE_SHIFT 0
82#define AREMC_STAT_CONTROL_MODE_BANDWIDTH 0
83#define AREMC_STAT_CONTROL_FILTER_ADDR_SHIFT 27
84#define AREMC_STAT_CONTROL_FILTER_ADDR_ENABLE 1
85#define AREMC_STAT_CONTROL_CLIENT_TYPE_SHIFT 8
86#define AREMC_STAT_CONTROL_CLIENT_TYPE_MPCORER 0
87#define AREMC_STAT_CONTROL_FILTER_CLIENT_SHIFT 26
88#define AREMC_STAT_CONTROL_FILTER_CLIENT_DISABLE 0
89#define AREMC_STAT_CONTROL_FILTER_ADDR_DISABLE 0
90#define AREMC_STAT_CONTROL_EVENT_SHIFT 16
91#define AREMC_STAT_CONTROL_EVENT_QUALIFIED 0
92
93#define EMC_STAT_LLMC_ADDR_LOW_0 0x168
94#define EMC_STAT_LLMC_ADDR_HIGH_0 0x16c
95#define EMC_STAT_LLMC_CLOCK_LIMIT_0 0x170
96#define EMC_STAT_LLMC_CONTROL_0_0 0x178
97#define EMC_STAT_LLMC_COUNT_0_0 0x188
98
99#define EMC_STAT_DRAM_CLOCK_LIMIT_LO_0 0x1a4
100#define EMC_STAT_DRAM_CLOCK_LIMIT_HI_0 0x1a8
101#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO_0 0x1b4
102#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI_0 0x1b8
103#define EMC_STAT_DRAM_DEV0_READ_CNT_LO_0 0x1bc
104#define EMC_STAT_DRAM_DEV0_READ_CNT_HI_0 0x1c0
105#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO_0 0x1c4
106#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI_0 0x1c8
107#define EMC_STAT_DRAM_DEV0_REF_CNT_LO_0 0x1cc
108#define EMC_STAT_DRAM_DEV0_REF_CNT_HI_0 0x1d0
109#define EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ1_LO_0 0x1d4
110#define EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ1_HI_0 0x1d8
111#define EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ0_LO_0 0x1dc
112#define EMC_STAT_DRAM_DEV0_CUMM_BANKS_ACTIVE_CKE_EQ0_HI_0 0x1e0
113#define EMC_STAT_DRAM_DEV0_CKE_EQ1_CLKS_LO_0 0x1e4
114#define EMC_STAT_DRAM_DEV0_CKE_EQ1_CLKS_HI_0 0x1e8
115#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_LO_0 0x1ec
116#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_HI_0 0x1f0
117#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_LO_0 0x1f4
118#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_HI_0 0x1f8
119#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO_0 0x1fc
120#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI_0 0x200
121#define EMC_STAT_DRAM_DEV1_READ_CNT_LO_0 0x204
122#define EMC_STAT_DRAM_DEV1_READ_CNT_HI_0 0x208
123#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO_0 0x20c
124#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI_0 0x210
125#define EMC_STAT_DRAM_DEV1_REF_CNT_LO_0 0x214
126#define EMC_STAT_DRAM_DEV1_REF_CNT_HI_0 0x218
127#define EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ1_LO_0 0x21c
128#define EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ1_HI_0 0x220
129#define EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ0_LO_0 0x224
130#define EMC_STAT_DRAM_DEV1_CUMM_BANKS_ACTIVE_CKE_EQ0_HI_0 0x228
131#define EMC_STAT_DRAM_DEV1_CKE_EQ1_CLKS_LO_0 0x22c
132#define EMC_STAT_DRAM_DEV1_CKE_EQ1_CLKS_HI_0 0x230
133#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_LO_0 0x234
134#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_HI_0 0x238
135#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_LO_0 0x23c
136#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_HI_0 0x240
137#define EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ1_LO_0 0x244
138#define EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ1_HI_0 0x248
139#define EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ0_LO_0 0x24c
140#define EMC_STAT_DRAM_DEV0_NO_BANKS_ACTIVE_CKE_EQ0_HI_0 0x250
141#define EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ1_LO_0 0x254
142#define EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ1_HI_0 0x258
143#define EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ0_LO_0 0x25c
144#define EMC_STAT_DRAM_DEV1_NO_BANKS_ACTIVE_CKE_EQ0_HI_0 0x260
145
146#pragma pack(push)
147#pragma pack(1)
148
149typedef struct {
150 u32 signature;
151 u32 client_number;
152 u32 client_counts;
153 u32 total_counts;
154 u32 emc_clock_rate;
155} sample_data_t;
156
157#pragma pack(pop)
158
159typedef struct tegra_mc_counter {
160 bool enabled;
161 u32 period;
162 FILTER_MODE mode;
163 u32 address_low;
164 u32 address_length;
165 u32 current_client_index;
166 u32 total_clients;
167 u8 clients[MC_COUNTER_CLIENT_SIZE];
168 sample_data_t sample_data;
169} tegra_mc_counter_t;
170
171typedef struct tegra_emc_dram_counter {
172 bool enabled;
173 u8 device_mask;
174
175 sample_data_t sample_data;
176} tegra_emc_dram_counter_t;
177
178/* client ids of mc/emc */
179typedef enum {
180 MC_STAT_BEGIN = 0,
181 CBR_DISPLAY0A = 0,
182 CBR_DISPLAY0AB,
183 CBR_DISPLAY0B,
184 CBR_DISPLAY0BB,
185 CBR_DISPLAY0C,
186 CBR_DISPLAY0CB,
187 CBR_DISPLAY1B,
188 CBR_DISPLAY1BB,
189 CBR_EPPUP,
190 CBR_G2PR,
191 CBR_G2SR,
192 CBR_MPEUNIFBR,
193 CBR_VIRUV,
194 CSR_AVPCARM7R,
195 CSR_DISPLAYHC,
196 CSR_DISPLAYHCB,
197 CSR_FDCDRD,
198 CSR_G2DR,
199 CSR_HOST1XDMAR,
200 CSR_HOST1XR,
201 CSR_IDXSRD,
202 CSR_MPCORER,
203 CSR_MPE_IPRED,
204 CSR_MPEAMEMRD,
205 CSR_MPECSRD,
206 CSR_PPCSAHBDMAR,
207 CSR_PPCSAHBSLVR,
208 CSR_TEXSRD,
209 CSR_VDEBSEVR,
210 CSR_VDEMBER,
211 CSR_VDEMCER,
212 CSR_VDETPER,
213 CBW_EPPU,
214 CBW_EPPV,
215 CBW_EPPY,
216 CBW_MPEUNIFBW,
217 CBW_VIWSB,
218 CBW_VIWU,
219 CBW_VIWV,
220 CBW_VIWY,
221 CCW_G2DW,
222 CSW_AVPCARM7W,
223 CSW_FDCDWR,
224 CSW_HOST1XW,
225 CSW_ISPW,
226 CSW_MPCOREW,
227 CSW_MPECSWR,
228 CSW_PPCSAHBDMAW,
229 CSW_PPCSAHBSLVW,
230 CSW_VDEBSEVW,
231 CSW_VDEMBEW,
232 CSW_VDETPMW,
233 MC_STAT_END,
234 EMC_DRAM_STAT_BEGIN = 128,
235 ACTIVATE_CNT = 128,
236 READ_CNT,
237 WRITE_CNT,
238 REF_CNT,
239 CUMM_BANKS_ACTIVE_CKE_EQ1,
240 CUMM_BANKS_ACTIVE_CKE_EQ0,
241 CKE_EQ1_CLKS,
242 EXTCLKS_CKE_EQ1,
243 EXTCLKS_CKE_EQ0,
244 NO_BANKS_ACTIVE_CKE_EQ1,
245 NO_BANKS_ACTIVE_CKE_EQ0,
246 EMC_DRAM_STAT_END,
247 MC_STAT_AGGREGATE = 255,
248} device_id;
249
250#endif
diff --git a/arch/arm/mach-tegra/tegra2_speedo.c b/arch/arm/mach-tegra/tegra2_speedo.c
new file mode 100644
index 00000000000..1e5fa26a5c4
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_speedo.c
@@ -0,0 +1,140 @@
1/*
2 * arch/arm/mach-tegra/tegra2_speedo.c
3 *
4 * Copyright (c) 2010, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/io.h>
23#include <linux/err.h>
24
25#include <mach/iomap.h>
26
27#include "fuse.h"
28
29#define CPU_SPEEDO_LSBIT 20
30#define CPU_SPEEDO_MSBIT 29
31#define CPU_SPEEDO_REDUND_LSBIT 30
32#define CPU_SPEEDO_REDUND_MSBIT 39
33#define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
34
35#define CORE_SPEEDO_LSBIT 40
36#define CORE_SPEEDO_MSBIT 47
37#define CORE_SPEEDO_REDUND_LSBIT 48
38#define CORE_SPEEDO_REDUND_MSBIT 55
39#define CORE_SPEEDO_REDUND_OFFS (CORE_SPEEDO_REDUND_MSBIT - CORE_SPEEDO_MSBIT)
40
41#define SPEEDO_MULT 4
42
43#define CHIP_ID 0x804
44#define CHIP_MINOR_SHIFT 16
45#define CHIP_MINOR_MASK (0xF << CHIP_MINOR_SHIFT)
46
47#define PROCESS_CORNERS_NUM 4
48
49#define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2)
50#define SPEEDO_ID_SELECT_1(sku) \
51 (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
52 ((sku) != 27) && ((sku) != 28))
53
54/* Maximum speedo levels for each CPU process corner */
55static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
56/* proc_id 0 1 2 3 */
57 {315, 366, 420, UINT_MAX}, /* speedo_id 0 */
58 {303, 368, 419, UINT_MAX}, /* speedo_id 1 */
59 {316, 331, 383, UINT_MAX}, /* speedo_id 2 */
60};
61
62/* Maximum speedo levels for each core process corner */
63static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = {
64/* proc_id 0 1 2 3 */
65 {165, 195, 224, UINT_MAX}, /* speedo_id 0 */
66 {165, 195, 224, UINT_MAX}, /* speedo_id 1 */
67 {165, 195, 224, UINT_MAX}, /* speedo_id 2 */
68};
69
70static int cpu_process_id;
71static int core_process_id;
72static int soc_speedo_id;
73
74void tegra_init_speedo_data(void)
75{
76 u32 reg, val;
77 int i, bit, rev;
78 int sku = tegra_sku_id();
79 void __iomem *apb_misc = IO_ADDRESS(TEGRA_APB_MISC_BASE);
80
81 reg = readl(apb_misc + CHIP_ID);
82 rev = (reg & CHIP_MINOR_MASK) >> CHIP_MINOR_SHIFT;
83 if (SPEEDO_ID_SELECT_0(rev))
84 soc_speedo_id = 0;
85 else if (SPEEDO_ID_SELECT_1(sku))
86 soc_speedo_id = 1;
87 else
88 soc_speedo_id = 2;
89 BUG_ON(soc_speedo_id >= ARRAY_SIZE(cpu_process_speedos));
90 BUG_ON(soc_speedo_id >= ARRAY_SIZE(core_process_speedos));
91
92 val = 0;
93 for (bit = CPU_SPEEDO_MSBIT; bit >= CPU_SPEEDO_LSBIT; bit--) {
94 reg = tegra_spare_fuse(bit) |
95 tegra_spare_fuse(bit + CPU_SPEEDO_REDUND_OFFS);
96 val = (val << 1) | (reg & 0x1);
97 }
98 val = val * SPEEDO_MULT;
99 pr_debug("%s CPU speedo level %u\n", __func__, val);
100
101 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
102 if (val <= cpu_process_speedos[soc_speedo_id][i])
103 break;
104 }
105 cpu_process_id = i;
106
107 val = 0;
108 for (bit = CORE_SPEEDO_MSBIT; bit >= CORE_SPEEDO_LSBIT; bit--) {
109 reg = tegra_spare_fuse(bit) |
110 tegra_spare_fuse(bit + CORE_SPEEDO_REDUND_OFFS);
111 val = (val << 1) | (reg & 0x1);
112 }
113 val = val * SPEEDO_MULT;
114 pr_debug("%s Core speedo level %u\n", __func__, val);
115
116 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
117 if (val <= core_process_speedos[soc_speedo_id][i])
118 break;
119 }
120 core_process_id = i;
121
122 pr_info("Tegra SKU: %d Rev: A%.2d CPU Process: %d Core Process: %d"
123 " Speedo ID: %d\n", sku, rev, cpu_process_id, core_process_id,
124 soc_speedo_id);
125}
126
127int tegra_cpu_process_id(void)
128{
129 return cpu_process_id;
130}
131
132int tegra_core_process_id(void)
133{
134 return core_process_id;
135}
136
137int tegra_soc_speedo_id(void)
138{
139 return soc_speedo_id;
140}
diff --git a/arch/arm/mach-tegra/tegra2_statmon.c b/arch/arm/mach-tegra/tegra2_statmon.c
new file mode 100644
index 00000000000..92f9b883f93
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_statmon.c
@@ -0,0 +1,440 @@
1/*
2 * arch/arm/mach-tegra/tegra2_statmon.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/clk.h>
25#include <linux/interrupt.h>
26#include <linux/delay.h>
27#include <linux/io.h>
28#include <linux/err.h>
29#include <linux/sysdev.h>
30#include <linux/bitops.h>
31
32#include <mach/iomap.h>
33#include <mach/irqs.h>
34#include <mach/io.h>
35#include <mach/clk.h>
36
37#include "clock.h"
38#include "tegra2_statmon.h"
39
40#define COP_MON_CTRL 0x120
41#define COP_MON_STATUS 0x124
42
43#define SAMPLE_PERIOD_SHIFT 20
44#define SAMPLE_PERIOD_MASK (0xFF << SAMPLE_PERIOD_SHIFT)
45#define INT_STATUS BIT(29) /* write 1 to clear */
46#define INT_ENABLE BIT(30)
47#define MON_ENABLE BIT(31)
48
49#define WINDOW_SIZE 128
50#define FREQ_MULT 1000
51#define UPPER_BAND 1000
52#define LOWER_BAND 1000
53#define BOOST_FRACTION_BITS 8
54
55struct sampler {
56 struct clk *clock;
57 unsigned long active_cycles[WINDOW_SIZE];
58 unsigned long total_active_cycles;
59 unsigned long avg_freq;
60 unsigned long *last_sample;
61 unsigned long idle_cycles;
62 unsigned long boost_freq;
63 unsigned long bumped_freq;
64 unsigned long *table;
65 int table_size;
66 u32 sample_count;
67 bool enable;
68 int sample_time;
69 int window_ms;
70 int min_samples;
71 unsigned long boost_step;
72 u8 boost_inc_coef;
73 u8 boost_dec_coef;
74};
75
76struct tegra2_stat_mon {
77 void __iomem *stat_mon_base;
78 void __iomem *vde_mon_base;
79 struct clk *stat_mon_clock;
80 struct mutex stat_mon_lock;
81 struct sampler avp_sampler;
82};
83
84static unsigned long sclk_table[] = {
85 300000,
86 240000,
87 200000,
88 150000,
89 120000,
90 100000,
91 80000,
92 75000,
93 60000,
94 50000,
95 48000,
96 40000
97};
98
99static struct tegra2_stat_mon *stat_mon;
100
101static inline u32 tegra2_stat_mon_read(u32 offset)
102{
103 return readl(stat_mon->stat_mon_base + offset);
104}
105
106static inline void tegra2_stat_mon_write(u32 value, u32 offset)
107{
108 writel(value, stat_mon->stat_mon_base + offset);
109}
110
111static inline u32 tegra2_vde_mon_read(u32 offset)
112{
113 return readl(stat_mon->vde_mon_base + offset);
114}
115
116static inline void tegra2_vde_mon_write(u32 value, u32 offset)
117{
118 writel(value, stat_mon->vde_mon_base + offset);
119}
120
121/* read the ticks in ISR and store */
122static irqreturn_t stat_mon_isr(int irq, void *data)
123{
124 u32 reg_val;
125
126 /* disable AVP monitor */
127 reg_val = tegra2_stat_mon_read(COP_MON_CTRL);
128 reg_val |= INT_STATUS;
129 tegra2_stat_mon_write(reg_val, COP_MON_CTRL);
130
131 stat_mon->avp_sampler.idle_cycles =
132 tegra2_stat_mon_read(COP_MON_STATUS);
133
134 return IRQ_WAKE_THREAD;
135}
136
137
138static void add_active_sample(struct sampler *s, unsigned long cycles)
139{
140 if (s->last_sample == &s->active_cycles[WINDOW_SIZE - 1])
141 s->last_sample = &s->active_cycles[0];
142 else
143 s->last_sample++;
144
145 s->total_active_cycles -= *s->last_sample;
146 *s->last_sample = cycles;
147 s->total_active_cycles += *s->last_sample;
148}
149
150static unsigned long round_rate(struct sampler *s, unsigned long rate)
151{
152 int i;
153 unsigned long *table = s->table;
154
155 if (rate >= table[0])
156 return table[0];
157
158 for (i = 1; i < s->table_size; i++) {
159 if (rate <= table[i])
160 continue;
161 else {
162 return table[i-1];
163 break;
164 }
165 }
166 if (rate <= table[s->table_size - 1])
167 return table[s->table_size - 1];
168 return rate;
169}
170
171static void set_target_freq(struct sampler *s)
172{
173 unsigned long clock_rate;
174 unsigned long target_freq;
175 unsigned long active_count;
176
177 clock_rate = clk_get_rate(s->clock) / FREQ_MULT;
178 active_count = (s->sample_time + 1) * clock_rate;
179 active_count = (active_count > s->idle_cycles) ?
180 (active_count - s->idle_cycles) : (0);
181
182 s->sample_count++;
183
184 add_active_sample(s, active_count);
185
186 s->avg_freq = s->total_active_cycles / s->window_ms;
187
188 if ((s->idle_cycles >= (1 + (active_count >> 3))) &&
189 (s->bumped_freq >= s->avg_freq)) {
190 s->boost_freq = (s->boost_freq *
191 ((0x1 << BOOST_FRACTION_BITS) - s->boost_dec_coef))
192 >> BOOST_FRACTION_BITS;
193 if (s->boost_freq < s->boost_step)
194 s->boost_freq = 0;
195 } else if (s->sample_count < s->min_samples) {
196 s->sample_count++;
197 } else {
198 s->boost_freq = ((s->boost_freq *
199 ((0x1 << BOOST_FRACTION_BITS) + s->boost_inc_coef))
200 >> BOOST_FRACTION_BITS) + s->boost_step;
201 if (s->boost_freq > s->clock->max_rate)
202 s->boost_freq = s->clock->max_rate;
203 }
204
205 if ((s->avg_freq + LOWER_BAND) < s->bumped_freq)
206 s->bumped_freq = s->avg_freq + LOWER_BAND;
207 else if (s->avg_freq > (s->bumped_freq + UPPER_BAND))
208 s->bumped_freq = s->avg_freq - UPPER_BAND;
209
210 s->bumped_freq += (s->bumped_freq >> 3);
211
212 target_freq = max(s->bumped_freq, s->clock->min_rate);
213 target_freq += s->boost_freq;
214
215 active_count = target_freq;
216 target_freq = round_rate(s, target_freq) * FREQ_MULT;
217 clk_set_rate(s->clock, target_freq);
218}
219
220/* - process ticks in thread context
221 */
222static irqreturn_t stat_mon_isr_thread_fn(int irq, void *data)
223{
224 u32 reg_val = 0;
225
226 mutex_lock(&stat_mon->stat_mon_lock);
227 set_target_freq(&stat_mon->avp_sampler);
228 mutex_unlock(&stat_mon->stat_mon_lock);
229
230 /* start AVP sampler */
231 reg_val = tegra2_stat_mon_read(COP_MON_CTRL);
232 reg_val |= MON_ENABLE;
233 tegra2_stat_mon_write(reg_val, COP_MON_CTRL);
234 return IRQ_HANDLED;
235}
236
237void tegra2_statmon_stop(void)
238{
239 u32 reg_val = 0;
240
241 /* disable AVP monitor */
242 reg_val |= INT_STATUS;
243 tegra2_stat_mon_write(reg_val, COP_MON_CTRL);
244
245 clk_disable(stat_mon->stat_mon_clock);
246 clk_disable(stat_mon->avp_sampler.clock);
247}
248
249int tegra2_statmon_start(void)
250{
251 u32 reg_val = 0;
252
253 clk_enable(stat_mon->avp_sampler.clock);
254 clk_enable(stat_mon->stat_mon_clock);
255
256 /* disable AVP monitor */
257 reg_val |= INT_STATUS;
258 tegra2_stat_mon_write(reg_val, COP_MON_CTRL);
259
260 /* start AVP sampler. also enable INT to CPU */
261 reg_val = 0;
262 reg_val |= MON_ENABLE;
263 reg_val |= INT_ENABLE;
264 reg_val |= ((stat_mon->avp_sampler.sample_time \
265 << SAMPLE_PERIOD_SHIFT) & SAMPLE_PERIOD_MASK);
266 tegra2_stat_mon_write(reg_val, COP_MON_CTRL);
267 return 0;
268}
269
270static ssize_t tegra2_statmon_enable_show(struct sysdev_class *class,
271 struct sysdev_class_attribute *attr, char *buf)
272{
273 return sprintf(buf, "%d\n", stat_mon->avp_sampler.enable);
274}
275
276static ssize_t tegra2_statmon_enable_store(struct sysdev_class *class,
277 struct sysdev_class_attribute *attr, const char *buf, size_t count)
278{
279 int value;
280
281 mutex_lock(&stat_mon->stat_mon_lock);
282 sscanf(buf, "%d", &value);
283
284 if (value == 0 || value == 1)
285 stat_mon->avp_sampler.enable = value;
286 else {
287 mutex_unlock(&stat_mon->stat_mon_lock);
288 return -EINVAL;
289 }
290 mutex_unlock(&stat_mon->stat_mon_lock);
291
292 if (stat_mon->avp_sampler.enable)
293 tegra2_statmon_start();
294 else
295 tegra2_statmon_stop();
296
297 return 0;
298}
299
300static ssize_t tegra2_statmon_sample_time_show(struct sysdev_class *class,
301 struct sysdev_class_attribute *attr, char *buf)
302{
303 return sprintf(buf, "%d\n", stat_mon->avp_sampler.sample_time);
304}
305
306static ssize_t tegra2_statmon_sample_time_store(struct sysdev_class *class,
307 struct sysdev_class_attribute *attr,
308 const char *buf, size_t count)
309{
310 int value;
311
312 mutex_lock(&stat_mon->stat_mon_lock);
313 sscanf(buf, "%d", &value);
314 stat_mon->avp_sampler.sample_time = value;
315 mutex_unlock(&stat_mon->stat_mon_lock);
316
317 return count;
318}
319
320static struct sysdev_class tegra2_statmon_sysclass = {
321 .name = "tegra2_statmon",
322};
323
324#define TEGRA2_STATMON_ATTRIBUTE_EXPAND(_attr, _mode) \
325 static SYSDEV_CLASS_ATTR(_attr, _mode, \
326 tegra2_statmon_##_attr##_show, tegra2_statmon_##_attr##_store)
327
328TEGRA2_STATMON_ATTRIBUTE_EXPAND(enable, 0666);
329TEGRA2_STATMON_ATTRIBUTE_EXPAND(sample_time, 0666);
330
331#define TEGRA2_STATMON_ATTRIBUTE(_name) (&attr_##_name)
332
333static struct sysdev_class_attribute *tegra2_statmon_attrs[] = {
334 TEGRA2_STATMON_ATTRIBUTE(enable),
335 TEGRA2_STATMON_ATTRIBUTE(sample_time),
336 NULL,
337};
338
339static int sampler_init(struct sampler *s)
340{
341 int i;
342 struct clk *clock;
343 unsigned long clock_rate;
344 unsigned long active_count;
345
346 s->enable = false;
347 s->sample_time = 9;
348
349 clock = tegra_get_clock_by_name("mon.sclk");
350 if (IS_ERR(clock)) {
351 pr_err("%s: Couldn't get mon.sckl\n", __func__);
352 return -1;
353 }
354
355 if (clk_set_rate(clock, clock->min_rate)) {
356 pr_err("%s: Failed to set rate\n", __func__);
357 return -1;
358 }
359 clock_rate = clk_get_rate(clock) / FREQ_MULT;
360 active_count = clock_rate * (s->sample_time + 1);
361
362 for (i = 0; i < WINDOW_SIZE; i++)
363 s->active_cycles[i] = active_count;
364
365 s->clock = clock;
366 s->last_sample = &s->active_cycles[0];
367 s->total_active_cycles = active_count << 7;
368 s->window_ms = (s->sample_time + 1) << 7;
369 s->avg_freq = s->total_active_cycles / s->window_ms;
370 s->bumped_freq = s->avg_freq;
371 s->boost_freq = 0;
372
373 return 0;
374}
375
376static int tegra2_stat_mon_init(void)
377{
378 int rc, i;
379 int ret_val = 0;
380
381 stat_mon = kzalloc(sizeof(struct tegra2_stat_mon), GFP_KERNEL);
382 if (stat_mon == NULL) {
383 pr_err("%s: unable to alloc data struct.\n", __func__);
384 return -ENOMEM;
385 }
386
387 stat_mon->stat_mon_base = IO_ADDRESS(TEGRA_STATMON_BASE);
388 stat_mon->vde_mon_base = IO_ADDRESS(TEGRA_VDE_BASE);
389
390 stat_mon->stat_mon_clock = tegra_get_clock_by_name("stat_mon");
391 if (stat_mon->stat_mon_clock == NULL) {
392 pr_err("Failed to get stat mon clock");
393 return -1;
394 }
395
396 if (sampler_init(&stat_mon->avp_sampler))
397 return -1;
398
399 stat_mon->avp_sampler.table = sclk_table;
400 stat_mon->avp_sampler.table_size = ARRAY_SIZE(sclk_table);
401 stat_mon->avp_sampler.boost_step = 1000;
402 stat_mon->avp_sampler.boost_inc_coef = 255;
403 stat_mon->avp_sampler.boost_dec_coef = 128;
404 stat_mon->avp_sampler.min_samples = 3;
405
406 mutex_init(&stat_mon->stat_mon_lock);
407
408 /* /sys/devices/system/tegra2_statmon */
409 rc = sysdev_class_register(&tegra2_statmon_sysclass);
410 if (rc) {
411 pr_err("%s : Couldn't create statmon sysfs entry\n", __func__);
412 return 0;
413 }
414
415 for (i = 0; i < ARRAY_SIZE(tegra2_statmon_attrs) - 1; i++) {
416 rc = sysdev_class_create_file(&tegra2_statmon_sysclass,
417 tegra2_statmon_attrs[i]);
418 if (rc) {
419 pr_err("%s: Failed to create sys class\n", __func__);
420 sysdev_class_unregister(&tegra2_statmon_sysclass);
421 kfree(stat_mon);
422 return 0;
423 }
424 }
425
426 ret_val = request_threaded_irq(INT_SYS_STATS_MON, stat_mon_isr,
427 stat_mon_isr_thread_fn, 0, "stat_mon_int", NULL);
428 if (ret_val) {
429 pr_err("%s: cannot register INT_SYS_STATS_MON handler, \
430 ret_val = 0x%x\n", __func__, ret_val);
431 tegra2_statmon_stop();
432 stat_mon->avp_sampler.enable = false;
433 kfree(stat_mon);
434 return ret_val;
435 }
436
437 return 0;
438}
439
440late_initcall(tegra2_stat_mon_init);
diff --git a/arch/arm/mach-tegra/tegra2_statmon.h b/arch/arm/mach-tegra/tegra2_statmon.h
new file mode 100644
index 00000000000..ae1094eb1c3
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_statmon.h
@@ -0,0 +1,33 @@
1/*
2 * arch/arm/mach-tegra/tegra2_statmon.h
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifdef CONFIG_TEGRA_STAT_MON
22int tegra2_statmon_start(void);
23void tegra2_statmon_stop(void);
24#else
25static inline int tegra2_statmon_start(void)
26{
27 return 0;
28}
29
30static inline void tegra2_statmon_stop(void)
31{
32}
33#endif
diff --git a/arch/arm/mach-tegra/tegra2_throttle.c b/arch/arm/mach-tegra/tegra2_throttle.c
new file mode 100644
index 00000000000..6114b20c6f5
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_throttle.c
@@ -0,0 +1,180 @@
1/*
2 * arch/arm/mach-tegra/tegra2_throttle.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Based on arch/arm/plat-omap/cpu-omap.c, (C) 2005 Nokia Corporation
9 *
10 * Copyright (C) 2010-2011 NVIDIA Corporation
11 *
12 * This software is licensed under the terms of the GNU General Public
13 * License version 2, as published by the Free Software Foundation, and
14 * may be copied, distributed, and modified under those terms.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/sched.h>
27#include <linux/cpufreq.h>
28#include <linux/delay.h>
29#include <linux/init.h>
30#include <linux/err.h>
31#include <linux/clk.h>
32#include <linux/io.h>
33#include <linux/debugfs.h>
34
35#include "clock.h"
36#include "cpu-tegra.h"
37
38/* tegra throttling require frequencies in the table to be in ascending order */
39static struct cpufreq_frequency_table *throttle_table;
40static struct mutex *cpu_throttle_lock;
41
42/* CPU frequency is gradually lowered when throttling is enabled */
43#define THROTTLE_DELAY msecs_to_jiffies(2000)
44
45static int is_throttling;
46static int throttle_lowest_index;
47static int throttle_highest_index;
48static int throttle_index;
49static int throttle_next_index;
50static struct delayed_work throttle_work;
51static struct workqueue_struct *workqueue;
52static DEFINE_MUTEX(tegra_throttle_lock);
53
54static void tegra_throttle_work_func(struct work_struct *work)
55{
56 unsigned int current_freq;
57
58 mutex_lock(cpu_throttle_lock);
59 if (!is_throttling)
60 goto out;
61
62 current_freq = tegra_getspeed(0);
63 throttle_index = throttle_next_index;
64
65 if (throttle_table[throttle_index].frequency < current_freq)
66 tegra_cpu_set_speed_cap(NULL);
67
68 if (throttle_index > throttle_lowest_index) {
69 throttle_next_index = throttle_index - 1;
70 queue_delayed_work(workqueue, &throttle_work, THROTTLE_DELAY);
71 }
72out:
73 mutex_unlock(cpu_throttle_lock);
74}
75
76/*
77 * tegra_throttling_enable
78 * This function may sleep
79 */
80void tegra_throttling_enable(bool enable)
81{
82 mutex_lock(&tegra_throttle_lock);
83 mutex_lock(cpu_throttle_lock);
84
85 if (enable && !(is_throttling++)) {
86 unsigned int current_freq = tegra_getspeed(0);
87
88 for (throttle_index = throttle_highest_index;
89 throttle_index >= throttle_lowest_index;
90 throttle_index--)
91 if (throttle_table[throttle_index].frequency
92 < current_freq)
93 break;
94
95 throttle_index = max(throttle_index, throttle_lowest_index);
96 throttle_next_index = throttle_index;
97 queue_delayed_work(workqueue, &throttle_work, 0);
98 } else if (!enable && is_throttling) {
99 if (!(--is_throttling)) {
100 /* restore speed requested by governor */
101 tegra_cpu_set_speed_cap(NULL);
102
103 mutex_unlock(cpu_throttle_lock);
104 cancel_delayed_work_sync(&throttle_work);
105 mutex_unlock(&tegra_throttle_lock);
106 return;
107 }
108 }
109 mutex_unlock(cpu_throttle_lock);
110 mutex_unlock(&tegra_throttle_lock);
111}
112EXPORT_SYMBOL_GPL(tegra_throttling_enable);
113
114unsigned int tegra_throttle_governor_speed(unsigned int requested_speed)
115{
116 return is_throttling ?
117 min(requested_speed, throttle_table[throttle_index].frequency) :
118 requested_speed;
119}
120
121bool tegra_is_throttling(void)
122{
123 return is_throttling;
124}
125
126int __init tegra_throttle_init(struct mutex *cpu_lock)
127{
128 struct tegra_cpufreq_table_data *table_data =
129 tegra_cpufreq_table_get();
130 if (IS_ERR_OR_NULL(table_data))
131 return -EINVAL;
132
133 /*
134 * High-priority, others flags default: not bound to a specific
135 * CPU, has rescue worker task (in case of allocation deadlock,
136 * etc.). Single-threaded.
137 */
138 workqueue = alloc_workqueue("cpu-tegra",
139 WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
140 if (!workqueue)
141 return -ENOMEM;
142 INIT_DELAYED_WORK(&throttle_work, tegra_throttle_work_func);
143
144 throttle_lowest_index = table_data->throttle_lowest_index;
145 throttle_highest_index = table_data->throttle_highest_index;
146 throttle_table = table_data->freq_table;
147 cpu_throttle_lock = cpu_lock;
148
149 return 0;
150}
151
152void tegra_throttle_exit(void)
153{
154 destroy_workqueue(workqueue);
155}
156
157#ifdef CONFIG_DEBUG_FS
158
159static int throttle_debug_set(void *data, u64 val)
160{
161 tegra_throttling_enable(val);
162 return 0;
163}
164static int throttle_debug_get(void *data, u64 *val)
165{
166 *val = (u64) is_throttling;
167 return 0;
168}
169DEFINE_SIMPLE_ATTRIBUTE(throttle_fops, throttle_debug_get, throttle_debug_set,
170 "%llu\n");
171
172int __init tegra_throttle_debug_init(struct dentry *cpu_tegra_debugfs_root)
173{
174 if (!debugfs_create_file("throttle", 0644, cpu_tegra_debugfs_root,
175 NULL, &throttle_fops))
176 return -ENOMEM;
177 return 0;
178}
179#endif /* CONFIG_DEBUG_FS */
180
diff --git a/arch/arm/mach-tegra/tegra3_actmon.c b/arch/arm/mach-tegra/tegra3_actmon.c
new file mode 100644
index 00000000000..43130f960ec
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_actmon.c
@@ -0,0 +1,847 @@
1/*
2 * Copyright (c) 2011, NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/spinlock.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/clk.h>
23#include <linux/interrupt.h>
24#include <linux/suspend.h>
25#include <linux/debugfs.h>
26#include <linux/seq_file.h>
27#include <linux/uaccess.h>
28
29#include <mach/iomap.h>
30#include <mach/irqs.h>
31#include <mach/clk.h>
32
33#include "clock.h"
34
35#define ACTMON_GLB_STATUS 0x00
36#define ACTMON_GLB_PERIOD_CTRL 0x04
37
38#define ACTMON_DEV_CTRL 0x00
39#define ACTMON_DEV_CTRL_ENB (0x1 << 31)
40#define ACTMON_DEV_CTRL_UP_WMARK_ENB (0x1 << 30)
41#define ACTMON_DEV_CTRL_DOWN_WMARK_ENB (0x1 << 29)
42#define ACTMON_DEV_CTRL_UP_WMARK_NUM_SHIFT 26
43#define ACTMON_DEV_CTRL_UP_WMARK_NUM_MASK (0x7 << 26)
44#define ACTMON_DEV_CTRL_DOWN_WMARK_NUM_SHIFT 23
45#define ACTMON_DEV_CTRL_DOWN_WMARK_NUM_MASK (0x7 << 23)
46#define ACTMON_DEV_CTRL_AVG_UP_WMARK_ENB (0x1 << 21)
47#define ACTMON_DEV_CTRL_AVG_DOWN_WMARK_ENB (0x1 << 20)
48#define ACTMON_DEV_CTRL_PERIODIC_ENB (0x1 << 18)
49#define ACTMON_DEV_CTRL_K_VAL_SHIFT 10
50#define ACTMON_DEV_CTRL_K_VAL_MASK (0x7 << 10)
51
52#define ACTMON_DEV_UP_WMARK 0x04
53#define ACTMON_DEV_DOWN_WMARK 0x08
54#define ACTMON_DEV_INIT_AVG 0x0c
55#define ACTMON_DEV_AVG_UP_WMARK 0x10
56#define ACTMON_DEV_AVG_DOWN_WMARK 0x14
57
58#define ACTMON_DEV_COUNT_WEGHT 0x18
59#define ACTMON_DEV_COUNT 0x1c
60#define ACTMON_DEV_AVG_COUNT 0x20
61
62#define ACTMON_DEV_INTR_STATUS 0x24
63#define ACTMON_DEV_INTR_UP_WMARK (0x1 << 31)
64#define ACTMON_DEV_INTR_DOWN_WMARK (0x1 << 30)
65#define ACTMON_DEV_INTR_AVG_DOWN_WMARK (0x1 << 25)
66#define ACTMON_DEV_INTR_AVG_UP_WMARK (0x1 << 24)
67
68#define ACTMON_DEFAULT_AVG_WINDOW_LOG2 6
69#define ACTMON_DEFAULT_AVG_BAND 6 /* 1/10 of % */
70
71enum actmon_type {
72 ACTMON_LOAD_SAMPLER,
73 ACTMON_FREQ_SAMPLER,
74};
75
76enum actmon_state {
77 ACTMON_UNINITIALIZED = -1,
78 ACTMON_OFF = 0,
79 ACTMON_ON = 1,
80 ACTMON_SUSPENDED = 2,
81};
82
83#define ACTMON_DEFAULT_SAMPLING_PERIOD 12
84static u8 actmon_sampling_period;
85
86static unsigned long actmon_clk_freq;
87
88
89/* Units:
90 * - frequency in kHz
91 * - coefficients, and thresholds in %
92 * - sampling period in ms
93 * - window in sample periods (value = setting + 1)
94 */
95struct actmon_dev {
96 u32 reg;
97 u32 glb_status_irq_mask;
98 const char *dev_id;
99 const char *con_id;
100 struct clk *clk;
101
102 unsigned long max_freq;
103 unsigned long target_freq;
104 unsigned long cur_freq;
105
106 unsigned long avg_actv_freq;
107 unsigned long avg_band_freq;
108 unsigned int avg_sustain_coef;
109 u32 avg_count;
110
111 unsigned long boost_freq;
112 unsigned long boost_freq_step;
113 unsigned int boost_up_coef;
114 unsigned int boost_down_coef;
115 unsigned int boost_up_threshold;
116 unsigned int boost_down_threshold;
117
118 u8 up_wmark_window;
119 u8 down_wmark_window;
120 u8 avg_window_log2;
121 u32 count_weight;
122
123 enum actmon_type type;
124 enum actmon_state state;
125 enum actmon_state saved_state;
126
127 spinlock_t lock;
128
129 struct notifier_block rate_change_nb;
130};
131
132static void __iomem *actmon_base = IO_ADDRESS(TEGRA_ACTMON_BASE);
133
134static inline u32 actmon_readl(u32 offset)
135{
136 return __raw_readl((u32)actmon_base + offset);
137}
138static inline void actmon_writel(u32 val, u32 offset)
139{
140 __raw_writel(val, (u32)actmon_base + offset);
141}
142static inline void actmon_wmb(void)
143{
144 wmb();
145 actmon_readl(ACTMON_GLB_STATUS);
146}
147
148#define offs(x) (dev->reg + x)
149
150static inline unsigned long do_percent(unsigned long val, unsigned int pct)
151{
152 return val * pct / 100;
153}
154
155static inline void actmon_dev_up_wmark_set(struct actmon_dev *dev)
156{
157 u32 val;
158 unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ?
159 dev->cur_freq : actmon_clk_freq;
160
161 val = freq * actmon_sampling_period;
162 actmon_writel(do_percent(val, dev->boost_up_threshold),
163 offs(ACTMON_DEV_UP_WMARK));
164}
165
166static inline void actmon_dev_down_wmark_set(struct actmon_dev *dev)
167{
168 u32 val;
169 unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ?
170 dev->cur_freq : actmon_clk_freq;
171
172 val = freq * actmon_sampling_period;
173 actmon_writel(do_percent(val, dev->boost_down_threshold),
174 offs(ACTMON_DEV_DOWN_WMARK));
175}
176
177static inline void actmon_dev_wmark_set(struct actmon_dev *dev)
178{
179 u32 val;
180 unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ?
181 dev->cur_freq : actmon_clk_freq;
182
183 val = freq * actmon_sampling_period;
184 actmon_writel(do_percent(val, dev->boost_up_threshold),
185 offs(ACTMON_DEV_UP_WMARK));
186 actmon_writel(do_percent(val, dev->boost_down_threshold),
187 offs(ACTMON_DEV_DOWN_WMARK));
188}
189
190static inline void actmon_dev_avg_wmark_set(struct actmon_dev *dev)
191{
192 u32 avg = dev->avg_count;
193 u32 band = dev->avg_band_freq * actmon_sampling_period;
194
195 actmon_writel(avg + band, offs(ACTMON_DEV_AVG_UP_WMARK));
196 avg = max(avg, band);
197 actmon_writel(avg - band, offs(ACTMON_DEV_AVG_DOWN_WMARK));
198}
199
200static unsigned long actmon_dev_avg_freq_get(struct actmon_dev *dev)
201{
202 u64 val;
203
204 if (dev->type == ACTMON_FREQ_SAMPLER)
205 return dev->avg_count / actmon_sampling_period;
206
207 val = (u64)dev->avg_count * dev->cur_freq;
208 do_div(val, actmon_clk_freq * actmon_sampling_period);
209 return (u32)val;
210}
211
212/* Activity monitor sampling operations */
213irqreturn_t actmon_dev_isr(int irq, void *dev_id)
214{
215 u32 val;
216 unsigned long flags;
217 struct actmon_dev *dev = (struct actmon_dev *)dev_id;
218
219 val = actmon_readl(ACTMON_GLB_STATUS) & dev->glb_status_irq_mask;
220 if (!val)
221 return IRQ_NONE;
222
223 spin_lock_irqsave(&dev->lock, flags);
224
225 dev->avg_count = actmon_readl(offs(ACTMON_DEV_AVG_COUNT));
226 actmon_dev_avg_wmark_set(dev);
227
228 val = actmon_readl(offs(ACTMON_DEV_INTR_STATUS));
229 if (val & ACTMON_DEV_INTR_UP_WMARK) {
230 val = actmon_readl(offs(ACTMON_DEV_CTRL)) |
231 ACTMON_DEV_CTRL_UP_WMARK_ENB |
232 ACTMON_DEV_CTRL_DOWN_WMARK_ENB;
233
234 dev->boost_freq = dev->boost_freq_step +
235 do_percent(dev->boost_freq, dev->boost_up_coef);
236 if (dev->boost_freq >= dev->max_freq) {
237 dev->boost_freq = dev->max_freq;
238 val &= ~ACTMON_DEV_CTRL_UP_WMARK_ENB;
239 }
240 actmon_writel(val, offs(ACTMON_DEV_CTRL));
241 } else if (val & ACTMON_DEV_INTR_DOWN_WMARK) {
242 val = actmon_readl(offs(ACTMON_DEV_CTRL)) |
243 ACTMON_DEV_CTRL_UP_WMARK_ENB |
244 ACTMON_DEV_CTRL_DOWN_WMARK_ENB;
245
246 dev->boost_freq =
247 do_percent(dev->boost_freq, dev->boost_down_coef);
248 if (dev->boost_freq < (dev->boost_freq_step >> 1)) {
249 dev->boost_freq = 0;
250 val &= ~ACTMON_DEV_CTRL_DOWN_WMARK_ENB;
251 }
252 actmon_writel(val, offs(ACTMON_DEV_CTRL));
253 }
254
255 actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS)); /* clr all */
256 actmon_wmb();
257
258 spin_unlock_irqrestore(&dev->lock, flags);
259 return IRQ_WAKE_THREAD;
260}
261
262irqreturn_t actmon_dev_fn(int irq, void *dev_id)
263{
264 unsigned long flags, freq;
265 struct actmon_dev *dev = (struct actmon_dev *)dev_id;
266
267 spin_lock_irqsave(&dev->lock, flags);
268
269 if (dev->state != ACTMON_ON) {
270 spin_unlock_irqrestore(&dev->lock, flags);
271 return IRQ_HANDLED;
272 }
273
274 freq = actmon_dev_avg_freq_get(dev);
275 dev->avg_actv_freq = freq;
276 freq = do_percent(freq, dev->avg_sustain_coef);
277 freq += dev->boost_freq;
278 dev->target_freq = freq;
279
280 spin_unlock_irqrestore(&dev->lock, flags);
281
282 pr_debug("%s.%s(kHz): avg: %lu, target: %lu current: %lu\n",
283 dev->dev_id, dev->con_id, dev->avg_actv_freq,
284 dev->target_freq, dev->cur_freq);
285 clk_set_rate(dev->clk, freq * 1000);
286
287 return IRQ_HANDLED;
288}
289
290static int actmon_rate_notify_cb(
291 struct notifier_block *nb, unsigned long rate, void *v)
292{
293 unsigned long flags;
294 struct actmon_dev *dev = container_of(
295 nb, struct actmon_dev, rate_change_nb);
296
297 spin_lock_irqsave(&dev->lock, flags);
298
299 dev->cur_freq = rate / 1000;
300 if (dev->type == ACTMON_FREQ_SAMPLER) {
301 actmon_dev_wmark_set(dev);
302 actmon_wmb();
303 }
304
305 spin_unlock_irqrestore(&dev->lock, flags);
306 return NOTIFY_OK;
307};
308
309/* Activity monitor configuration and control */
310static void actmon_dev_configure(struct actmon_dev *dev, unsigned long freq)
311{
312 u32 val;
313
314 dev->cur_freq = freq;
315 dev->target_freq = freq;
316 dev->avg_actv_freq = freq;
317
318 if (dev->type == ACTMON_FREQ_SAMPLER) {
319 dev->avg_count = dev->cur_freq * actmon_sampling_period;
320 dev->avg_band_freq = dev->max_freq *
321 ACTMON_DEFAULT_AVG_BAND / 1000;
322 } else {
323 dev->avg_count = actmon_clk_freq * actmon_sampling_period;
324 dev->avg_band_freq = actmon_clk_freq *
325 ACTMON_DEFAULT_AVG_BAND / 1000;
326 }
327 actmon_writel(dev->avg_count, offs(ACTMON_DEV_INIT_AVG));
328
329 BUG_ON(!dev->boost_up_threshold);
330 dev->avg_sustain_coef = 100 * 100 / dev->boost_up_threshold;
331 actmon_dev_avg_wmark_set(dev);
332 actmon_dev_wmark_set(dev);
333
334 actmon_writel(dev->count_weight, offs(ACTMON_DEV_COUNT_WEGHT));
335 actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS)); /* clr all */
336
337 val = ACTMON_DEV_CTRL_PERIODIC_ENB | ACTMON_DEV_CTRL_AVG_UP_WMARK_ENB |
338 ACTMON_DEV_CTRL_AVG_DOWN_WMARK_ENB;
339 val |= ((dev->avg_window_log2 - 1) << ACTMON_DEV_CTRL_K_VAL_SHIFT) &
340 ACTMON_DEV_CTRL_K_VAL_MASK;
341 val |= ((dev->down_wmark_window - 1) <<
342 ACTMON_DEV_CTRL_DOWN_WMARK_NUM_SHIFT) &
343 ACTMON_DEV_CTRL_DOWN_WMARK_NUM_MASK;
344 val |= ((dev->up_wmark_window - 1) <<
345 ACTMON_DEV_CTRL_UP_WMARK_NUM_SHIFT) &
346 ACTMON_DEV_CTRL_UP_WMARK_NUM_MASK;
347 val |= ACTMON_DEV_CTRL_DOWN_WMARK_ENB | ACTMON_DEV_CTRL_UP_WMARK_ENB;
348 actmon_writel(val, offs(ACTMON_DEV_CTRL));
349 actmon_wmb();
350}
351
352static void actmon_dev_enable(struct actmon_dev *dev)
353{
354 u32 val;
355 unsigned long flags;
356
357 spin_lock_irqsave(&dev->lock, flags);
358
359 if (dev->state == ACTMON_OFF) {
360 dev->state = ACTMON_ON;
361
362 val = actmon_readl(offs(ACTMON_DEV_CTRL));
363 val |= ACTMON_DEV_CTRL_ENB;
364 actmon_writel(val, offs(ACTMON_DEV_CTRL));
365 actmon_wmb();
366 }
367 spin_unlock_irqrestore(&dev->lock, flags);
368}
369
370static void actmon_dev_disable(struct actmon_dev *dev)
371{
372 u32 val;
373 unsigned long flags;
374
375 spin_lock_irqsave(&dev->lock, flags);
376
377 if (dev->state == ACTMON_ON) {
378 dev->state = ACTMON_OFF;
379
380 val = actmon_readl(offs(ACTMON_DEV_CTRL));
381 val &= ~ACTMON_DEV_CTRL_ENB;
382 actmon_writel(val, offs(ACTMON_DEV_CTRL));
383 actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS));
384 actmon_wmb();
385 }
386 spin_unlock_irqrestore(&dev->lock, flags);
387}
388
389static void actmon_dev_suspend(struct actmon_dev *dev)
390{
391 u32 val;
392 unsigned long flags;
393
394 spin_lock_irqsave(&dev->lock, flags);
395
396 if ((dev->state == ACTMON_ON) || (dev->state == ACTMON_OFF)){
397 dev->saved_state = dev->state;
398 dev->state = ACTMON_SUSPENDED;
399
400 val = actmon_readl(offs(ACTMON_DEV_CTRL));
401 val &= ~ACTMON_DEV_CTRL_ENB;
402 actmon_writel(val, offs(ACTMON_DEV_CTRL));
403 actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS));
404 actmon_wmb();
405 }
406 spin_unlock_irqrestore(&dev->lock, flags);
407}
408
409static void actmon_dev_resume(struct actmon_dev *dev)
410{
411 u32 val;
412 unsigned long flags;
413 unsigned long freq = clk_get_rate(dev->clk) / 1000;
414
415 spin_lock_irqsave(&dev->lock, flags);
416
417 if (dev->state == ACTMON_SUSPENDED) {
418 actmon_dev_configure(dev, freq);
419 dev->state = dev->saved_state;
420 if (dev->state == ACTMON_ON) {
421 val = actmon_readl(offs(ACTMON_DEV_CTRL));
422 val |= ACTMON_DEV_CTRL_ENB;
423 actmon_writel(val, offs(ACTMON_DEV_CTRL));
424 actmon_wmb();
425 }
426 }
427 spin_unlock_irqrestore(&dev->lock, flags);
428}
429
430static int __init actmon_dev_init(struct actmon_dev *dev)
431{
432 int ret;
433 struct clk *p;
434 unsigned long freq;
435
436 spin_lock_init(&dev->lock);
437
438 dev->clk = clk_get_sys(dev->dev_id, dev->con_id);
439 if (IS_ERR(dev->clk)) {
440 pr_err("Failed to find %s.%s clock\n",
441 dev->dev_id, dev->con_id);
442 return -ENODEV;
443 }
444 dev->max_freq = clk_round_rate(dev->clk, ULONG_MAX);
445 clk_set_rate(dev->clk, dev->max_freq);
446 dev->max_freq /= 1000;
447 freq = clk_get_rate(dev->clk) / 1000;
448 actmon_dev_configure(dev, freq);
449
450 /* actmon device controls shared bus user clock, but rate
451 change notification should come from bus clock itself */
452 p = clk_get_parent(dev->clk);
453 BUG_ON(!p);
454
455 if (dev->rate_change_nb.notifier_call) {
456 ret = tegra_register_clk_rate_notifier(p, &dev->rate_change_nb);
457 if (ret) {
458 pr_err("Failed to register %s rate change notifier"
459 " for %s\n", p->name, dev->dev_id);
460 return ret;
461 }
462 }
463
464 ret = request_threaded_irq(INT_ACTMON, actmon_dev_isr, actmon_dev_fn,
465 IRQF_SHARED, dev->dev_id, dev);
466 if (ret) {
467 pr_err("Failed irq %d request for %s.%s\n",
468 INT_ACTMON, dev->dev_id, dev->con_id);
469 tegra_unregister_clk_rate_notifier(p, &dev->rate_change_nb);
470 return ret;
471 }
472
473 dev->state = ACTMON_OFF;
474 actmon_dev_enable(dev);
475 clk_enable(dev->clk);
476 return 0;
477}
478
479/* EMC activity monitor: frequency sampling device:
480 * activity counter is incremented every 256 memory transactions, and
481 * each transaction takes 2 EMC clocks; count_weight = 512.
482 */
483static struct actmon_dev actmon_dev_emc = {
484 .reg = 0x1c0,
485 .glb_status_irq_mask = (0x1 << 26),
486 .dev_id = "tegra_actmon",
487 .con_id = "emc",
488
489 .boost_freq_step = 16000,
490 .boost_up_coef = 200,
491 .boost_down_coef = 50,
492 .boost_up_threshold = 60,
493 .boost_down_threshold = 40,
494
495 .up_wmark_window = 1,
496 .down_wmark_window = 3,
497 .avg_window_log2 = ACTMON_DEFAULT_AVG_WINDOW_LOG2,
498 .count_weight = 0x200,
499
500 .type = ACTMON_FREQ_SAMPLER,
501 .state = ACTMON_UNINITIALIZED,
502
503 .rate_change_nb = {
504 .notifier_call = actmon_rate_notify_cb,
505 },
506};
507
508/* AVP activity monitor: load sampling device:
509 * activity counter is incremented on every actmon clock pulse while
510 * AVP is not halted by flow controller; count_weight = 1.
511 */
512static struct actmon_dev actmon_dev_avp = {
513 .reg = 0x0c0,
514 .glb_status_irq_mask = (0x1 << 30),
515 .dev_id = "tegra_actmon",
516 .con_id = "avp",
517
518 .boost_freq_step = 8000,
519 .boost_up_coef = 200,
520 .boost_down_coef = 50,
521 .boost_up_threshold = 75,
522 .boost_down_threshold = 50,
523
524 .up_wmark_window = 1,
525 .down_wmark_window = 3,
526 .avg_window_log2 = ACTMON_DEFAULT_AVG_WINDOW_LOG2,
527 .count_weight = 0x1,
528
529 .type = ACTMON_LOAD_SAMPLER,
530 .state = ACTMON_UNINITIALIZED,
531
532 .rate_change_nb = {
533 .notifier_call = actmon_rate_notify_cb,
534 },
535};
536
537static struct actmon_dev *actmon_devices[] = {
538 &actmon_dev_emc,
539 &actmon_dev_avp,
540};
541
542/* Activity monitor suspend/resume */
543static int actmon_pm_notify(struct notifier_block *nb,
544 unsigned long event, void *data)
545{
546 int i;
547
548 switch (event) {
549 case PM_SUSPEND_PREPARE:
550 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++)
551 actmon_dev_suspend(actmon_devices[i]);
552 break;
553 case PM_POST_SUSPEND:
554 actmon_writel(actmon_sampling_period - 1,
555 ACTMON_GLB_PERIOD_CTRL);
556 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++)
557 actmon_dev_resume(actmon_devices[i]);
558 break;
559 }
560
561 return NOTIFY_OK;
562};
563
564static struct notifier_block actmon_pm_nb = {
565 .notifier_call = actmon_pm_notify,
566};
567
568#ifdef CONFIG_DEBUG_FS
569
570#define RW_MODE (S_IWUSR | S_IRUGO)
571#define RO_MODE S_IRUGO
572
573static struct dentry *clk_debugfs_root;
574
575static int type_show(struct seq_file *s, void *data)
576{
577 struct actmon_dev *dev = s->private;
578
579 seq_printf(s, "%s\n", (dev->type == ACTMON_LOAD_SAMPLER) ?
580 "Load Activity Monitor" : "Frequency Activity Monitor");
581 return 0;
582}
583static int type_open(struct inode *inode, struct file *file)
584{
585 return single_open(file, type_show, inode->i_private);
586}
587static const struct file_operations type_fops = {
588 .open = type_open,
589 .read = seq_read,
590 .llseek = seq_lseek,
591 .release = single_release,
592};
593
594static int actv_get(void *data, u64 *val)
595{
596 unsigned long flags;
597 struct actmon_dev *dev = data;
598
599 spin_lock_irqsave(&dev->lock, flags);
600 *val = actmon_dev_avg_freq_get(dev);
601 spin_unlock_irqrestore(&dev->lock, flags);
602 return 0;
603}
604DEFINE_SIMPLE_ATTRIBUTE(actv_fops, actv_get, NULL, "%llu\n");
605
606static int step_get(void *data, u64 *val)
607{
608 struct actmon_dev *dev = data;
609 *val = dev->boost_freq_step * 100 / dev->max_freq;
610 return 0;
611}
612static int step_set(void *data, u64 val)
613{
614 unsigned long flags;
615 struct actmon_dev *dev = data;
616
617 if (val > 100)
618 val = 100;
619
620 spin_lock_irqsave(&dev->lock, flags);
621 dev->boost_freq_step = do_percent(dev->max_freq, (unsigned int)val);
622 spin_unlock_irqrestore(&dev->lock, flags);
623 return 0;
624}
625DEFINE_SIMPLE_ATTRIBUTE(step_fops, step_get, step_set, "%llu\n");
626
627static int up_threshold_get(void *data, u64 *val)
628{
629 struct actmon_dev *dev = data;
630 *val = dev->boost_up_threshold;
631 return 0;
632}
633static int up_threshold_set(void *data, u64 val)
634{
635 unsigned long flags;
636 struct actmon_dev *dev = data;
637 unsigned int up_threshold = (unsigned int)val;
638
639 if (up_threshold > 100)
640 up_threshold = 100;
641
642 spin_lock_irqsave(&dev->lock, flags);
643
644 if (up_threshold <= dev->boost_down_threshold)
645 up_threshold = dev->boost_down_threshold;
646 if (up_threshold)
647 dev->avg_sustain_coef = 100 * 100 / up_threshold;
648 dev->boost_up_threshold = up_threshold;
649
650 actmon_dev_up_wmark_set(dev);
651 actmon_wmb();
652
653 spin_unlock_irqrestore(&dev->lock, flags);
654 return 0;
655}
656DEFINE_SIMPLE_ATTRIBUTE(up_threshold_fops, up_threshold_get,
657 up_threshold_set, "%llu\n");
658
659static int down_threshold_get(void *data, u64 *val)
660{
661 struct actmon_dev *dev = data;
662 *val = dev->boost_down_threshold;
663 return 0;
664}
665static int down_threshold_set(void *data, u64 val)
666{
667 unsigned long flags;
668 struct actmon_dev *dev = data;
669 unsigned int down_threshold = (unsigned int)val;
670
671 spin_lock_irqsave(&dev->lock, flags);
672
673 if (down_threshold >= dev->boost_up_threshold)
674 down_threshold = dev->boost_up_threshold;
675 dev->boost_down_threshold = down_threshold;
676
677 actmon_dev_down_wmark_set(dev);
678 actmon_wmb();
679
680 spin_unlock_irqrestore(&dev->lock, flags);
681 return 0;
682}
683DEFINE_SIMPLE_ATTRIBUTE(down_threshold_fops, down_threshold_get,
684 down_threshold_set, "%llu\n");
685
686static int state_get(void *data, u64 *val)
687{
688 struct actmon_dev *dev = data;
689 *val = dev->state;
690 return 0;
691}
692static int state_set(void *data, u64 val)
693{
694 struct actmon_dev *dev = data;
695
696 if (val)
697 actmon_dev_enable(dev);
698 else
699 actmon_dev_disable(dev);
700 return 0;
701}
702DEFINE_SIMPLE_ATTRIBUTE(state_fops, state_get, state_set, "%llu\n");
703
704static int period_get(void *data, u64 *val)
705{
706 *val = actmon_sampling_period;
707 return 0;
708}
709static int period_set(void *data, u64 val)
710{
711 int i;
712 unsigned long flags;
713 u8 period = (u8)val;
714
715 if (period) {
716 actmon_sampling_period = period;
717 actmon_writel(period - 1, ACTMON_GLB_PERIOD_CTRL);
718
719 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++) {
720 struct actmon_dev *dev = actmon_devices[i];
721 spin_lock_irqsave(&dev->lock, flags);
722 actmon_dev_wmark_set(dev);
723 spin_unlock_irqrestore(&dev->lock, flags);
724 }
725 actmon_wmb();
726 return 0;
727 }
728 return -EINVAL;
729}
730DEFINE_SIMPLE_ATTRIBUTE(period_fops, period_get, period_set, "%llu\n");
731
732
733static int actmon_debugfs_create_dev(struct actmon_dev *dev)
734{
735 struct dentry *dir, *d;
736
737 if (dev->state == ACTMON_UNINITIALIZED)
738 return 0;
739
740 dir = debugfs_create_dir(dev->con_id, clk_debugfs_root);
741 if (!dir)
742 return -ENOMEM;
743
744 d = debugfs_create_file(
745 "actv_type", RO_MODE, dir, dev, &type_fops);
746 if (!d)
747 return -ENOMEM;
748
749 d = debugfs_create_file(
750 "avg_activity", RO_MODE, dir, dev, &actv_fops);
751 if (!d)
752 return -ENOMEM;
753
754 d = debugfs_create_file(
755 "boost_step", RW_MODE, dir, dev, &step_fops);
756 if (!d)
757 return -ENOMEM;
758
759 d = debugfs_create_u32(
760 "boost_rate_dec", RW_MODE, dir, (u32 *)&dev->boost_down_coef);
761 if (!d)
762 return -ENOMEM;
763
764 d = debugfs_create_u32(
765 "boost_rate_inc", RW_MODE, dir, (u32 *)&dev->boost_up_coef);
766 if (!d)
767 return -ENOMEM;
768
769 d = debugfs_create_file(
770 "boost_threshold_dn", RW_MODE, dir, dev, &down_threshold_fops);
771 if (!d)
772 return -ENOMEM;
773
774 d = debugfs_create_file(
775 "boost_threshold_up", RW_MODE, dir, dev, &up_threshold_fops);
776 if (!d)
777 return -ENOMEM;
778
779 d = debugfs_create_file(
780 "state", RW_MODE, dir, dev, &state_fops);
781 if (!d)
782 return -ENOMEM;
783
784 return 0;
785}
786
787static int __init actmon_debugfs_init(void)
788{
789 int i;
790 int ret = -ENOMEM;
791 struct dentry *d;
792
793 d = debugfs_create_dir("tegra_actmon", NULL);
794 if (!d)
795 return ret;
796 clk_debugfs_root = d;
797
798 d = debugfs_create_file("period", RW_MODE, d, NULL, &period_fops);
799 if (!d)
800 goto err_out;
801
802 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++) {
803 ret = actmon_debugfs_create_dev(actmon_devices[i]);
804 if (ret)
805 goto err_out;
806 }
807 return 0;
808
809err_out:
810 debugfs_remove_recursive(clk_debugfs_root);
811 return ret;
812}
813
814#endif
815
816static int __init tegra_actmon_init(void)
817{
818 int i, ret;
819 struct clk *c = tegra_get_clock_by_name("actmon");
820
821 if (!c) {
822 pr_err("%s: Failed to find actmon clock\n", __func__);
823 return 0;
824 }
825 actmon_clk_freq = clk_get_rate(c) / 1000;
826 ret = clk_enable(c);
827 if (ret) {
828 pr_err("%s: Failed to enable actmon clock\n", __func__);
829 return 0;
830 }
831 actmon_sampling_period = ACTMON_DEFAULT_SAMPLING_PERIOD;
832 actmon_writel(actmon_sampling_period - 1, ACTMON_GLB_PERIOD_CTRL);
833
834 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++) {
835 ret = actmon_dev_init(actmon_devices[i]);
836 pr_info("%s.%s: %s initialization (%d)\n",
837 actmon_devices[i]->dev_id, actmon_devices[i]->con_id,
838 ret ? "Failed" : "Completed", ret);
839 }
840 register_pm_notifier(&actmon_pm_nb);
841
842#ifdef CONFIG_DEBUG_FS
843 actmon_debugfs_init();
844#endif
845 return 0;
846}
847late_initcall(tegra_actmon_init);
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
new file mode 100644
index 00000000000..0b2d4f4fc6d
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -0,0 +1,5212 @@
1/*
2 * arch/arm/mach-tegra/tegra3_clocks.c
3 *
4 * Copyright (C) 2010-2012 NVIDIA Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/list.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/clk.h>
29#include <linux/cpufreq.h>
30#include <linux/syscore_ops.h>
31
32#include <asm/clkdev.h>
33
34#include <mach/iomap.h>
35#include <mach/edp.h>
36
37#include "clock.h"
38#include "fuse.h"
39#include "dvfs.h"
40#include "pm.h"
41#include "sleep.h"
42#include "tegra3_emc.h"
43
44#define RST_DEVICES_L 0x004
45#define RST_DEVICES_H 0x008
46#define RST_DEVICES_U 0x00C
47#define RST_DEVICES_V 0x358
48#define RST_DEVICES_W 0x35C
49#define RST_DEVICES_SET_L 0x300
50#define RST_DEVICES_CLR_L 0x304
51#define RST_DEVICES_SET_V 0x430
52#define RST_DEVICES_CLR_V 0x434
53#define RST_DEVICES_NUM 5
54
55#define CLK_OUT_ENB_L 0x010
56#define CLK_OUT_ENB_H 0x014
57#define CLK_OUT_ENB_U 0x018
58#define CLK_OUT_ENB_V 0x360
59#define CLK_OUT_ENB_W 0x364
60#define CLK_OUT_ENB_SET_L 0x320
61#define CLK_OUT_ENB_CLR_L 0x324
62#define CLK_OUT_ENB_SET_V 0x440
63#define CLK_OUT_ENB_CLR_V 0x444
64#define CLK_OUT_ENB_NUM 5
65
66#define RST_DEVICES_V_SWR_CPULP_RST_DIS (0x1 << 1)
67#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1)
68
69#define PERIPH_CLK_TO_BIT(c) (1 << (c->u.periph.clk_num % 32))
70#define PERIPH_CLK_TO_RST_REG(c) \
71 periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4)
72#define PERIPH_CLK_TO_RST_SET_REG(c) \
73 periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8)
74#define PERIPH_CLK_TO_RST_CLR_REG(c) \
75 periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8)
76
77#define PERIPH_CLK_TO_ENB_REG(c) \
78 periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4)
79#define PERIPH_CLK_TO_ENB_SET_REG(c) \
80 periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8)
81#define PERIPH_CLK_TO_ENB_CLR_REG(c) \
82 periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8)
83
84#define CLK_MASK_ARM 0x44
85#define MISC_CLK_ENB 0x48
86
87#define OSC_CTRL 0x50
88#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
89#define OSC_CTRL_OSC_FREQ_13MHZ (0x0<<28)
90#define OSC_CTRL_OSC_FREQ_19_2MHZ (0x4<<28)
91#define OSC_CTRL_OSC_FREQ_12MHZ (0x8<<28)
92#define OSC_CTRL_OSC_FREQ_26MHZ (0xC<<28)
93#define OSC_CTRL_OSC_FREQ_16_8MHZ (0x1<<28)
94#define OSC_CTRL_OSC_FREQ_38_4MHZ (0x5<<28)
95#define OSC_CTRL_OSC_FREQ_48MHZ (0x9<<28)
96#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
97
98#define OSC_CTRL_PLL_REF_DIV_MASK (3<<26)
99#define OSC_CTRL_PLL_REF_DIV_1 (0<<26)
100#define OSC_CTRL_PLL_REF_DIV_2 (1<<26)
101#define OSC_CTRL_PLL_REF_DIV_4 (2<<26)
102
103#define PERIPH_CLK_SOURCE_I2S1 0x100
104#define PERIPH_CLK_SOURCE_EMC 0x19c
105#define PERIPH_CLK_SOURCE_OSC 0x1fc
106#define PERIPH_CLK_SOURCE_NUM1 \
107 ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
108
109#define PERIPH_CLK_SOURCE_G3D2 0x3b0
110#define PERIPH_CLK_SOURCE_SE 0x42c
111#define PERIPH_CLK_SOURCE_NUM2 \
112 ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1)
113
114#define AUDIO_DLY_CLK 0x49c
115#define AUDIO_SYNC_CLK_SPDIF 0x4b4
116#define PERIPH_CLK_SOURCE_NUM3 \
117 ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1)
118
119#define PERIPH_CLK_SOURCE_NUM (PERIPH_CLK_SOURCE_NUM1 + \
120 PERIPH_CLK_SOURCE_NUM2 + \
121 PERIPH_CLK_SOURCE_NUM3)
122
123#define CPU_SOFTRST_CTRL 0x380
124
125#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
126#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
127#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
128#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT 8
129#define PERIPH_CLK_SOURCE_DIVIDLE_VAL 50
130#define PERIPH_CLK_UART_DIV_ENB (1<<24)
131#define PERIPH_CLK_VI_SEL_EX_SHIFT 24
132#define PERIPH_CLK_VI_SEL_EX_MASK (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT)
133#define PERIPH_CLK_NAND_DIV_EX_ENB (1<<8)
134#define PERIPH_CLK_DTV_POLARITY_INV (1<<25)
135
136#define AUDIO_SYNC_SOURCE_MASK 0x0F
137#define AUDIO_SYNC_DISABLE_BIT 0x10
138#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4)
139
140#define PLL_BASE 0x0
141#define PLL_BASE_BYPASS (1<<31)
142#define PLL_BASE_ENABLE (1<<30)
143#define PLL_BASE_REF_ENABLE (1<<29)
144#define PLL_BASE_OVERRIDE (1<<28)
145#define PLL_BASE_LOCK (1<<27)
146#define PLL_BASE_DIVP_MASK (0x7<<20)
147#define PLL_BASE_DIVP_SHIFT 20
148#define PLL_BASE_DIVN_MASK (0x3FF<<8)
149#define PLL_BASE_DIVN_SHIFT 8
150#define PLL_BASE_DIVM_MASK (0x1F)
151#define PLL_BASE_DIVM_SHIFT 0
152
153#define PLL_OUT_RATIO_MASK (0xFF<<8)
154#define PLL_OUT_RATIO_SHIFT 8
155#define PLL_OUT_OVERRIDE (1<<2)
156#define PLL_OUT_CLKEN (1<<1)
157#define PLL_OUT_RESET_DISABLE (1<<0)
158
159#define PLL_MISC(c) \
160 (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
161#define PLL_MISC_LOCK_ENABLE(c) \
162 (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18))
163
164#define PLL_MISC_DCCON_SHIFT 20
165#define PLL_MISC_CPCON_SHIFT 8
166#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
167#define PLL_MISC_LFCON_SHIFT 4
168#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
169#define PLL_MISC_VCOCON_SHIFT 0
170#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
171#define PLLD_MISC_CLKENABLE (1<<30)
172
173#define PLLU_BASE_POST_DIV (1<<20)
174
175#define PLLD_BASE_DSIB_MUX_SHIFT 25
176#define PLLD_BASE_DSIB_MUX_MASK (1<<PLLD_BASE_DSIB_MUX_SHIFT)
177#define PLLD_BASE_CSI_CLKENABLE (1<<26)
178#define PLLD_MISC_DSI_CLKENABLE (1<<30)
179#define PLLD_MISC_DIV_RST (1<<23)
180#define PLLD_MISC_DCCON_SHIFT 12
181
182#define PLLDU_LFCON_SET_DIVN 600
183
184/* FIXME: OUT_OF_TABLE_CPCON per pll */
185#define OUT_OF_TABLE_CPCON 0x8
186
187#define SUPER_CLK_MUX 0x00
188#define SUPER_STATE_SHIFT 28
189#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
190#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
191#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
192#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
193#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
194#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
195#define SUPER_LP_DIV2_BYPASS (0x1 << 16)
196#define SUPER_SOURCE_MASK 0xF
197#define SUPER_FIQ_SOURCE_SHIFT 12
198#define SUPER_IRQ_SOURCE_SHIFT 8
199#define SUPER_RUN_SOURCE_SHIFT 4
200#define SUPER_IDLE_SOURCE_SHIFT 0
201
202#define SUPER_CLK_DIVIDER 0x04
203#define SUPER_CLOCK_SKIP_ENABLE (0x1 << 31)
204#define SUPER_CLOCK_DIV_U71_SHIFT 16
205#define SUPER_CLOCK_DIV_U71_MASK (0xff << SUPER_CLOCK_DIV_U71_SHIFT)
206#define SUPER_CLOCK_SKIP_MUL_SHIFT 8
207#define SUPER_CLOCK_SKIP_MUL_MASK (0xff << SUPER_CLOCK_SKIP_MUL_SHIFT)
208#define SUPER_CLOCK_SKIP_DIV_SHIFT 0
209#define SUPER_CLOCK_SKIP_DIV_MASK (0xff << SUPER_CLOCK_SKIP_DIV_SHIFT)
210#define SUPER_CLOCK_SKIP_MASK \
211 (SUPER_CLOCK_SKIP_MUL_MASK | SUPER_CLOCK_SKIP_DIV_MASK)
212#define SUPER_CLOCK_SKIP_TERM_MAX 256
213
214#define BUS_CLK_DISABLE (1<<3)
215#define BUS_CLK_DIV_MASK 0x3
216
217#define PMC_CTRL 0x0
218 #define PMC_CTRL_BLINK_ENB (1 << 7)
219
220#define PMC_DPD_PADS_ORIDE 0x1c
221 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
222
223#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
224#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
225#define PMC_BLINK_TIMER_ENB (1 << 15)
226#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
227#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
228
229#define PMC_PLLP_WB0_OVERRIDE 0xf8
230#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE (1 << 12)
231
232#define UTMIP_PLL_CFG2 0x488
233#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6)
234#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
235#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN (1 << 0)
236#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN (1 << 2)
237#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN (1 << 4)
238
239#define UTMIP_PLL_CFG1 0x484
240#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
241#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
242#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN (1 << 14)
243#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN (1 << 12)
244#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN (1 << 16)
245
246#define PLLE_BASE_CML_ENABLE (1<<31)
247#define PLLE_BASE_ENABLE (1<<30)
248#define PLLE_BASE_DIVCML_SHIFT 24
249#define PLLE_BASE_DIVCML_MASK (0xf<<PLLE_BASE_DIVCML_SHIFT)
250#define PLLE_BASE_DIVP_SHIFT 16
251#define PLLE_BASE_DIVP_MASK (0x3f<<PLLE_BASE_DIVP_SHIFT)
252#define PLLE_BASE_DIVN_SHIFT 8
253#define PLLE_BASE_DIVN_MASK (0xFF<<PLLE_BASE_DIVN_SHIFT)
254#define PLLE_BASE_DIVM_SHIFT 0
255#define PLLE_BASE_DIVM_MASK (0xFF<<PLLE_BASE_DIVM_SHIFT)
256#define PLLE_BASE_DIV_MASK \
257 (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \
258 PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK)
259#define PLLE_BASE_DIV(m, n, p, cml) \
260 (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \
261 ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT))
262
263#define PLLE_MISC_SETUP_BASE_SHIFT 16
264#define PLLE_MISC_SETUP_BASE_MASK (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT)
265#define PLLE_MISC_READY (1<<15)
266#define PLLE_MISC_LOCK (1<<11)
267#define PLLE_MISC_LOCK_ENABLE (1<<9)
268#define PLLE_MISC_SETUP_EX_SHIFT 2
269#define PLLE_MISC_SETUP_EX_MASK (0x3<<PLLE_MISC_SETUP_EX_SHIFT)
270#define PLLE_MISC_SETUP_MASK \
271 (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK)
272#define PLLE_MISC_SETUP_VALUE \
273 ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT))
274
275#define PLLE_SS_CTRL 0x68
276#define PLLE_SS_INCINTRV_SHIFT 24
277#define PLLE_SS_INCINTRV_MASK (0x3f<<PLLE_SS_INCINTRV_SHIFT)
278#define PLLE_SS_INC_SHIFT 16
279#define PLLE_SS_INC_MASK (0xff<<PLLE_SS_INC_SHIFT)
280#define PLLE_SS_MAX_SHIFT 0
281#define PLLE_SS_MAX_MASK (0x1ff<<PLLE_SS_MAX_SHIFT)
282#define PLLE_SS_COEFFICIENTS_MASK \
283 (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
284#define PLLE_SS_COEFFICIENTS_12MHZ \
285 ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
286 (0x24<<PLLE_SS_MAX_SHIFT))
287#define PLLE_SS_DISABLE ((1<<12) | (1<<11) | (1<<10))
288
289#define PLLE_AUX 0x48c
290#define PLLE_AUX_PLLP_SEL (1<<2)
291#define PLLE_AUX_CML_SATA_ENABLE (1<<1)
292#define PLLE_AUX_CML_PCIE_ENABLE (1<<0)
293
294#define PMC_SATA_PWRGT 0x1ac
295#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5)
296#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4)
297
298#define ROUND_DIVIDER_UP 0
299#define ROUND_DIVIDER_DOWN 1
300
301/* PLLP default fixed rate in h/w controlled mode */
302#define PLLP_DEFAULT_FIXED_RATE 216000000
303
304/* Threshold to engage CPU clock skipper during CPU rate change */
305#define SKIPPER_ENGAGE_RATE 800000000
306
307static void tegra3_pllp_init_dependencies(unsigned long pllp_rate);
308static int tegra3_clk_shared_bus_update(struct clk *bus);
309
310static unsigned long cpu_stay_on_backup_max;
311static struct clk *emc_bridge;
312
313static bool detach_shared_bus;
314module_param(detach_shared_bus, bool, 0644);
315
316static int skipper_delay = 10;
317module_param(skipper_delay, int, 0644);
318
319void tegra3_set_cpu_skipper_delay(int delay)
320{
321 skipper_delay = delay;
322}
323
324/**
325* Structure defining the fields for USB UTMI clocks Parameters.
326*/
327struct utmi_clk_param
328{
329 /* Oscillator Frequency in KHz */
330 u32 osc_frequency;
331 /* UTMIP PLL Enable Delay Count */
332 u8 enable_delay_count;
333 /* UTMIP PLL Stable count */
334 u8 stable_count;
335 /* UTMIP PLL Active delay count */
336 u8 active_delay_count;
337 /* UTMIP PLL Xtal frequency count */
338 u8 xtal_freq_count;
339};
340
341static const struct utmi_clk_param utmi_parameters[] =
342{
343/* OSC_FREQUENCY, ENABLE_DLY, STABLE_CNT, ACTIVE_DLY, XTAL_FREQ_CNT */
344 {13000000, 0x02, 0x33, 0x05, 0x7F},
345 {19200000, 0x03, 0x4B, 0x06, 0xBB},
346 {12000000, 0x02, 0x2F, 0x04, 0x76},
347 {26000000, 0x04, 0x66, 0x09, 0xFE},
348 {16800000, 0x03, 0x41, 0x0A, 0xA4},
349};
350
351static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
352static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
353static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
354
355#define MISC_GP_HIDREV 0x804
356
357/*
358 * Some peripheral clocks share an enable bit, so refcount the enable bits
359 * in registers CLK_ENABLE_L, ... CLK_ENABLE_W, and protect refcount updates
360 * with lock
361 */
362static DEFINE_SPINLOCK(periph_refcount_lock);
363static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
364
365#define clk_writel(value, reg) \
366 __raw_writel(value, (u32)reg_clk_base + (reg))
367#define clk_readl(reg) \
368 __raw_readl((u32)reg_clk_base + (reg))
369#define pmc_writel(value, reg) \
370 __raw_writel(value, (u32)reg_pmc_base + (reg))
371#define pmc_readl(reg) \
372 __raw_readl((u32)reg_pmc_base + (reg))
373#define chipid_readl() \
374 __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
375
376#define clk_writel_delay(value, reg) \
377 do { \
378 __raw_writel((value), (u32)reg_clk_base + (reg)); \
379 udelay(2); \
380 } while (0)
381
382
383static inline int clk_set_div(struct clk *c, u32 n)
384{
385 return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
386}
387
388static inline u32 periph_clk_to_reg(
389 struct clk *c, u32 reg_L, u32 reg_V, int offs)
390{
391 u32 reg = c->u.periph.clk_num / 32;
392 BUG_ON(reg >= RST_DEVICES_NUM);
393 if (reg < 3) {
394 reg = reg_L + (reg * offs);
395 } else {
396 reg = reg_V + ((reg - 3) * offs);
397 }
398 return reg;
399}
400
401static int clk_div_x1_get_divider(unsigned long parent_rate, unsigned long rate,
402 u32 max_x, u32 flags, u32 round_mode)
403{
404 s64 divider_ux1 = parent_rate;
405 if (!rate)
406 return -EINVAL;
407
408 if (!(flags & DIV_U71_INT))
409 divider_ux1 *= 2;
410
411 if (round_mode == ROUND_DIVIDER_UP)
412 divider_ux1 += rate - 1;
413 do_div(divider_ux1, rate);
414
415 if (flags & DIV_U71_INT)
416 divider_ux1 *= 2;
417
418 if (divider_ux1 - 2 < 0)
419 return 0;
420
421 if (divider_ux1 - 2 > max_x)
422 return -EINVAL;
423
424 return divider_ux1 - 2;
425}
426
427static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate,
428 u32 flags, u32 round_mode)
429{
430 return clk_div_x1_get_divider(parent_rate, rate, 0xFF,
431 flags, round_mode);
432}
433
434static int clk_div151_get_divider(unsigned long parent_rate, unsigned long rate,
435 u32 flags, u32 round_mode)
436{
437 return clk_div_x1_get_divider(parent_rate, rate, 0xFFFF,
438 flags, round_mode);
439}
440
441static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
442{
443 s64 divider_u16;
444
445 divider_u16 = parent_rate;
446 if (!rate)
447 return -EINVAL;
448 divider_u16 += rate - 1;
449 do_div(divider_u16, rate);
450
451 if (divider_u16 - 1 < 0)
452 return 0;
453
454 if (divider_u16 - 1 > 0xFFFF)
455 return -EINVAL;
456
457 return divider_u16 - 1;
458}
459
460/* clk_m functions */
461static unsigned long tegra3_clk_m_autodetect_rate(struct clk *c)
462{
463 u32 osc_ctrl = clk_readl(OSC_CTRL);
464 u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
465 u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
466
467 c->rate = tegra_clk_measure_input_freq();
468 switch (c->rate) {
469 case 12000000:
470 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
471 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
472 break;
473 case 13000000:
474 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
475 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
476 break;
477 case 19200000:
478 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
479 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
480 break;
481 case 26000000:
482 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
483 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
484 break;
485 case 16800000:
486 auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ;
487 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
488 break;
489 case 38400000:
490 auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ;
491 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
492 break;
493 case 48000000:
494 auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ;
495 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
496 break;
497 default:
498 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
499 BUG();
500 }
501 clk_writel(auto_clock_control, OSC_CTRL);
502 return c->rate;
503}
504
505static void tegra3_clk_m_init(struct clk *c)
506{
507 pr_debug("%s on clock %s\n", __func__, c->name);
508 tegra3_clk_m_autodetect_rate(c);
509}
510
511static int tegra3_clk_m_enable(struct clk *c)
512{
513 pr_debug("%s on clock %s\n", __func__, c->name);
514 return 0;
515}
516
517static void tegra3_clk_m_disable(struct clk *c)
518{
519 pr_debug("%s on clock %s\n", __func__, c->name);
520 WARN(1, "Attempting to disable main SoC clock\n");
521}
522
523static struct clk_ops tegra_clk_m_ops = {
524 .init = tegra3_clk_m_init,
525 .enable = tegra3_clk_m_enable,
526 .disable = tegra3_clk_m_disable,
527};
528
529static struct clk_ops tegra_clk_m_div_ops = {
530 .enable = tegra3_clk_m_enable,
531};
532
533/* PLL reference divider functions */
534static void tegra3_pll_ref_init(struct clk *c)
535{
536 u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
537 pr_debug("%s on clock %s\n", __func__, c->name);
538
539 switch (pll_ref_div) {
540 case OSC_CTRL_PLL_REF_DIV_1:
541 c->div = 1;
542 break;
543 case OSC_CTRL_PLL_REF_DIV_2:
544 c->div = 2;
545 break;
546 case OSC_CTRL_PLL_REF_DIV_4:
547 c->div = 4;
548 break;
549 default:
550 pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div);
551 BUG();
552 }
553 c->mul = 1;
554 c->state = ON;
555}
556
557static struct clk_ops tegra_pll_ref_ops = {
558 .init = tegra3_pll_ref_init,
559 .enable = tegra3_clk_m_enable,
560 .disable = tegra3_clk_m_disable,
561};
562
563/* super clock functions */
564/* "super clocks" on tegra3 have two-stage muxes, fractional 7.1 divider and
565 * clock skipping super divider. We will ignore the clock skipping divider,
566 * since we can't lower the voltage when using the clock skip, but we can if
567 * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock
568 * only when its parent is a fixed rate PLL, since we can't change PLL rate
569 * in this case.
570 */
571static void tegra3_super_clk_init(struct clk *c)
572{
573 u32 val;
574 int source;
575 int shift;
576 const struct clk_mux_sel *sel;
577
578 val = clk_readl(c->reg + SUPER_CLK_MUX);
579 c->state = ON;
580 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
581 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
582 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
583 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
584 source = (val >> shift) & SUPER_SOURCE_MASK;
585 if (c->flags & DIV_2)
586 source |= val & SUPER_LP_DIV2_BYPASS;
587 for (sel = c->inputs; sel->input != NULL; sel++) {
588 if (sel->value == source)
589 break;
590 }
591 BUG_ON(sel->input == NULL);
592 c->parent = sel->input;
593
594 if (c->flags & DIV_U71) {
595 /* Init safe 7.1 divider value (does not affect PLLX path).
596 Super skipper is enabled to be ready for emergency throttle,
597 but set 1:1 */
598 c->mul = 2;
599 c->div = 2;
600 if (!(c->parent->flags & PLLX)) {
601 val = clk_readl(c->reg + SUPER_CLK_DIVIDER);
602 val &= SUPER_CLOCK_DIV_U71_MASK;
603 val >>= SUPER_CLOCK_DIV_U71_SHIFT;
604 val = max(val, c->u.cclk.div71);
605 c->u.cclk.div71 = val;
606 c->div += val;
607 }
608 val = SUPER_CLOCK_SKIP_ENABLE +
609 (c->u.cclk.div71 << SUPER_CLOCK_DIV_U71_SHIFT);
610 clk_writel(val, c->reg + SUPER_CLK_DIVIDER);
611 }
612 else
613 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
614}
615
616static int tegra3_super_clk_enable(struct clk *c)
617{
618 return 0;
619}
620
621static void tegra3_super_clk_disable(struct clk *c)
622{
623 /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and
624 geared up g-mode super clock - mode switch may request to disable
625 either of them; accept request with no affect on h/w */
626}
627
628static int tegra3_super_clk_set_parent(struct clk *c, struct clk *p)
629{
630 u32 val;
631 const struct clk_mux_sel *sel;
632 int shift;
633
634 val = clk_readl(c->reg + SUPER_CLK_MUX);;
635 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
636 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
637 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
638 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
639 for (sel = c->inputs; sel->input != NULL; sel++) {
640 if (sel->input == p) {
641 /* For LP mode super-clock switch between PLLX direct
642 and divided-by-2 outputs is allowed only when other
643 than PLLX clock source is current parent */
644 if ((c->flags & DIV_2) && (p->flags & PLLX) &&
645 ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) {
646 if (c->parent->flags & PLLX)
647 return -EINVAL;
648 val ^= SUPER_LP_DIV2_BYPASS;
649 clk_writel_delay(val, c->reg);
650 }
651 val &= ~(SUPER_SOURCE_MASK << shift);
652 val |= (sel->value & SUPER_SOURCE_MASK) << shift;
653
654 /* 7.1 divider for CPU super-clock does not affect
655 PLLX path */
656 if (c->flags & DIV_U71) {
657 u32 div = 0;
658 if (!(p->flags & PLLX)) {
659 div = clk_readl(c->reg +
660 SUPER_CLK_DIVIDER);
661 div &= SUPER_CLOCK_DIV_U71_MASK;
662 div >>= SUPER_CLOCK_DIV_U71_SHIFT;
663 }
664 c->div = div + 2;
665 c->mul = 2;
666 }
667
668 if (c->refcnt)
669 clk_enable(p);
670
671 clk_writel_delay(val, c->reg);
672
673 if (c->refcnt && c->parent)
674 clk_disable(c->parent);
675
676 clk_reparent(c, p);
677 return 0;
678 }
679 }
680 return -EINVAL;
681}
682
683static DEFINE_SPINLOCK(super_divider_lock);
684
685static void tegra3_super_clk_divider_update(struct clk *c, u8 div)
686{
687 u32 val;
688 unsigned long flags;
689
690 spin_lock_irqsave(&super_divider_lock, flags);
691 val = clk_readl(c->reg + SUPER_CLK_DIVIDER);
692 val &= ~SUPER_CLOCK_DIV_U71_MASK;
693 val |= div << SUPER_CLOCK_DIV_U71_SHIFT;
694 clk_writel(val, c->reg + SUPER_CLK_DIVIDER);
695 spin_unlock_irqrestore(&super_divider_lock, flags);
696 udelay(2);
697}
698
699static void tegra3_super_clk_skipper_update(struct clk *c, u8 mul, u8 div)
700{
701 u32 val;
702 unsigned long flags;
703
704 spin_lock_irqsave(&super_divider_lock, flags);
705 val = clk_readl(c->reg + SUPER_CLK_DIVIDER);
706
707 /* multiplier or divider value = the respective field + 1 */
708 if (mul && div) {
709 u32 old_mul = ((val & SUPER_CLOCK_SKIP_MUL_MASK) >>
710 SUPER_CLOCK_SKIP_MUL_SHIFT) + 1;
711 u32 old_div = ((val & SUPER_CLOCK_SKIP_DIV_MASK) >>
712 SUPER_CLOCK_SKIP_DIV_SHIFT) + 1;
713
714 if (mul >= div) {
715 /* improper fraction is only used to reciprocate the
716 previous proper one - the division below is exact */
717 old_mul /= div;
718 old_div /= mul;
719 } else {
720 old_mul *= mul;
721 old_div *= div;
722 }
723 mul = (old_mul <= SUPER_CLOCK_SKIP_TERM_MAX) ?
724 old_mul : SUPER_CLOCK_SKIP_TERM_MAX;
725 div = (old_div <= SUPER_CLOCK_SKIP_TERM_MAX) ?
726 old_div : SUPER_CLOCK_SKIP_TERM_MAX;
727 }
728
729 if (!mul || (mul >= div)) {
730 mul = 1;
731 div = 1;
732 }
733 val &= ~SUPER_CLOCK_SKIP_MASK;
734 val |= SUPER_CLOCK_SKIP_ENABLE |
735 ((mul - 1) << SUPER_CLOCK_SKIP_MUL_SHIFT) |
736 ((div - 1) << SUPER_CLOCK_SKIP_DIV_SHIFT);
737
738 clk_writel(val, c->reg + SUPER_CLK_DIVIDER);
739 spin_unlock_irqrestore(&super_divider_lock, flags);
740}
741
742/*
743 * Do not use super clocks "skippers", since dividing using a clock skipper
744 * does not allow the voltage to be scaled down. Instead adjust the rate of
745 * the parent clock. This requires that the parent of a super clock have no
746 * other children, otherwise the rate will change underneath the other
747 * children. Special case: if fixed rate PLL is CPU super clock parent the
748 * rate of this PLL can't be changed, and it has many other children. In
749 * this case use 7.1 fractional divider to adjust the super clock rate.
750 */
751static int tegra3_super_clk_set_rate(struct clk *c, unsigned long rate)
752{
753 if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) {
754 int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate,
755 rate, c->flags, ROUND_DIVIDER_DOWN);
756 if (div < 0)
757 return div;
758
759 tegra3_super_clk_divider_update(c, div);
760 c->u.cclk.div71 = div;
761 c->div = div + 2;
762 c->mul = 2;
763 return 0;
764 }
765 return clk_set_rate(c->parent, rate);
766}
767
768static struct clk_ops tegra_super_ops = {
769 .init = tegra3_super_clk_init,
770 .enable = tegra3_super_clk_enable,
771 .disable = tegra3_super_clk_disable,
772 .set_parent = tegra3_super_clk_set_parent,
773 .set_rate = tegra3_super_clk_set_rate,
774};
775
776static int tegra3_twd_clk_set_rate(struct clk *c, unsigned long rate)
777{
778 /* The input value 'rate' is the clock rate of the CPU complex. */
779 c->rate = (rate * c->mul) / c->div;
780 return 0;
781}
782
783static struct clk_ops tegra3_twd_ops = {
784 .set_rate = tegra3_twd_clk_set_rate,
785};
786
787static struct clk tegra3_clk_twd = {
788 /* NOTE: The twd clock must have *NO* parent. It's rate is directly
789 updated by tegra3_cpu_cmplx_clk_set_rate() because the
790 frequency change notifer for the twd is called in an
791 atomic context which cannot take a mutex. */
792 .name = "twd",
793 .ops = &tegra3_twd_ops,
794 .max_rate = 1400000000, /* Same as tegra_clk_cpu_cmplx.max_rate */
795 .mul = 1,
796 .div = 2,
797};
798
799/* virtual cpu clock functions */
800/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
801 To change the frequency of these clocks, the parent pll may need to be
802 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
803 and then the clock moved back to the pll. Clock skipper maybe temporarily
804 engaged during the switch to limit frequency jumps. To hide this sequence,
805 a virtual clock handles it.
806 */
807static void tegra3_cpu_clk_init(struct clk *c)
808{
809 c->state = (!is_lp_cluster() == (c->u.cpu.mode == MODE_G))? ON : OFF;
810}
811
812static int tegra3_cpu_clk_enable(struct clk *c)
813{
814 return 0;
815}
816
817static void tegra3_cpu_clk_disable(struct clk *c)
818{
819 /* since tegra 3 has 2 virtual CPU clocks - low power lp-mode clock
820 and geared up g-mode clock - mode switch may request to disable
821 either of them; accept request with no affect on h/w */
822}
823
824static int tegra3_cpu_clk_set_rate(struct clk *c, unsigned long rate)
825{
826 int ret = 0;
827 bool skipped = false;
828 bool skip = (c->u.cpu.mode == MODE_G) && skipper_delay;
829 bool skip_from_backup = skip && (rate >= SKIPPER_ENGAGE_RATE);
830 bool skip_to_backup =
831 skip && (clk_get_rate_all_locked(c) >= SKIPPER_ENGAGE_RATE);
832
833 /* Hardware clock control is not possible on FPGA platforms.
834 Report success so that upper level layers don't complain
835 needlessly. */
836#ifndef CONFIG_TEGRA_FPGA_PLATFORM
837 if (c->dvfs) {
838 if (!c->dvfs->dvfs_rail)
839 return -ENOSYS;
840 else if ((!c->dvfs->dvfs_rail->reg) &&
841 (clk_get_rate_locked(c) < rate)) {
842 WARN(1, "Increasing CPU rate while regulator is not"
843 " ready may overclock CPU\n");
844 return -ENOSYS;
845 }
846 }
847
848 /*
849 * Take an extra reference to the main pll so it doesn't turn
850 * off when we move the cpu off of it
851 */
852 clk_enable(c->u.cpu.main);
853
854 if (c->parent->parent != c->u.cpu.backup) {
855 if (skip_to_backup) {
856 /* on G CPU use 1/2 skipper step for main <=> backup */
857 skipped = true;
858 tegra3_super_clk_skipper_update(c->parent, 1, 2);
859 udelay(skipper_delay);
860 }
861
862 ret = clk_set_parent(c->parent, c->u.cpu.backup);
863 if (ret) {
864 pr_err("Failed to switch cpu to clock %s\n",
865 c->u.cpu.backup->name);
866 goto out;
867 }
868
869 if (skipped && !skip_from_backup) {
870 skipped = false;
871 tegra3_super_clk_skipper_update(c->parent, 2, 1);
872 }
873 }
874
875 if (rate <= cpu_stay_on_backup_max) {
876 ret = clk_set_rate(c->parent, rate);
877 if (ret)
878 pr_err("Failed to set cpu rate %lu on backup source\n",
879 rate);
880 goto out;
881 } else {
882 ret = clk_set_rate(c->parent, c->u.cpu.backup_rate);
883 if (ret) {
884 pr_err("Failed to set cpu rate %lu on backup source\n",
885 c->u.cpu.backup_rate);
886 goto out;
887 }
888 }
889
890 if (rate != clk_get_rate(c->u.cpu.main)) {
891 ret = clk_set_rate(c->u.cpu.main, rate);
892 if (ret) {
893 pr_err("Failed to change cpu pll to %lu\n", rate);
894 goto out;
895 }
896 }
897
898 if (!skipped && skip_from_backup) {
899 skipped = true;
900 tegra3_super_clk_skipper_update(c->parent, 1, 2);
901 }
902
903 ret = clk_set_parent(c->parent, c->u.cpu.main);
904 if (ret) {
905 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
906 goto out;
907 }
908
909out:
910 if (skipped) {
911 udelay(skipper_delay);
912 tegra3_super_clk_skipper_update(c->parent, 2, 1);
913 }
914 clk_disable(c->u.cpu.main);
915#endif
916 return ret;
917}
918
919static struct clk_ops tegra_cpu_ops = {
920 .init = tegra3_cpu_clk_init,
921 .enable = tegra3_cpu_clk_enable,
922 .disable = tegra3_cpu_clk_disable,
923 .set_rate = tegra3_cpu_clk_set_rate,
924};
925
926
927static void tegra3_cpu_cmplx_clk_init(struct clk *c)
928{
929 int i = !!is_lp_cluster();
930
931 BUG_ON(c->inputs[0].input->u.cpu.mode != MODE_G);
932 BUG_ON(c->inputs[1].input->u.cpu.mode != MODE_LP);
933 c->parent = c->inputs[i].input;
934}
935
936/* cpu complex clock provides second level vitualization (on top of
937 cpu virtual cpu rate control) in order to hide the CPU mode switch
938 sequence */
939#if PARAMETERIZE_CLUSTER_SWITCH
940static unsigned int switch_delay;
941static unsigned int switch_flags;
942static DEFINE_SPINLOCK(parameters_lock);
943
944void tegra_cluster_switch_set_parameters(unsigned int us, unsigned int flags)
945{
946 spin_lock(&parameters_lock);
947 switch_delay = us;
948 switch_flags = flags;
949 spin_unlock(&parameters_lock);
950}
951#endif
952
953static int tegra3_cpu_cmplx_clk_enable(struct clk *c)
954{
955 return 0;
956}
957
958static void tegra3_cpu_cmplx_clk_disable(struct clk *c)
959{
960 pr_debug("%s on clock %s\n", __func__, c->name);
961
962 /* oops - don't disable the CPU complex clock! */
963 BUG();
964}
965
966static int tegra3_cpu_cmplx_clk_set_rate(struct clk *c, unsigned long rate)
967{
968 unsigned long flags;
969 int ret;
970 struct clk *parent = c->parent;
971
972 if (!parent->ops || !parent->ops->set_rate)
973 return -ENOSYS;
974
975 clk_lock_save(parent, &flags);
976
977 ret = clk_set_rate_locked(parent, rate);
978
979 /* We can't parent the twd to directly to the CPU complex because
980 the TWD frequency update notifier is called in an atomic context
981 and the CPU frequency update requires a mutex. Update the twd
982 clock rate with the new CPU complex rate. */
983 clk_set_rate(&tegra3_clk_twd, clk_get_rate_locked(parent));
984
985 clk_unlock_restore(parent, &flags);
986
987 return ret;
988}
989
990static int tegra3_cpu_cmplx_clk_set_parent(struct clk *c, struct clk *p)
991{
992 int ret;
993 unsigned int flags, delay;
994 const struct clk_mux_sel *sel;
995 unsigned long rate = clk_get_rate(c->parent);
996
997 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
998 BUG_ON(c->parent->u.cpu.mode != (is_lp_cluster() ? MODE_LP : MODE_G));
999
1000 for (sel = c->inputs; sel->input != NULL; sel++) {
1001 if (sel->input == p)
1002 break;
1003 }
1004 if (!sel->input)
1005 return -EINVAL;
1006
1007#if PARAMETERIZE_CLUSTER_SWITCH
1008 spin_lock(&parameters_lock);
1009 flags = switch_flags;
1010 delay = switch_delay;
1011 switch_flags = 0;
1012 spin_unlock(&parameters_lock);
1013
1014 if (flags) {
1015 /* over/under-clocking after switch - allow, but update rate */
1016 if ((rate > p->max_rate) || (rate < p->min_rate)) {
1017 unsigned long fl;
1018
1019 rate = rate > p->max_rate ? p->max_rate : p->min_rate;
1020 ret = clk_set_rate(c->parent, rate);
1021 if (ret) {
1022 pr_err("%s: Failed to set rate %lu for %s\n",
1023 __func__, rate, p->name);
1024 return ret;
1025 }
1026 clk_lock_save(c->parent, &fl);
1027 clk_set_rate(&tegra3_clk_twd,
1028 clk_get_rate_locked(c->parent));
1029 clk_unlock_restore(c->parent, &fl);
1030 }
1031 } else
1032#endif
1033 {
1034 if (p == c->parent) /* already switched - exit*/
1035 return 0;
1036
1037 if (rate > p->max_rate) { /* over-clocking - no switch */
1038 pr_warn("%s: No %s mode switch to %s at rate %lu\n",
1039 __func__, c->name, p->name, rate);
1040 return -ECANCELED;
1041 }
1042 flags = TEGRA_POWER_CLUSTER_IMMEDIATE;
1043 delay = 0;
1044 }
1045 flags |= (p->u.cpu.mode == MODE_LP) ? TEGRA_POWER_CLUSTER_LP :
1046 TEGRA_POWER_CLUSTER_G;
1047
1048 /* Since in both LP and G mode CPU main and backup sources are the
1049 same, set rate on the new parent just synchronizes super-clock
1050 muxes before mode switch with no PLL re-locking */
1051 ret = clk_set_rate(p, rate);
1052 if (ret) {
1053 pr_err("%s: Failed to set rate %lu for %s\n",
1054 __func__, rate, p->name);
1055 return ret;
1056 }
1057
1058 /* Enabling new parent scales new mode voltage rail in advanvce
1059 before the switch happens*/
1060 if (c->refcnt)
1061 clk_enable(p);
1062
1063 /* switch CPU mode */
1064 ret = tegra_cluster_control(delay, flags);
1065 if (ret) {
1066 if (c->refcnt)
1067 clk_disable(p);
1068 pr_err("%s: Failed to switch %s mode to %s\n",
1069 __func__, c->name, p->name);
1070 return ret;
1071 }
1072
1073 /* Disabling old parent scales old mode voltage rail */
1074 if (c->refcnt && c->parent)
1075 clk_disable(c->parent);
1076
1077 clk_reparent(c, p);
1078 return 0;
1079}
1080
1081static long tegra3_cpu_cmplx_round_rate(struct clk *c,
1082 unsigned long rate)
1083{
1084 if (rate > c->parent->max_rate)
1085 rate = c->parent->max_rate;
1086 else if (rate < c->parent->min_rate)
1087 rate = c->parent->min_rate;
1088 return rate;
1089}
1090
1091static struct clk_ops tegra_cpu_cmplx_ops = {
1092 .init = tegra3_cpu_cmplx_clk_init,
1093 .enable = tegra3_cpu_cmplx_clk_enable,
1094 .disable = tegra3_cpu_cmplx_clk_disable,
1095 .set_rate = tegra3_cpu_cmplx_clk_set_rate,
1096 .set_parent = tegra3_cpu_cmplx_clk_set_parent,
1097 .round_rate = tegra3_cpu_cmplx_round_rate,
1098};
1099
1100/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
1101 * reset the COP block (i.e. AVP) */
1102static void tegra3_cop_clk_reset(struct clk *c, bool assert)
1103{
1104 unsigned long reg = assert ? RST_DEVICES_SET_L : RST_DEVICES_CLR_L;
1105
1106 pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
1107 clk_writel(1 << 1, reg);
1108}
1109
1110static struct clk_ops tegra_cop_ops = {
1111 .reset = tegra3_cop_clk_reset,
1112};
1113
1114/* bus clock functions */
1115static void tegra3_bus_clk_init(struct clk *c)
1116{
1117 u32 val = clk_readl(c->reg);
1118 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
1119 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
1120 c->mul = 1;
1121}
1122
1123static int tegra3_bus_clk_enable(struct clk *c)
1124{
1125 u32 val = clk_readl(c->reg);
1126 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
1127 clk_writel(val, c->reg);
1128 return 0;
1129}
1130
1131static void tegra3_bus_clk_disable(struct clk *c)
1132{
1133 u32 val = clk_readl(c->reg);
1134 val |= BUS_CLK_DISABLE << c->reg_shift;
1135 clk_writel(val, c->reg);
1136}
1137
1138static int tegra3_bus_clk_set_rate(struct clk *c, unsigned long rate)
1139{
1140 u32 val = clk_readl(c->reg);
1141 unsigned long parent_rate = clk_get_rate(c->parent);
1142 int i;
1143 for (i = 1; i <= 4; i++) {
1144 if (rate >= parent_rate / i) {
1145 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
1146 val |= (i - 1) << c->reg_shift;
1147 clk_writel(val, c->reg);
1148 c->div = i;
1149 c->mul = 1;
1150 return 0;
1151 }
1152 }
1153 return -EINVAL;
1154}
1155
1156static struct clk_ops tegra_bus_ops = {
1157 .init = tegra3_bus_clk_init,
1158 .enable = tegra3_bus_clk_enable,
1159 .disable = tegra3_bus_clk_disable,
1160 .set_rate = tegra3_bus_clk_set_rate,
1161};
1162
1163/* Virtual system bus complex clock is used to hide the sequence of
1164 changing sclk/hclk/pclk parents and dividers to configure requested
1165 sclk target rate. */
1166static void tegra3_sbus_cmplx_init(struct clk *c)
1167{
1168 unsigned long rate;
1169
1170 c->max_rate = c->parent->max_rate;
1171 c->min_rate = c->parent->min_rate;
1172
1173 /* Threshold must be an exact proper factor of low range parent,
1174 and both low/high range parents have 7.1 fractional dividers */
1175 rate = clk_get_rate(c->u.system.sclk_low->parent);
1176 if (c->u.system.threshold) {
1177 BUG_ON(c->u.system.threshold > rate) ;
1178 BUG_ON((rate % c->u.system.threshold) != 0);
1179 }
1180 BUG_ON(!(c->u.system.sclk_low->flags & DIV_U71));
1181 BUG_ON(!(c->u.system.sclk_high->flags & DIV_U71));
1182}
1183
1184/* This special sbus round function is implemented because:
1185 *
1186 * (a) fractional dividers can not be used to derive system bus clock with one
1187 * exception: 1 : 2.5 divider is allowed at 1.2V and above (and we do need this
1188 * divider to reach top sbus frequencies from high frequency source).
1189 *
1190 * (b) since sbus is a shared bus, and its frequency is set to the highest
1191 * enabled shared_bus_user clock, the target rate should be rounded up divider
1192 * ladder (if max limit allows it) - for pll_div and peripheral_div common is
1193 * rounding down - special case again.
1194 *
1195 * Note that final rate is trimmed (not rounded up) to avoid spiraling up in
1196 * recursive calls. Lost 1Hz is added in tegra3_sbus_cmplx_set_rate before
1197 * actually setting divider rate.
1198 */
1199static unsigned long sclk_high_2_5_rate;
1200static bool sclk_high_2_5_valid;
1201
1202static long tegra3_sbus_cmplx_round_rate(struct clk *c, unsigned long rate)
1203{
1204 int i, divider;
1205 unsigned long source_rate, round_rate;
1206 struct clk *new_parent;
1207
1208 rate = max(rate, c->min_rate);
1209
1210 if (!sclk_high_2_5_rate) {
1211 source_rate = clk_get_rate(c->u.system.sclk_high->parent);
1212 sclk_high_2_5_rate = 2 * source_rate / 5;
1213 i = tegra_dvfs_predict_millivolts(c, sclk_high_2_5_rate);
1214 if (!IS_ERR_VALUE(i) && (i >= 1200) &&
1215 (sclk_high_2_5_rate <= c->max_rate))
1216 sclk_high_2_5_valid = true;
1217 }
1218
1219 new_parent = (rate <= c->u.system.threshold) ?
1220 c->u.system.sclk_low : c->u.system.sclk_high;
1221 source_rate = clk_get_rate(new_parent->parent);
1222
1223 divider = clk_div71_get_divider(source_rate, rate,
1224 new_parent->flags | DIV_U71_INT, ROUND_DIVIDER_DOWN);
1225 if (divider < 0)
1226 return divider;
1227
1228 round_rate = source_rate * 2 / (divider + 2);
1229 if (round_rate > c->max_rate) {
1230 divider += 2;
1231 round_rate = source_rate * 2 / (divider + 2);
1232 }
1233
1234 if (new_parent == c->u.system.sclk_high) {
1235 /* Check if 1 : 2.5 ratio provides better approximation */
1236 if (sclk_high_2_5_valid) {
1237 if (((sclk_high_2_5_rate < round_rate) &&
1238 (sclk_high_2_5_rate >= rate)) ||
1239 ((round_rate < sclk_high_2_5_rate) &&
1240 (round_rate < rate)))
1241 round_rate = sclk_high_2_5_rate;
1242 }
1243
1244 if (round_rate <= c->u.system.threshold)
1245 round_rate = c->u.system.threshold;
1246 }
1247 return round_rate;
1248}
1249
1250static int tegra3_sbus_cmplx_set_rate(struct clk *c, unsigned long rate)
1251{
1252 int ret;
1253 struct clk *new_parent;
1254
1255 /* - select the appropriate sclk parent
1256 - keep hclk at the same rate as sclk
1257 - set pclk at 1:2 rate of hclk unless pclk minimum is violated,
1258 in the latter case switch to 1:1 ratio */
1259
1260 if (rate >= c->u.system.pclk->min_rate * 2) {
1261 ret = clk_set_div(c->u.system.pclk, 2);
1262 if (ret) {
1263 pr_err("Failed to set 1 : 2 pclk divider\n");
1264 return ret;
1265 }
1266 }
1267
1268 new_parent = (rate <= c->u.system.threshold) ?
1269 c->u.system.sclk_low : c->u.system.sclk_high;
1270
1271 ret = clk_set_rate(new_parent, rate + 1);
1272 if (ret) {
1273 pr_err("Failed to set sclk source %s to %lu\n",
1274 new_parent->name, rate);
1275 return ret;
1276 }
1277
1278 if (new_parent != clk_get_parent(c->parent)) {
1279 ret = clk_set_parent(c->parent, new_parent);
1280 if (ret) {
1281 pr_err("Failed to switch sclk source to %s\n",
1282 new_parent->name);
1283 return ret;
1284 }
1285 }
1286
1287 if (rate < c->u.system.pclk->min_rate * 2) {
1288 ret = clk_set_div(c->u.system.pclk, 1);
1289 if (ret) {
1290 pr_err("Failed to set 1 : 1 pclk divider\n");
1291 return ret;
1292 }
1293 }
1294
1295 return 0;
1296}
1297
1298static struct clk_ops tegra_sbus_cmplx_ops = {
1299 .init = tegra3_sbus_cmplx_init,
1300 .set_rate = tegra3_sbus_cmplx_set_rate,
1301 .round_rate = tegra3_sbus_cmplx_round_rate,
1302 .shared_bus_update = tegra3_clk_shared_bus_update,
1303};
1304
1305/* Blink output functions */
1306
1307static void tegra3_blink_clk_init(struct clk *c)
1308{
1309 u32 val;
1310
1311 val = pmc_readl(PMC_CTRL);
1312 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
1313 c->mul = 1;
1314 val = pmc_readl(c->reg);
1315
1316 if (val & PMC_BLINK_TIMER_ENB) {
1317 unsigned int on_off;
1318
1319 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
1320 PMC_BLINK_TIMER_DATA_ON_MASK;
1321 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
1322 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
1323 on_off += val;
1324 /* each tick in the blink timer is 4 32KHz clocks */
1325 c->div = on_off * 4;
1326 } else {
1327 c->div = 1;
1328 }
1329}
1330
1331static int tegra3_blink_clk_enable(struct clk *c)
1332{
1333 u32 val;
1334
1335 val = pmc_readl(PMC_DPD_PADS_ORIDE);
1336 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
1337
1338 val = pmc_readl(PMC_CTRL);
1339 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
1340
1341 return 0;
1342}
1343
1344static void tegra3_blink_clk_disable(struct clk *c)
1345{
1346 u32 val;
1347
1348 val = pmc_readl(PMC_CTRL);
1349 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
1350
1351 val = pmc_readl(PMC_DPD_PADS_ORIDE);
1352 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
1353}
1354
1355static int tegra3_blink_clk_set_rate(struct clk *c, unsigned long rate)
1356{
1357 unsigned long parent_rate = clk_get_rate(c->parent);
1358 if (rate >= parent_rate) {
1359 c->div = 1;
1360 pmc_writel(0, c->reg);
1361 } else {
1362 unsigned int on_off;
1363 u32 val;
1364
1365 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
1366 c->div = on_off * 8;
1367
1368 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
1369 PMC_BLINK_TIMER_DATA_ON_SHIFT;
1370 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
1371 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
1372 val |= on_off;
1373 val |= PMC_BLINK_TIMER_ENB;
1374 pmc_writel(val, c->reg);
1375 }
1376
1377 return 0;
1378}
1379
1380static struct clk_ops tegra_blink_clk_ops = {
1381 .init = &tegra3_blink_clk_init,
1382 .enable = &tegra3_blink_clk_enable,
1383 .disable = &tegra3_blink_clk_disable,
1384 .set_rate = &tegra3_blink_clk_set_rate,
1385};
1386
1387/* PLL Functions */
1388static int tegra3_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg, u32 lock_bit)
1389{
1390#if USE_PLL_LOCK_BITS
1391 int i;
1392 for (i = 0; i < c->u.pll.lock_delay; i++) {
1393 if (clk_readl(lock_reg) & lock_bit) {
1394 udelay(PLL_POST_LOCK_DELAY);
1395 return 0;
1396 }
1397 udelay(2); /* timeout = 2 * lock time */
1398 }
1399 pr_err("Timed out waiting for lock bit on pll %s", c->name);
1400 return -1;
1401#endif
1402 udelay(c->u.pll.lock_delay);
1403
1404 return 0;
1405}
1406
1407
1408static void tegra3_utmi_param_configure(struct clk *c)
1409{
1410 u32 reg;
1411 int i;
1412 unsigned long main_rate =
1413 clk_get_rate(c->parent->parent);
1414
1415 for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
1416 if (main_rate == utmi_parameters[i].osc_frequency) {
1417 break;
1418 }
1419 }
1420
1421 if (i >= ARRAY_SIZE(utmi_parameters)) {
1422 pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate);
1423 return;
1424 }
1425
1426 reg = clk_readl(UTMIP_PLL_CFG2);
1427
1428 /* Program UTMIP PLL stable and active counts */
1429 /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
1430 reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
1431 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
1432 utmi_parameters[i].stable_count);
1433
1434 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
1435
1436 reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
1437 utmi_parameters[i].active_delay_count);
1438
1439 /* Remove power downs from UTMIP PLL control bits */
1440 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
1441 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
1442 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
1443
1444 clk_writel(reg, UTMIP_PLL_CFG2);
1445
1446 /* Program UTMIP PLL delay and oscillator frequency counts */
1447 reg = clk_readl(UTMIP_PLL_CFG1);
1448 reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
1449
1450 reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
1451 utmi_parameters[i].enable_delay_count);
1452
1453 reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
1454 reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
1455 utmi_parameters[i].xtal_freq_count);
1456
1457 /* Remove power downs from UTMIP PLL control bits */
1458 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
1459 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
1460 reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
1461
1462 clk_writel(reg, UTMIP_PLL_CFG1);
1463}
1464
1465static void tegra3_pll_clk_init(struct clk *c)
1466{
1467 u32 val = clk_readl(c->reg + PLL_BASE);
1468
1469 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
1470
1471 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
1472 const struct clk_pll_freq_table *sel;
1473 unsigned long input_rate = clk_get_rate(c->parent);
1474 c->u.pll.fixed_rate = PLLP_DEFAULT_FIXED_RATE;
1475
1476 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1477 if (sel->input_rate == input_rate &&
1478 sel->output_rate == c->u.pll.fixed_rate) {
1479 c->mul = sel->n;
1480 c->div = sel->m * sel->p;
1481 return;
1482 }
1483 }
1484 pr_err("Clock %s has unknown fixed frequency\n", c->name);
1485 BUG();
1486 } else if (val & PLL_BASE_BYPASS) {
1487 c->mul = 1;
1488 c->div = 1;
1489 } else {
1490 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
1491 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
1492 if (c->flags & PLLU)
1493 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
1494 else
1495 c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
1496 PLL_BASE_DIVP_SHIFT));
1497 }
1498
1499 if (c->flags & PLL_FIXED) {
1500 c->u.pll.fixed_rate = clk_get_rate_locked(c);
1501 }
1502
1503 if (c->flags & PLLU) {
1504 tegra3_utmi_param_configure(c);
1505 }
1506}
1507
1508static int tegra3_pll_clk_enable(struct clk *c)
1509{
1510 u32 val;
1511 pr_debug("%s on clock %s\n", __func__, c->name);
1512
1513#if USE_PLL_LOCK_BITS
1514 val = clk_readl(c->reg + PLL_MISC(c));
1515 val |= PLL_MISC_LOCK_ENABLE(c);
1516 clk_writel(val, c->reg + PLL_MISC(c));
1517#endif
1518 val = clk_readl(c->reg + PLL_BASE);
1519 val &= ~PLL_BASE_BYPASS;
1520 val |= PLL_BASE_ENABLE;
1521 clk_writel(val, c->reg + PLL_BASE);
1522
1523 if (c->flags & PLLM) {
1524 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
1525 val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
1526 pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
1527 }
1528
1529 tegra3_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK);
1530
1531 return 0;
1532}
1533
1534static void tegra3_pll_clk_disable(struct clk *c)
1535{
1536 u32 val;
1537 pr_debug("%s on clock %s\n", __func__, c->name);
1538
1539 val = clk_readl(c->reg);
1540 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
1541 clk_writel(val, c->reg);
1542
1543 if (c->flags & PLLM) {
1544 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
1545 val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
1546 pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
1547 }
1548}
1549
1550static int tegra3_pll_clk_set_rate(struct clk *c, unsigned long rate)
1551{
1552 u32 val, p_div, old_base;
1553 unsigned long input_rate;
1554 const struct clk_pll_freq_table *sel;
1555 struct clk_pll_freq_table cfg;
1556
1557 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1558
1559 if (c->flags & PLL_FIXED) {
1560 int ret = 0;
1561 if (rate != c->u.pll.fixed_rate) {
1562 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
1563 __func__, c->name, c->u.pll.fixed_rate, rate);
1564 ret = -EINVAL;
1565 }
1566 return ret;
1567 }
1568
1569 if (c->flags & PLLM) {
1570 if (rate != clk_get_rate_locked(c)) {
1571 pr_err("%s: Can not change memory %s rate in flight\n",
1572 __func__, c->name);
1573 return -EINVAL;
1574 }
1575 return 0;
1576 }
1577
1578 p_div = 0;
1579 input_rate = clk_get_rate(c->parent);
1580
1581 /* Check if the target rate is tabulated */
1582 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1583 if (sel->input_rate == input_rate && sel->output_rate == rate) {
1584 if (c->flags & PLLU) {
1585 BUG_ON(sel->p < 1 || sel->p > 2);
1586 if (sel->p == 1)
1587 p_div = PLLU_BASE_POST_DIV;
1588 } else {
1589 BUG_ON(sel->p < 1);
1590 for (val = sel->p; val > 1; val >>= 1, p_div++);
1591 p_div <<= PLL_BASE_DIVP_SHIFT;
1592 }
1593 break;
1594 }
1595 }
1596
1597 /* Configure out-of-table rate */
1598 if (sel->input_rate == 0) {
1599 unsigned long cfreq;
1600 BUG_ON(c->flags & PLLU);
1601 sel = &cfg;
1602
1603 switch (input_rate) {
1604 case 12000000:
1605 case 26000000:
1606 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
1607 break;
1608 case 13000000:
1609 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
1610 break;
1611 case 16800000:
1612 case 19200000:
1613 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
1614 break;
1615 default:
1616 if (c->parent->flags & DIV_U71_FIXED) {
1617 /* PLLP_OUT1 rate is not in PLLA table */
1618 pr_warn("%s: failed %s ref/out rates %lu/%lu\n",
1619 __func__, c->name, input_rate, rate);
1620 cfreq = input_rate/(input_rate/1000000);
1621 break;
1622 }
1623 pr_err("%s: Unexpected reference rate %lu\n",
1624 __func__, input_rate);
1625 BUG();
1626 }
1627
1628 /* Raise VCO to guarantee 0.5% accuracy */
1629 for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
1630 cfg.output_rate <<= 1, p_div++);
1631
1632 cfg.p = 0x1 << p_div;
1633 cfg.m = input_rate / cfreq;
1634 cfg.n = cfg.output_rate / cfreq;
1635 cfg.cpcon = OUT_OF_TABLE_CPCON;
1636
1637 if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
1638 (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
1639 (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
1640 (cfg.output_rate > c->u.pll.vco_max)) {
1641 pr_err("%s: Failed to set %s out-of-table rate %lu\n",
1642 __func__, c->name, rate);
1643 return -EINVAL;
1644 }
1645 p_div <<= PLL_BASE_DIVP_SHIFT;
1646 }
1647
1648 c->mul = sel->n;
1649 c->div = sel->m * sel->p;
1650
1651 old_base = val = clk_readl(c->reg + PLL_BASE);
1652 val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
1653 ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
1654 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
1655 (sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
1656 if (val == old_base)
1657 return 0;
1658
1659 if (c->state == ON) {
1660 tegra3_pll_clk_disable(c);
1661 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
1662 }
1663 clk_writel(val, c->reg + PLL_BASE);
1664
1665 if (c->flags & PLL_HAS_CPCON) {
1666 val = clk_readl(c->reg + PLL_MISC(c));
1667 val &= ~PLL_MISC_CPCON_MASK;
1668 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
1669 if (c->flags & (PLLU | PLLD)) {
1670 val &= ~PLL_MISC_LFCON_MASK;
1671 if (sel->n >= PLLDU_LFCON_SET_DIVN)
1672 val |= 0x1 << PLL_MISC_LFCON_SHIFT;
1673 } else if (c->flags & (PLLX | PLLM)) {
1674 val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
1675 if (rate >= (c->u.pll.vco_max >> 1))
1676 val |= 0x1 << PLL_MISC_DCCON_SHIFT;
1677 }
1678 clk_writel(val, c->reg + PLL_MISC(c));
1679 }
1680
1681 if (c->state == ON)
1682 tegra3_pll_clk_enable(c);
1683
1684 return 0;
1685}
1686
1687static struct clk_ops tegra_pll_ops = {
1688 .init = tegra3_pll_clk_init,
1689 .enable = tegra3_pll_clk_enable,
1690 .disable = tegra3_pll_clk_disable,
1691 .set_rate = tegra3_pll_clk_set_rate,
1692};
1693
1694static void tegra3_pllp_clk_init(struct clk *c)
1695{
1696 tegra3_pll_clk_init(c);
1697 tegra3_pllp_init_dependencies(c->u.pll.fixed_rate);
1698}
1699
1700static void tegra3_pllp_clk_resume(struct clk *c)
1701{
1702 unsigned long rate = c->u.pll.fixed_rate;
1703 tegra3_pll_clk_init(c);
1704 BUG_ON(rate != c->u.pll.fixed_rate);
1705}
1706
1707static struct clk_ops tegra_pllp_ops = {
1708 .init = tegra3_pllp_clk_init,
1709 .enable = tegra3_pll_clk_enable,
1710 .disable = tegra3_pll_clk_disable,
1711 .set_rate = tegra3_pll_clk_set_rate,
1712};
1713
1714static int
1715tegra3_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
1716{
1717 u32 val, mask, reg;
1718
1719 switch (p) {
1720 case TEGRA_CLK_PLLD_CSI_OUT_ENB:
1721 mask = PLLD_BASE_CSI_CLKENABLE;
1722 reg = c->reg + PLL_BASE;
1723 break;
1724 case TEGRA_CLK_PLLD_DSI_OUT_ENB:
1725 mask = PLLD_MISC_DSI_CLKENABLE;
1726 reg = c->reg + PLL_MISC(c);
1727 break;
1728 case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
1729 if (!(c->flags & PLL_ALT_MISC_REG)) {
1730 mask = PLLD_BASE_DSIB_MUX_MASK;
1731 reg = c->reg + PLL_BASE;
1732 break;
1733 }
1734 /* fall through - error since PLLD2 does not have MUX_SEL control */
1735 default:
1736 return -EINVAL;
1737 }
1738
1739 val = clk_readl(reg);
1740 if (setting)
1741 val |= mask;
1742 else
1743 val &= ~mask;
1744 clk_writel(val, reg);
1745 return 0;
1746}
1747
1748static struct clk_ops tegra_plld_ops = {
1749 .init = tegra3_pll_clk_init,
1750 .enable = tegra3_pll_clk_enable,
1751 .disable = tegra3_pll_clk_disable,
1752 .set_rate = tegra3_pll_clk_set_rate,
1753 .clk_cfg_ex = tegra3_plld_clk_cfg_ex,
1754};
1755
1756static void tegra3_plle_clk_init(struct clk *c)
1757{
1758 u32 val;
1759
1760 val = clk_readl(PLLE_AUX);
1761 c->parent = (val & PLLE_AUX_PLLP_SEL) ?
1762 tegra_get_clock_by_name("pll_p") :
1763 tegra_get_clock_by_name("pll_ref");
1764
1765 val = clk_readl(c->reg + PLL_BASE);
1766 c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
1767 c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
1768 c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
1769 c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
1770}
1771
1772static void tegra3_plle_clk_disable(struct clk *c)
1773{
1774 u32 val;
1775 pr_debug("%s on clock %s\n", __func__, c->name);
1776
1777 val = clk_readl(c->reg + PLL_BASE);
1778 val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
1779 clk_writel(val, c->reg + PLL_BASE);
1780}
1781
1782static void tegra3_plle_training(struct clk *c)
1783{
1784 u32 val;
1785
1786 /* PLLE is already disabled, and setup cleared;
1787 * create falling edge on PLLE IDDQ input */
1788 val = pmc_readl(PMC_SATA_PWRGT);
1789 val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
1790 pmc_writel(val, PMC_SATA_PWRGT);
1791
1792 val = pmc_readl(PMC_SATA_PWRGT);
1793 val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
1794 pmc_writel(val, PMC_SATA_PWRGT);
1795
1796 val = pmc_readl(PMC_SATA_PWRGT);
1797 val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
1798 pmc_writel(val, PMC_SATA_PWRGT);
1799
1800 do {
1801 val = clk_readl(c->reg + PLL_MISC(c));
1802 } while (!(val & PLLE_MISC_READY));
1803}
1804
1805static int tegra3_plle_configure(struct clk *c, bool force_training)
1806{
1807 u32 val;
1808 const struct clk_pll_freq_table *sel;
1809 unsigned long rate = c->u.pll.fixed_rate;
1810 unsigned long input_rate = clk_get_rate(c->parent);
1811
1812 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1813 if (sel->input_rate == input_rate && sel->output_rate == rate)
1814 break;
1815 }
1816
1817 if (sel->input_rate == 0)
1818 return -ENOSYS;
1819
1820 /* disable PLLE, clear setup fiels */
1821 tegra3_plle_clk_disable(c);
1822
1823 val = clk_readl(c->reg + PLL_MISC(c));
1824 val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
1825 clk_writel(val, c->reg + PLL_MISC(c));
1826
1827 /* training */
1828 val = clk_readl(c->reg + PLL_MISC(c));
1829 if (force_training || (!(val & PLLE_MISC_READY)))
1830 tegra3_plle_training(c);
1831
1832 /* configure dividers, setup, disable SS */
1833 val = clk_readl(c->reg + PLL_BASE);
1834 val &= ~PLLE_BASE_DIV_MASK;
1835 val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon);
1836 clk_writel(val, c->reg + PLL_BASE);
1837 c->mul = sel->n;
1838 c->div = sel->m * sel->p;
1839
1840 val = clk_readl(c->reg + PLL_MISC(c));
1841 val |= PLLE_MISC_SETUP_VALUE;
1842 val |= PLLE_MISC_LOCK_ENABLE;
1843 clk_writel(val, c->reg + PLL_MISC(c));
1844
1845 val = clk_readl(PLLE_SS_CTRL);
1846 val |= PLLE_SS_DISABLE;
1847 clk_writel(val, PLLE_SS_CTRL);
1848
1849 /* enable and lock PLLE*/
1850 val = clk_readl(c->reg + PLL_BASE);
1851 val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
1852 clk_writel(val, c->reg + PLL_BASE);
1853
1854 tegra3_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK);
1855
1856#if USE_PLLE_SS
1857 /* configure spread spectrum coefficients */
1858 /* FIXME: coefficients for 216MHZ input? */
1859#ifdef CONFIG_TEGRA_SILICON_PLATFORM
1860 if (input_rate == 12000000)
1861#endif
1862 {
1863 val = clk_readl(PLLE_SS_CTRL);
1864 val &= ~(PLLE_SS_COEFFICIENTS_MASK | PLLE_SS_DISABLE);
1865 val |= PLLE_SS_COEFFICIENTS_12MHZ;
1866 clk_writel(val, PLLE_SS_CTRL);
1867 }
1868#endif
1869 return 0;
1870}
1871
1872static int tegra3_plle_clk_enable(struct clk *c)
1873{
1874 pr_debug("%s on clock %s\n", __func__, c->name);
1875 return tegra3_plle_configure(c, !c->set);
1876}
1877
1878static struct clk_ops tegra_plle_ops = {
1879 .init = tegra3_plle_clk_init,
1880 .enable = tegra3_plle_clk_enable,
1881 .disable = tegra3_plle_clk_disable,
1882};
1883
1884/* Clock divider ops (non-atomic shared register access) */
1885static DEFINE_SPINLOCK(pll_div_lock);
1886
1887static int tegra3_pll_div_clk_set_rate(struct clk *c, unsigned long rate);
1888static void tegra3_pll_div_clk_init(struct clk *c)
1889{
1890 if (c->flags & DIV_U71) {
1891 u32 divu71;
1892 u32 val = clk_readl(c->reg);
1893 val >>= c->reg_shift;
1894 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
1895 if (!(val & PLL_OUT_RESET_DISABLE))
1896 c->state = OFF;
1897
1898 if (c->u.pll_div.default_rate) {
1899 int ret = tegra3_pll_div_clk_set_rate(
1900 c, c->u.pll_div.default_rate);
1901 if (!ret)
1902 return;
1903 }
1904 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
1905 c->div = (divu71 + 2);
1906 c->mul = 2;
1907 } else if (c->flags & DIV_2) {
1908 c->state = ON;
1909 if (c->flags & (PLLD | PLLX)) {
1910 c->div = 2;
1911 c->mul = 1;
1912 }
1913 else
1914 BUG();
1915 } else {
1916 c->state = ON;
1917 c->div = 1;
1918 c->mul = 1;
1919 }
1920}
1921
1922static int tegra3_pll_div_clk_enable(struct clk *c)
1923{
1924 u32 val;
1925 u32 new_val;
1926 unsigned long flags;
1927
1928 pr_debug("%s: %s\n", __func__, c->name);
1929 if (c->flags & DIV_U71) {
1930 spin_lock_irqsave(&pll_div_lock, flags);
1931 val = clk_readl(c->reg);
1932 new_val = val >> c->reg_shift;
1933 new_val &= 0xFFFF;
1934
1935 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
1936
1937 val &= ~(0xFFFF << c->reg_shift);
1938 val |= new_val << c->reg_shift;
1939 clk_writel_delay(val, c->reg);
1940 spin_unlock_irqrestore(&pll_div_lock, flags);
1941 return 0;
1942 } else if (c->flags & DIV_2) {
1943 return 0;
1944 }
1945 return -EINVAL;
1946}
1947
1948static void tegra3_pll_div_clk_disable(struct clk *c)
1949{
1950 u32 val;
1951 u32 new_val;
1952 unsigned long flags;
1953
1954 pr_debug("%s: %s\n", __func__, c->name);
1955 if (c->flags & DIV_U71) {
1956 spin_lock_irqsave(&pll_div_lock, flags);
1957 val = clk_readl(c->reg);
1958 new_val = val >> c->reg_shift;
1959 new_val &= 0xFFFF;
1960
1961 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
1962
1963 val &= ~(0xFFFF << c->reg_shift);
1964 val |= new_val << c->reg_shift;
1965 clk_writel_delay(val, c->reg);
1966 spin_unlock_irqrestore(&pll_div_lock, flags);
1967 }
1968}
1969
1970static int tegra3_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
1971{
1972 u32 val;
1973 u32 new_val;
1974 int divider_u71;
1975 unsigned long parent_rate = clk_get_rate(c->parent);
1976 unsigned long flags;
1977
1978 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1979 if (c->flags & DIV_U71) {
1980 divider_u71 = clk_div71_get_divider(
1981 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1982 if (divider_u71 >= 0) {
1983 spin_lock_irqsave(&pll_div_lock, flags);
1984 val = clk_readl(c->reg);
1985 new_val = val >> c->reg_shift;
1986 new_val &= 0xFFFF;
1987 if (c->flags & DIV_U71_FIXED)
1988 new_val |= PLL_OUT_OVERRIDE;
1989 new_val &= ~PLL_OUT_RATIO_MASK;
1990 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
1991
1992 val &= ~(0xFFFF << c->reg_shift);
1993 val |= new_val << c->reg_shift;
1994 clk_writel_delay(val, c->reg);
1995 c->div = divider_u71 + 2;
1996 c->mul = 2;
1997 spin_unlock_irqrestore(&pll_div_lock, flags);
1998 return 0;
1999 }
2000 } else if (c->flags & DIV_2)
2001 return clk_set_rate(c->parent, rate * 2);
2002
2003 return -EINVAL;
2004}
2005
2006static long tegra3_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
2007{
2008 int divider;
2009 unsigned long parent_rate = clk_get_rate(c->parent);
2010 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
2011
2012 if (c->flags & DIV_U71) {
2013 divider = clk_div71_get_divider(
2014 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
2015 if (divider < 0)
2016 return divider;
2017 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
2018 } else if (c->flags & DIV_2)
2019 /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */
2020 return rate;
2021
2022 return -EINVAL;
2023}
2024
2025static struct clk_ops tegra_pll_div_ops = {
2026 .init = tegra3_pll_div_clk_init,
2027 .enable = tegra3_pll_div_clk_enable,
2028 .disable = tegra3_pll_div_clk_disable,
2029 .set_rate = tegra3_pll_div_clk_set_rate,
2030 .round_rate = tegra3_pll_div_clk_round_rate,
2031};
2032
2033/* Periph clk ops */
2034static inline u32 periph_clk_source_mask(struct clk *c)
2035{
2036 if (c->flags & MUX8)
2037 return 7 << 29;
2038 else if (c->flags & MUX_PWM)
2039 return 3 << 28;
2040 else if (c->flags & MUX_CLK_OUT)
2041 return 3 << (c->u.periph.clk_num + 4);
2042 else if (c->flags & PLLD)
2043 return PLLD_BASE_DSIB_MUX_MASK;
2044 else
2045 return 3 << 30;
2046}
2047
2048static inline u32 periph_clk_source_shift(struct clk *c)
2049{
2050 if (c->flags & MUX8)
2051 return 29;
2052 else if (c->flags & MUX_PWM)
2053 return 28;
2054 else if (c->flags & MUX_CLK_OUT)
2055 return c->u.periph.clk_num + 4;
2056 else if (c->flags & PLLD)
2057 return PLLD_BASE_DSIB_MUX_SHIFT;
2058 else
2059 return 30;
2060}
2061
2062static void tegra3_periph_clk_init(struct clk *c)
2063{
2064 u32 val = clk_readl(c->reg);
2065 const struct clk_mux_sel *mux = 0;
2066 const struct clk_mux_sel *sel;
2067 if (c->flags & MUX) {
2068 for (sel = c->inputs; sel->input != NULL; sel++) {
2069 if (((val & periph_clk_source_mask(c)) >>
2070 periph_clk_source_shift(c)) == sel->value)
2071 mux = sel;
2072 }
2073 BUG_ON(!mux);
2074
2075 c->parent = mux->input;
2076 } else {
2077 c->parent = c->inputs[0].input;
2078 }
2079
2080 if (c->flags & DIV_U71) {
2081 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
2082 if (c->flags & DIV_U71_IDLE) {
2083 val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
2084 PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
2085 val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
2086 PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
2087 clk_writel(val, c->reg);
2088 }
2089 c->div = divu71 + 2;
2090 c->mul = 2;
2091 } else if (c->flags & DIV_U151) {
2092 u32 divu151 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
2093 if ((c->flags & DIV_U151_UART) &&
2094 (!(val & PERIPH_CLK_UART_DIV_ENB))) {
2095 divu151 = 0;
2096 }
2097 c->div = divu151 + 2;
2098 c->mul = 2;
2099 } else if (c->flags & DIV_U16) {
2100 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
2101 c->div = divu16 + 1;
2102 c->mul = 1;
2103 } else {
2104 c->div = 1;
2105 c->mul = 1;
2106 }
2107
2108 c->state = ON;
2109
2110 if (c->flags & PERIPH_NO_ENB)
2111 return;
2112
2113 if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
2114 c->state = OFF;
2115 if (!(c->flags & PERIPH_NO_RESET))
2116 if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
2117 c->state = OFF;
2118}
2119
2120static int tegra3_periph_clk_enable(struct clk *c)
2121{
2122 unsigned long flags;
2123 pr_debug("%s on clock %s\n", __func__, c->name);
2124
2125 if (c->flags & PERIPH_NO_ENB)
2126 return 0;
2127
2128 spin_lock_irqsave(&periph_refcount_lock, flags);
2129
2130 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
2131 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) {
2132 spin_unlock_irqrestore(&periph_refcount_lock, flags);
2133 return 0;
2134 }
2135
2136 clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c));
2137 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET)) {
2138 if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c)) {
2139 udelay(5); /* reset propagation delay */
2140 clk_writel(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_RST_CLR_REG(c));
2141 }
2142 }
2143 spin_unlock_irqrestore(&periph_refcount_lock, flags);
2144 return 0;
2145}
2146
2147static void tegra3_periph_clk_disable(struct clk *c)
2148{
2149 unsigned long val, flags;
2150 pr_debug("%s on clock %s\n", __func__, c->name);
2151
2152 if (c->flags & PERIPH_NO_ENB)
2153 return;
2154
2155 spin_lock_irqsave(&periph_refcount_lock, flags);
2156
2157 if (c->refcnt)
2158 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
2159
2160 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
2161 /* If peripheral is in the APB bus then read the APB bus to
2162 * flush the write operation in apb bus. This will avoid the
2163 * peripheral access after disabling clock*/
2164 if (c->flags & PERIPH_ON_APB)
2165 val = chipid_readl();
2166
2167 clk_writel_delay(
2168 PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
2169 }
2170 spin_unlock_irqrestore(&periph_refcount_lock, flags);
2171}
2172
2173static void tegra3_periph_clk_reset(struct clk *c, bool assert)
2174{
2175 unsigned long val;
2176 pr_debug("%s %s on clock %s\n", __func__,
2177 assert ? "assert" : "deassert", c->name);
2178
2179 if (c->flags & PERIPH_NO_ENB)
2180 return;
2181
2182 if (!(c->flags & PERIPH_NO_RESET)) {
2183 if (assert) {
2184 /* If peripheral is in the APB bus then read the APB
2185 * bus to flush the write operation in apb bus. This
2186 * will avoid the peripheral access after disabling
2187 * clock */
2188 if (c->flags & PERIPH_ON_APB)
2189 val = chipid_readl();
2190
2191 clk_writel(PERIPH_CLK_TO_BIT(c),
2192 PERIPH_CLK_TO_RST_SET_REG(c));
2193 } else
2194 clk_writel(PERIPH_CLK_TO_BIT(c),
2195 PERIPH_CLK_TO_RST_CLR_REG(c));
2196 }
2197}
2198
2199static int tegra3_periph_clk_set_parent(struct clk *c, struct clk *p)
2200{
2201 u32 val;
2202 const struct clk_mux_sel *sel;
2203 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
2204
2205 if (!(c->flags & MUX))
2206 return (p == c->parent) ? 0 : (-EINVAL);
2207
2208 for (sel = c->inputs; sel->input != NULL; sel++) {
2209 if (sel->input == p) {
2210 val = clk_readl(c->reg);
2211 val &= ~periph_clk_source_mask(c);
2212 val |= (sel->value << periph_clk_source_shift(c));
2213
2214 if (c->refcnt)
2215 clk_enable(p);
2216
2217 clk_writel_delay(val, c->reg);
2218
2219 if (c->refcnt && c->parent)
2220 clk_disable(c->parent);
2221
2222 clk_reparent(c, p);
2223 return 0;
2224 }
2225 }
2226
2227 return -EINVAL;
2228}
2229
2230static int tegra3_periph_clk_set_rate(struct clk *c, unsigned long rate)
2231{
2232 u32 val;
2233 int divider;
2234 unsigned long parent_rate = clk_get_rate(c->parent);
2235
2236 if (c->flags & DIV_U71) {
2237 divider = clk_div71_get_divider(
2238 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
2239 if (divider >= 0) {
2240 val = clk_readl(c->reg);
2241 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
2242 val |= divider;
2243 clk_writel_delay(val, c->reg);
2244 c->div = divider + 2;
2245 c->mul = 2;
2246 return 0;
2247 }
2248 } else if (c->flags & DIV_U151) {
2249 divider = clk_div151_get_divider(
2250 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
2251 if (divider >= 0) {
2252 val = clk_readl(c->reg);
2253 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
2254 val |= divider;
2255 if (c->flags & DIV_U151_UART) {
2256 if (divider)
2257 val |= PERIPH_CLK_UART_DIV_ENB;
2258 else
2259 val &= ~PERIPH_CLK_UART_DIV_ENB;
2260 }
2261 clk_writel_delay(val, c->reg);
2262 c->div = divider + 2;
2263 c->mul = 2;
2264 return 0;
2265 }
2266 } else if (c->flags & DIV_U16) {
2267 divider = clk_div16_get_divider(parent_rate, rate);
2268 if (divider >= 0) {
2269 val = clk_readl(c->reg);
2270 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
2271 val |= divider;
2272 clk_writel_delay(val, c->reg);
2273 c->div = divider + 1;
2274 c->mul = 1;
2275 return 0;
2276 }
2277 } else if (parent_rate <= rate) {
2278 c->div = 1;
2279 c->mul = 1;
2280 return 0;
2281 }
2282 return -EINVAL;
2283}
2284
2285static long tegra3_periph_clk_round_rate(struct clk *c,
2286 unsigned long rate)
2287{
2288 int divider;
2289 unsigned long parent_rate = clk_get_rate(c->parent);
2290 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
2291
2292 if (c->flags & DIV_U71) {
2293 divider = clk_div71_get_divider(
2294 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
2295 if (divider < 0)
2296 return divider;
2297
2298 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
2299 } else if (c->flags & DIV_U151) {
2300 divider = clk_div151_get_divider(
2301 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
2302 if (divider < 0)
2303 return divider;
2304
2305 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
2306 } else if (c->flags & DIV_U16) {
2307 divider = clk_div16_get_divider(parent_rate, rate);
2308 if (divider < 0)
2309 return divider;
2310 return DIV_ROUND_UP(parent_rate, divider + 1);
2311 }
2312 return -EINVAL;
2313}
2314
2315static struct clk_ops tegra_periph_clk_ops = {
2316 .init = &tegra3_periph_clk_init,
2317 .enable = &tegra3_periph_clk_enable,
2318 .disable = &tegra3_periph_clk_disable,
2319 .set_parent = &tegra3_periph_clk_set_parent,
2320 .set_rate = &tegra3_periph_clk_set_rate,
2321 .round_rate = &tegra3_periph_clk_round_rate,
2322 .reset = &tegra3_periph_clk_reset,
2323};
2324
2325
2326/* Periph extended clock configuration ops */
2327static int
2328tegra3_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
2329{
2330 if (p == TEGRA_CLK_VI_INP_SEL) {
2331 u32 val = clk_readl(c->reg);
2332 val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
2333 val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) &
2334 PERIPH_CLK_VI_SEL_EX_MASK;
2335 clk_writel(val, c->reg);
2336 return 0;
2337 }
2338 return -EINVAL;
2339}
2340
2341static struct clk_ops tegra_vi_clk_ops = {
2342 .init = &tegra3_periph_clk_init,
2343 .enable = &tegra3_periph_clk_enable,
2344 .disable = &tegra3_periph_clk_disable,
2345 .set_parent = &tegra3_periph_clk_set_parent,
2346 .set_rate = &tegra3_periph_clk_set_rate,
2347 .round_rate = &tegra3_periph_clk_round_rate,
2348 .clk_cfg_ex = &tegra3_vi_clk_cfg_ex,
2349 .reset = &tegra3_periph_clk_reset,
2350};
2351
2352static int
2353tegra3_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
2354{
2355 if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
2356 u32 val = clk_readl(c->reg);
2357 if (setting)
2358 val |= PERIPH_CLK_NAND_DIV_EX_ENB;
2359 else
2360 val &= ~PERIPH_CLK_NAND_DIV_EX_ENB;
2361 clk_writel(val, c->reg);
2362 return 0;
2363 }
2364 return -EINVAL;
2365}
2366
2367static struct clk_ops tegra_nand_clk_ops = {
2368 .init = &tegra3_periph_clk_init,
2369 .enable = &tegra3_periph_clk_enable,
2370 .disable = &tegra3_periph_clk_disable,
2371 .set_parent = &tegra3_periph_clk_set_parent,
2372 .set_rate = &tegra3_periph_clk_set_rate,
2373 .round_rate = &tegra3_periph_clk_round_rate,
2374 .clk_cfg_ex = &tegra3_nand_clk_cfg_ex,
2375 .reset = &tegra3_periph_clk_reset,
2376};
2377
2378
2379static int
2380tegra3_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
2381{
2382 if (p == TEGRA_CLK_DTV_INVERT) {
2383 u32 val = clk_readl(c->reg);
2384 if (setting)
2385 val |= PERIPH_CLK_DTV_POLARITY_INV;
2386 else
2387 val &= ~PERIPH_CLK_DTV_POLARITY_INV;
2388 clk_writel(val, c->reg);
2389 return 0;
2390 }
2391 return -EINVAL;
2392}
2393
2394static struct clk_ops tegra_dtv_clk_ops = {
2395 .init = &tegra3_periph_clk_init,
2396 .enable = &tegra3_periph_clk_enable,
2397 .disable = &tegra3_periph_clk_disable,
2398 .set_parent = &tegra3_periph_clk_set_parent,
2399 .set_rate = &tegra3_periph_clk_set_rate,
2400 .round_rate = &tegra3_periph_clk_round_rate,
2401 .clk_cfg_ex = &tegra3_dtv_clk_cfg_ex,
2402 .reset = &tegra3_periph_clk_reset,
2403};
2404
2405static int tegra3_dsib_clk_set_parent(struct clk *c, struct clk *p)
2406{
2407 const struct clk_mux_sel *sel;
2408 struct clk *d = tegra_get_clock_by_name("pll_d");
2409
2410 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
2411
2412 for (sel = c->inputs; sel->input != NULL; sel++) {
2413 if (sel->input == p) {
2414 if (c->refcnt)
2415 clk_enable(p);
2416
2417 /* The DSIB parent selection bit is in PLLD base
2418 register - can not do direct r-m-w, must be
2419 protected by PLLD lock */
2420 tegra_clk_cfg_ex(
2421 d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value);
2422
2423 if (c->refcnt && c->parent)
2424 clk_disable(c->parent);
2425
2426 clk_reparent(c, p);
2427 return 0;
2428 }
2429 }
2430
2431 return -EINVAL;
2432}
2433
2434static struct clk_ops tegra_dsib_clk_ops = {
2435 .init = &tegra3_periph_clk_init,
2436 .enable = &tegra3_periph_clk_enable,
2437 .disable = &tegra3_periph_clk_disable,
2438 .set_parent = &tegra3_dsib_clk_set_parent,
2439 .set_rate = &tegra3_periph_clk_set_rate,
2440 .round_rate = &tegra3_periph_clk_round_rate,
2441 .reset = &tegra3_periph_clk_reset,
2442};
2443
2444/* pciex clock support only reset function */
2445static struct clk_ops tegra_pciex_clk_ops = {
2446 .reset = tegra3_periph_clk_reset,
2447};
2448
2449/* Output clock ops (non-atomic shared register access) */
2450
2451static DEFINE_SPINLOCK(clk_out_lock);
2452
2453static void tegra3_clk_out_init(struct clk *c)
2454{
2455 const struct clk_mux_sel *mux = 0;
2456 const struct clk_mux_sel *sel;
2457 u32 val = pmc_readl(c->reg);
2458
2459 c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
2460 c->mul = 1;
2461 c->div = 1;
2462
2463 for (sel = c->inputs; sel->input != NULL; sel++) {
2464 if (((val & periph_clk_source_mask(c)) >>
2465 periph_clk_source_shift(c)) == sel->value)
2466 mux = sel;
2467 }
2468 BUG_ON(!mux);
2469 c->parent = mux->input;
2470}
2471
2472static int tegra3_clk_out_enable(struct clk *c)
2473{
2474 u32 val;
2475 unsigned long flags;
2476
2477 pr_debug("%s on clock %s\n", __func__, c->name);
2478
2479 spin_lock_irqsave(&clk_out_lock, flags);
2480 val = pmc_readl(c->reg);
2481 val |= (0x1 << c->u.periph.clk_num);
2482 pmc_writel(val, c->reg);
2483 spin_unlock_irqrestore(&clk_out_lock, flags);
2484
2485 return 0;
2486}
2487
2488static void tegra3_clk_out_disable(struct clk *c)
2489{
2490 u32 val;
2491 unsigned long flags;
2492
2493 pr_debug("%s on clock %s\n", __func__, c->name);
2494
2495 spin_lock_irqsave(&clk_out_lock, flags);
2496 val = pmc_readl(c->reg);
2497 val &= ~(0x1 << c->u.periph.clk_num);
2498 pmc_writel(val, c->reg);
2499 spin_unlock_irqrestore(&clk_out_lock, flags);
2500}
2501
2502static int tegra3_clk_out_set_parent(struct clk *c, struct clk *p)
2503{
2504 u32 val;
2505 unsigned long flags;
2506 const struct clk_mux_sel *sel;
2507
2508 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
2509
2510 for (sel = c->inputs; sel->input != NULL; sel++) {
2511 if (sel->input == p) {
2512 if (c->refcnt)
2513 clk_enable(p);
2514
2515 spin_lock_irqsave(&clk_out_lock, flags);
2516 val = pmc_readl(c->reg);
2517 val &= ~periph_clk_source_mask(c);
2518 val |= (sel->value << periph_clk_source_shift(c));
2519 pmc_writel(val, c->reg);
2520 spin_unlock_irqrestore(&clk_out_lock, flags);
2521
2522 if (c->refcnt && c->parent)
2523 clk_disable(c->parent);
2524
2525 clk_reparent(c, p);
2526 return 0;
2527 }
2528 }
2529 return -EINVAL;
2530}
2531
2532static struct clk_ops tegra_clk_out_ops = {
2533 .init = &tegra3_clk_out_init,
2534 .enable = &tegra3_clk_out_enable,
2535 .disable = &tegra3_clk_out_disable,
2536 .set_parent = &tegra3_clk_out_set_parent,
2537};
2538
2539
2540/* External memory controller clock ops */
2541static void tegra3_emc_clk_init(struct clk *c)
2542{
2543 tegra3_periph_clk_init(c);
2544 tegra_emc_dram_type_init(c);
2545
2546 /* On A01 limit EMC maximum rate to boot frequency;
2547 starting with A02 full PLLM range should be supported */
2548 if (tegra_get_revision() == TEGRA_REVISION_A01)
2549 c->max_rate = clk_get_rate_locked(c);
2550 else
2551 c->max_rate = clk_get_rate(c->parent);
2552}
2553
2554static long tegra3_emc_clk_round_rate(struct clk *c, unsigned long rate)
2555{
2556 long new_rate = max(rate, c->min_rate);
2557
2558 new_rate = tegra_emc_round_rate(new_rate);
2559 if (new_rate < 0)
2560 new_rate = c->max_rate;
2561
2562 return new_rate;
2563}
2564
2565static int tegra3_emc_clk_set_rate(struct clk *c, unsigned long rate)
2566{
2567 int ret;
2568 u32 div_value;
2569 struct clk *p;
2570
2571 /* The tegra3 memory controller has an interlock with the clock
2572 * block that allows memory shadowed registers to be updated,
2573 * and then transfer them to the main registers at the same
2574 * time as the clock update without glitches. During clock change
2575 * operation both clock parent and divider may change simultaneously
2576 * to achieve requested rate. */
2577 p = tegra_emc_predict_parent(rate, &div_value);
2578 div_value += 2; /* emc has fractional DIV_U71 divider */
2579 if (!p)
2580 return -EINVAL;
2581
2582 if (p == c->parent) {
2583 if (div_value == c->div)
2584 return 0;
2585 } else if (c->refcnt)
2586 clk_enable(p);
2587
2588 ret = tegra_emc_set_rate(rate);
2589 if (ret < 0)
2590 return ret;
2591
2592 if (p != c->parent) {
2593 if(c->refcnt && c->parent)
2594 clk_disable(c->parent);
2595 clk_reparent(c, p);
2596 }
2597 c->div = div_value;
2598 c->mul = 2;
2599 return 0;
2600}
2601
2602static struct clk_ops tegra_emc_clk_ops = {
2603 .init = &tegra3_emc_clk_init,
2604 .enable = &tegra3_periph_clk_enable,
2605 .disable = &tegra3_periph_clk_disable,
2606 .set_rate = &tegra3_emc_clk_set_rate,
2607 .round_rate = &tegra3_emc_clk_round_rate,
2608 .reset = &tegra3_periph_clk_reset,
2609 .shared_bus_update = &tegra3_clk_shared_bus_update,
2610};
2611
2612/* Clock doubler ops (non-atomic shared register access) */
2613static DEFINE_SPINLOCK(doubler_lock);
2614
2615static void tegra3_clk_double_init(struct clk *c)
2616{
2617 u32 val = clk_readl(c->reg);
2618 c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
2619 c->div = 1;
2620 c->state = ON;
2621 if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
2622 c->state = OFF;
2623};
2624
2625static int tegra3_clk_double_set_rate(struct clk *c, unsigned long rate)
2626{
2627 u32 val;
2628 unsigned long parent_rate = clk_get_rate(c->parent);
2629 unsigned long flags;
2630
2631 if (rate == parent_rate) {
2632 spin_lock_irqsave(&doubler_lock, flags);
2633 val = clk_readl(c->reg) | (0x1 << c->reg_shift);
2634 clk_writel(val, c->reg);
2635 c->mul = 1;
2636 c->div = 1;
2637 spin_unlock_irqrestore(&doubler_lock, flags);
2638 return 0;
2639 } else if (rate == 2 * parent_rate) {
2640 spin_lock_irqsave(&doubler_lock, flags);
2641 val = clk_readl(c->reg) & (~(0x1 << c->reg_shift));
2642 clk_writel(val, c->reg);
2643 c->mul = 2;
2644 c->div = 1;
2645 spin_unlock_irqrestore(&doubler_lock, flags);
2646 return 0;
2647 }
2648 return -EINVAL;
2649}
2650
2651static struct clk_ops tegra_clk_double_ops = {
2652 .init = &tegra3_clk_double_init,
2653 .enable = &tegra3_periph_clk_enable,
2654 .disable = &tegra3_periph_clk_disable,
2655 .set_rate = &tegra3_clk_double_set_rate,
2656};
2657
2658/* Audio sync clock ops */
2659static int tegra3_sync_source_set_rate(struct clk *c, unsigned long rate)
2660{
2661 c->rate = rate;
2662 return 0;
2663}
2664
2665static struct clk_ops tegra_sync_source_ops = {
2666 .set_rate = &tegra3_sync_source_set_rate,
2667};
2668
2669static void tegra3_audio_sync_clk_init(struct clk *c)
2670{
2671 int source;
2672 const struct clk_mux_sel *sel;
2673 u32 val = clk_readl(c->reg);
2674 c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
2675 source = val & AUDIO_SYNC_SOURCE_MASK;
2676 for (sel = c->inputs; sel->input != NULL; sel++)
2677 if (sel->value == source)
2678 break;
2679 BUG_ON(sel->input == NULL);
2680 c->parent = sel->input;
2681}
2682
2683static int tegra3_audio_sync_clk_enable(struct clk *c)
2684{
2685 u32 val = clk_readl(c->reg);
2686 clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
2687 return 0;
2688}
2689
2690static void tegra3_audio_sync_clk_disable(struct clk *c)
2691{
2692 u32 val = clk_readl(c->reg);
2693 clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
2694}
2695
2696static int tegra3_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
2697{
2698 u32 val;
2699 const struct clk_mux_sel *sel;
2700 for (sel = c->inputs; sel->input != NULL; sel++) {
2701 if (sel->input == p) {
2702 val = clk_readl(c->reg);
2703 val &= ~AUDIO_SYNC_SOURCE_MASK;
2704 val |= sel->value;
2705
2706 if (c->refcnt)
2707 clk_enable(p);
2708
2709 clk_writel(val, c->reg);
2710
2711 if (c->refcnt && c->parent)
2712 clk_disable(c->parent);
2713
2714 clk_reparent(c, p);
2715 return 0;
2716 }
2717 }
2718
2719 return -EINVAL;
2720}
2721
2722static struct clk_ops tegra_audio_sync_clk_ops = {
2723 .init = tegra3_audio_sync_clk_init,
2724 .enable = tegra3_audio_sync_clk_enable,
2725 .disable = tegra3_audio_sync_clk_disable,
2726 .set_parent = tegra3_audio_sync_clk_set_parent,
2727};
2728
2729/* cml0 (pcie), and cml1 (sata) clock ops (non-atomic shared register access) */
2730static DEFINE_SPINLOCK(cml_lock);
2731
2732static void tegra3_cml_clk_init(struct clk *c)
2733{
2734 u32 val = clk_readl(c->reg);
2735 c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
2736}
2737
2738static int tegra3_cml_clk_enable(struct clk *c)
2739{
2740 u32 val;
2741 unsigned long flags;
2742
2743 spin_lock_irqsave(&cml_lock, flags);
2744 val = clk_readl(c->reg);
2745 val |= (0x1 << c->u.periph.clk_num);
2746 clk_writel(val, c->reg);
2747 spin_unlock_irqrestore(&cml_lock, flags);
2748 return 0;
2749}
2750
2751static void tegra3_cml_clk_disable(struct clk *c)
2752{
2753 u32 val;
2754 unsigned long flags;
2755
2756 spin_lock_irqsave(&cml_lock, flags);
2757 val = clk_readl(c->reg);
2758 val &= ~(0x1 << c->u.periph.clk_num);
2759 clk_writel(val, c->reg);
2760 spin_unlock_irqrestore(&cml_lock, flags);
2761}
2762
2763static struct clk_ops tegra_cml_clk_ops = {
2764 .init = &tegra3_cml_clk_init,
2765 .enable = &tegra3_cml_clk_enable,
2766 .disable = &tegra3_cml_clk_disable,
2767};
2768
2769
2770/* cbus ops */
2771/*
2772 * Some clocks require dynamic re-locking of source PLL in order to
2773 * achieve frequency scaling granularity that matches characterized
2774 * core voltage steps. The cbus clock creates a shared bus that
2775 * provides a virtual root for such clocks to hide and synchronize
2776 * parent PLL re-locking as well as backup operations.
2777*/
2778
2779static void tegra3_clk_cbus_init(struct clk *c)
2780{
2781 c->state = OFF;
2782 c->set = true;
2783}
2784
2785static int tegra3_clk_cbus_enable(struct clk *c)
2786{
2787 return 0;
2788}
2789
2790static long tegra3_clk_cbus_round_rate(struct clk *c, unsigned long rate)
2791{
2792 int i;
2793
2794 if (!c->dvfs)
2795 return rate;
2796
2797 /* update min now, since no dvfs table was available during init
2798 (skip placeholder entries set to 1 kHz) */
2799 if (!c->min_rate) {
2800 for (i = 0; i < (c->dvfs->num_freqs - 1); i++) {
2801 if (c->dvfs->freqs[i] > 1 * c->dvfs->freqs_mult) {
2802 c->min_rate = c->dvfs->freqs[i];
2803 break;
2804 }
2805 }
2806 BUG_ON(!c->min_rate);
2807 }
2808 rate = max(rate, c->min_rate);
2809
2810 for (i = 0; i < (c->dvfs->num_freqs - 1); i++) {
2811 unsigned long f = c->dvfs->freqs[i];
2812 if (f >= rate)
2813 break;
2814 }
2815 return c->dvfs->freqs[i];
2816}
2817
2818static int cbus_switch_one(struct clk *c, struct clk *p, u32 div, bool abort)
2819{
2820 int ret = 0;
2821
2822 /* set new divider if it is bigger than the current one */
2823 if (c->div < c->mul * div) {
2824 ret = clk_set_div(c, div);
2825 if (ret) {
2826 pr_err("%s: failed to set %s clock divider %u: %d\n",
2827 __func__, c->name, div, ret);
2828 if (abort)
2829 return ret;
2830 }
2831 }
2832
2833 ret = clk_set_parent(c, p);
2834 if (ret) {
2835 pr_err("%s: failed to set %s clock parent %s: %d\n",
2836 __func__, c->name, p->name, ret);
2837 if (abort)
2838 return ret;
2839 }
2840
2841 /* set new divider if it is smaller than the current one */
2842 if (c->div > c->mul * div) {
2843 ret = clk_set_div(c, div);
2844 if (ret)
2845 pr_err("%s: failed to set %s clock divider %u: %d\n",
2846 __func__, c->name, div, ret);
2847 }
2848
2849 return ret;
2850}
2851
2852static int cbus_backup(struct clk *c)
2853{
2854 int ret;
2855 struct clk *user;
2856
2857 list_for_each_entry(user, &c->shared_bus_list,
2858 u.shared_bus_user.node) {
2859 bool enabled = user->u.shared_bus_user.client &&
2860 (user->u.shared_bus_user.enabled ||
2861 user->u.shared_bus_user.client->refcnt);
2862 if (enabled) {
2863 ret = cbus_switch_one(user->u.shared_bus_user.client,
2864 c->shared_bus_backup.input,
2865 c->shared_bus_backup.value *
2866 user->div, true);
2867 if (ret)
2868 return ret;
2869 }
2870 }
2871 return 0;
2872}
2873
2874static void cbus_restore(struct clk *c)
2875{
2876 struct clk *user;
2877
2878 list_for_each_entry(user, &c->shared_bus_list,
2879 u.shared_bus_user.node) {
2880 bool back = user->u.shared_bus_user.client && (c->parent !=
2881 user->u.shared_bus_user.client->parent);
2882 if (back)
2883 cbus_switch_one(user->u.shared_bus_user.client,
2884 c->parent, c->div * user->div, false);
2885 }
2886}
2887
2888static int tegra3_clk_cbus_set_rate(struct clk *c, unsigned long rate)
2889{
2890 int ret;
2891
2892 if (rate == 0)
2893 return 0;
2894
2895 ret = clk_enable(c->parent);
2896 if (ret) {
2897 pr_err("%s: failed to enable %s clock: %d\n",
2898 __func__, c->name, ret);
2899 return ret;
2900 }
2901
2902 ret = cbus_backup(c);
2903 if (ret)
2904 goto out;
2905
2906 ret = clk_set_rate(c->parent, rate * c->div);
2907 if (ret) {
2908 pr_err("%s: failed to set %s clock rate %lu: %d\n",
2909 __func__, c->name, rate, ret);
2910 goto out;
2911 }
2912
2913 cbus_restore(c);
2914
2915out:
2916 clk_disable(c->parent);
2917 return ret;
2918}
2919
2920static struct clk_ops tegra_clk_cbus_ops = {
2921 .init = tegra3_clk_cbus_init,
2922 .enable = tegra3_clk_cbus_enable,
2923 .set_rate = tegra3_clk_cbus_set_rate,
2924 .round_rate = tegra3_clk_cbus_round_rate,
2925 .shared_bus_update = tegra3_clk_shared_bus_update,
2926};
2927
2928/* shared bus ops */
2929/*
2930 * Some clocks may have multiple downstream users that need to request a
2931 * higher clock rate. Shared bus clocks provide a unique shared_bus_user
2932 * clock to each user. The frequency of the bus is set to the highest
2933 * enabled shared_bus_user clock, with a minimum value set by the
2934 * shared bus.
2935 */
2936
2937static noinline int shared_bus_set_rate(struct clk *bus, unsigned long rate,
2938 unsigned long old_rate)
2939{
2940 int ret, mv, old_mv;
2941 unsigned long bridge_rate = emc_bridge->u.shared_bus_user.rate;
2942
2943 /* If bridge is not needed (LPDDR2) just set bus rate */
2944 if (tegra_emc_get_dram_type() == DRAM_TYPE_LPDDR2)
2945 return clk_set_rate_locked(bus, rate);
2946
2947 mv = tegra_dvfs_predict_millivolts(bus, rate);
2948 old_mv = tegra_dvfs_predict_millivolts(bus, old_rate);
2949 if (IS_ERR_VALUE(mv) || IS_ERR_VALUE(old_mv)) {
2950 pr_err("%s: Failed to predict %s voltage for %lu => %lu\n",
2951 __func__, bus->name, old_rate, rate);
2952 return -EINVAL;
2953 }
2954
2955 /* emc bus: set bridge rate as intermediate step when crossing
2956 * bridge threshold in any direction
2957 */
2958 if (bus->flags & PERIPH_EMC_ENB) {
2959 if (((mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
2960 (old_rate < bridge_rate)) ||
2961 ((old_mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
2962 (rate < bridge_rate))) {
2963 ret = clk_set_rate_locked(bus, bridge_rate);
2964 if (ret) {
2965 pr_err("%s: Failed to set emc bridge rate %lu\n",
2966 __func__, bridge_rate);
2967 return ret;
2968 }
2969 }
2970 return clk_set_rate_locked(bus, rate);
2971 }
2972
2973 /* sbus and cbus: enable/disable emc bridge user when crossing voltage
2974 * threshold up/down respectively; hence, emc rate is kept above the
2975 * bridge rate as long as any sbus or cbus user requires high voltage
2976 */
2977 if ((mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
2978 (old_mv <= TEGRA_EMC_BRIDGE_MVOLTS_MIN)) {
2979 ret = clk_enable(emc_bridge);
2980 if (ret) {
2981 pr_err("%s: Failed to enable emc bridge\n", __func__);
2982 return ret;
2983 }
2984 }
2985
2986 ret = clk_set_rate_locked(bus, rate);
2987 if (ret)
2988 return ret;
2989
2990 if ((mv <= TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
2991 (old_mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN))
2992 clk_disable(emc_bridge);
2993
2994 return 0;
2995}
2996
2997static int tegra3_clk_shared_bus_update(struct clk *bus)
2998{
2999 struct clk *c;
3000 unsigned long old_rate;
3001 unsigned long rate = bus->min_rate;
3002 unsigned long bw = 0;
3003 unsigned long ceiling = bus->max_rate;
3004
3005 if (detach_shared_bus)
3006 return 0;
3007
3008 list_for_each_entry(c, &bus->shared_bus_list,
3009 u.shared_bus_user.node) {
3010 /* Ignore requests from disabled users and from users with
3011 fixed bus-to-client ratio */
3012 if (c->u.shared_bus_user.enabled) {
3013 switch (c->u.shared_bus_user.mode) {
3014 case SHARED_BW:
3015 bw += c->u.shared_bus_user.rate;
3016 break;
3017 case SHARED_CEILING:
3018 ceiling = min(c->u.shared_bus_user.rate,
3019 ceiling);
3020 break;
3021 case SHARED_AUTO:
3022 case SHARED_FLOOR:
3023 default:
3024 rate = max(c->u.shared_bus_user.rate, rate);
3025 }
3026 }
3027 }
3028 rate = min(max(rate, bw), ceiling);
3029
3030 old_rate = clk_get_rate_locked(bus);
3031 if (rate == old_rate)
3032 return 0;
3033
3034 return shared_bus_set_rate(bus, rate, old_rate);
3035};
3036
3037static void tegra_clk_shared_bus_init(struct clk *c)
3038{
3039 c->max_rate = c->parent->max_rate;
3040 c->u.shared_bus_user.rate = c->parent->max_rate;
3041 c->state = OFF;
3042 c->set = true;
3043
3044 if (c->u.shared_bus_user.client_id) {
3045 c->u.shared_bus_user.client =
3046 tegra_get_clock_by_name(c->u.shared_bus_user.client_id);
3047 if (!c->u.shared_bus_user.client) {
3048 pr_err("%s: could not find clk %s\n", __func__,
3049 c->u.shared_bus_user.client_id);
3050 return;
3051 }
3052 c->u.shared_bus_user.client->flags |=
3053 c->parent->flags & PERIPH_ON_CBUS;
3054 c->flags |= c->parent->flags & PERIPH_ON_CBUS;
3055 c->div = c->u.shared_bus_user.client_div ? : 1;
3056 c->mul = 1;
3057 }
3058
3059 list_add_tail(&c->u.shared_bus_user.node,
3060 &c->parent->shared_bus_list);
3061}
3062
3063static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
3064{
3065 c->u.shared_bus_user.rate = rate;
3066 tegra_clk_shared_bus_update(c->parent);
3067 return 0;
3068}
3069
3070static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
3071{
3072 /* auto user follow others, by itself it run at minimum bus rate */
3073 if (c->u.shared_bus_user.mode == SHARED_AUTO)
3074 rate = 0;
3075
3076 return clk_round_rate(c->parent, rate);
3077}
3078
3079static int tegra_clk_shared_bus_enable(struct clk *c)
3080{
3081 c->u.shared_bus_user.enabled = true;
3082 tegra_clk_shared_bus_update(c->parent);
3083 if (c->u.shared_bus_user.client) {
3084 return clk_enable(c->u.shared_bus_user.client);
3085 }
3086 return 0;
3087}
3088
3089static void tegra_clk_shared_bus_disable(struct clk *c)
3090{
3091 if (c->u.shared_bus_user.client)
3092 clk_disable(c->u.shared_bus_user.client);
3093 c->u.shared_bus_user.enabled = false;
3094 tegra_clk_shared_bus_update(c->parent);
3095}
3096
3097static void tegra_clk_shared_bus_reset(struct clk *c, bool assert)
3098{
3099 if (c->u.shared_bus_user.client) {
3100 if (c->u.shared_bus_user.client->ops &&
3101 c->u.shared_bus_user.client->ops->reset)
3102 c->u.shared_bus_user.client->ops->reset(
3103 c->u.shared_bus_user.client, assert);
3104 }
3105}
3106
3107static struct clk_ops tegra_clk_shared_bus_ops = {
3108 .init = tegra_clk_shared_bus_init,
3109 .enable = tegra_clk_shared_bus_enable,
3110 .disable = tegra_clk_shared_bus_disable,
3111 .set_rate = tegra_clk_shared_bus_set_rate,
3112 .round_rate = tegra_clk_shared_bus_round_rate,
3113 .reset = tegra_clk_shared_bus_reset,
3114};
3115
3116/* emc bridge ops */
3117/* On Tegra3 platforms emc configurations for DDR3 low rates can not work
3118 * at high core voltage; the intermediate step (bridge) is mandatory whenever
3119 * core voltage is crossing the threshold: TEGRA_EMC_BRIDGE_MVOLTS_MIN (fixed
3120 * for the entire Tegra3 arch); also emc must run above the bridge rate if any
3121 * other than emc clock requires high voltage. LP CPU, memory, sbus and cbus
3122 * together include all clocks that may require core voltage above threshold
3123 * (other peripherals can reach their maximum rates below threshold). LP CPU
3124 * dependency is taken care of via tegra_emc_to_cpu_ratio() api. Memory clock
3125 * transitions are forced to step through bridge rate; sbus and cbus control
3126 * emc bridge to set emc clock floor as necessary.
3127 *
3128 * EMC bridge is implemented as a special emc shared bus user: initialized at
3129 * minimum rate until updated once by emc dvfs setup; then it is only enabled
3130 * or disabled when sbus and/or cbus voltage is crossing the threshold.
3131 */
3132static void tegra3_clk_emc_bridge_init(struct clk *c)
3133{
3134 tegra_clk_shared_bus_init(c);
3135 c->u.shared_bus_user.rate = 0;
3136}
3137
3138static int tegra3_clk_emc_bridge_set_rate(struct clk *c, unsigned long rate)
3139{
3140 if (c->u.shared_bus_user.rate == 0)
3141 c->u.shared_bus_user.rate = rate;
3142 return 0;
3143}
3144
3145static struct clk_ops tegra_clk_emc_bridge_ops = {
3146 .init = tegra3_clk_emc_bridge_init,
3147 .enable = tegra_clk_shared_bus_enable,
3148 .disable = tegra_clk_shared_bus_disable,
3149 .set_rate = tegra3_clk_emc_bridge_set_rate,
3150 .round_rate = tegra_clk_shared_bus_round_rate,
3151};
3152
3153/* Clock definitions */
3154static struct clk tegra_clk_32k = {
3155 .name = "clk_32k",
3156 .rate = 32768,
3157 .ops = NULL,
3158 .max_rate = 32768,
3159};
3160
3161static struct clk tegra_clk_m = {
3162 .name = "clk_m",
3163 .flags = ENABLE_ON_INIT,
3164 .ops = &tegra_clk_m_ops,
3165 .reg = 0x1fc,
3166 .reg_shift = 28,
3167 .max_rate = 48000000,
3168};
3169
3170static struct clk tegra_clk_m_div2 = {
3171 .name = "clk_m_div2",
3172 .ops = &tegra_clk_m_div_ops,
3173 .parent = &tegra_clk_m,
3174 .mul = 1,
3175 .div = 2,
3176 .state = ON,
3177 .max_rate = 24000000,
3178};
3179
3180static struct clk tegra_clk_m_div4 = {
3181 .name = "clk_m_div4",
3182 .ops = &tegra_clk_m_div_ops,
3183 .parent = &tegra_clk_m,
3184 .mul = 1,
3185 .div = 4,
3186 .state = ON,
3187 .max_rate = 12000000,
3188};
3189
3190static struct clk tegra_pll_ref = {
3191 .name = "pll_ref",
3192 .flags = ENABLE_ON_INIT,
3193 .ops = &tegra_pll_ref_ops,
3194 .parent = &tegra_clk_m,
3195 .max_rate = 26000000,
3196};
3197
3198static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
3199 { 12000000, 1200000000, 600, 6, 1, 8},
3200 { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */
3201 { 16800000, 1200000000, 500, 7, 1, 8},
3202 { 19200000, 1200000000, 500, 8, 1, 8},
3203 { 26000000, 1200000000, 600, 13, 1, 8},
3204
3205 { 12000000, 1040000000, 520, 6, 1, 8},
3206 { 13000000, 1040000000, 480, 6, 1, 8},
3207 { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */
3208 { 19200000, 1040000000, 325, 6, 1, 6},
3209 { 26000000, 1040000000, 520, 13, 1, 8},
3210
3211 { 12000000, 832000000, 416, 6, 1, 8},
3212 { 13000000, 832000000, 832, 13, 1, 8},
3213 { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */
3214 { 19200000, 832000000, 260, 6, 1, 8},
3215 { 26000000, 832000000, 416, 13, 1, 8},
3216
3217 { 12000000, 624000000, 624, 12, 1, 8},
3218 { 13000000, 624000000, 624, 13, 1, 8},
3219 { 16800000, 624000000, 520, 14, 1, 8},
3220 { 19200000, 624000000, 520, 16, 1, 8},
3221 { 26000000, 624000000, 624, 26, 1, 8},
3222
3223 { 12000000, 600000000, 600, 12, 1, 8},
3224 { 13000000, 600000000, 600, 13, 1, 8},
3225 { 16800000, 600000000, 500, 14, 1, 8},
3226 { 19200000, 600000000, 375, 12, 1, 6},
3227 { 26000000, 600000000, 600, 26, 1, 8},
3228
3229 { 12000000, 520000000, 520, 12, 1, 8},
3230 { 13000000, 520000000, 520, 13, 1, 8},
3231 { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */
3232 { 19200000, 520000000, 325, 12, 1, 6},
3233 { 26000000, 520000000, 520, 26, 1, 8},
3234
3235 { 12000000, 416000000, 416, 12, 1, 8},
3236 { 13000000, 416000000, 416, 13, 1, 8},
3237 { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */
3238 { 19200000, 416000000, 260, 12, 1, 6},
3239 { 26000000, 416000000, 416, 26, 1, 8},
3240 { 0, 0, 0, 0, 0, 0 },
3241};
3242
3243static struct clk tegra_pll_c = {
3244 .name = "pll_c",
3245 .flags = PLL_HAS_CPCON,
3246 .ops = &tegra_pll_ops,
3247 .reg = 0x80,
3248 .parent = &tegra_pll_ref,
3249 .max_rate = 1400000000,
3250 .u.pll = {
3251 .input_min = 2000000,
3252 .input_max = 31000000,
3253 .cf_min = 1000000,
3254 .cf_max = 6000000,
3255 .vco_min = 20000000,
3256 .vco_max = 1400000000,
3257 .freq_table = tegra_pll_c_freq_table,
3258 .lock_delay = 300,
3259 },
3260};
3261
3262static struct clk tegra_pll_c_out1 = {
3263 .name = "pll_c_out1",
3264 .ops = &tegra_pll_div_ops,
3265 .flags = DIV_U71 | PERIPH_ON_CBUS,
3266 .parent = &tegra_pll_c,
3267 .reg = 0x84,
3268 .reg_shift = 0,
3269 .max_rate = 700000000,
3270};
3271
3272static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
3273 { 12000000, 666000000, 666, 12, 1, 8},
3274 { 13000000, 666000000, 666, 13, 1, 8},
3275 { 16800000, 666000000, 555, 14, 1, 8},
3276 { 19200000, 666000000, 555, 16, 1, 8},
3277 { 26000000, 666000000, 666, 26, 1, 8},
3278 { 12000000, 600000000, 600, 12, 1, 8},
3279 { 13000000, 600000000, 600, 13, 1, 8},
3280 { 16800000, 600000000, 500, 14, 1, 8},
3281 { 19200000, 600000000, 375, 12, 1, 6},
3282 { 26000000, 600000000, 600, 26, 1, 8},
3283 { 0, 0, 0, 0, 0, 0 },
3284};
3285
3286static struct clk tegra_pll_m = {
3287 .name = "pll_m",
3288 .flags = PLL_HAS_CPCON | PLLM,
3289 .ops = &tegra_pll_ops,
3290 .reg = 0x90,
3291 .parent = &tegra_pll_ref,
3292 .max_rate = 900000000,
3293 .u.pll = {
3294 .input_min = 2000000,
3295 .input_max = 31000000,
3296 .cf_min = 1000000,
3297 .cf_max = 6000000,
3298 .vco_min = 20000000,
3299 .vco_max = 1200000000,
3300 .freq_table = tegra_pll_m_freq_table,
3301 .lock_delay = 300,
3302 },
3303};
3304
3305static struct clk tegra_pll_m_out1 = {
3306 .name = "pll_m_out1",
3307 .ops = &tegra_pll_div_ops,
3308 .flags = DIV_U71,
3309 .parent = &tegra_pll_m,
3310 .reg = 0x94,
3311 .reg_shift = 0,
3312 .max_rate = 600000000,
3313};
3314
3315static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
3316 { 12000000, 216000000, 432, 12, 2, 8},
3317 { 13000000, 216000000, 432, 13, 2, 8},
3318 { 16800000, 216000000, 360, 14, 2, 8},
3319 { 19200000, 216000000, 360, 16, 2, 8},
3320 { 26000000, 216000000, 432, 26, 2, 8},
3321 { 0, 0, 0, 0, 0, 0 },
3322};
3323
3324static struct clk tegra_pll_p = {
3325 .name = "pll_p",
3326 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
3327 .ops = &tegra_pllp_ops,
3328 .reg = 0xa0,
3329 .parent = &tegra_pll_ref,
3330 .max_rate = 432000000,
3331 .u.pll = {
3332 .input_min = 2000000,
3333 .input_max = 31000000,
3334 .cf_min = 1000000,
3335 .cf_max = 6000000,
3336 .vco_min = 20000000,
3337 .vco_max = 1400000000,
3338 .freq_table = tegra_pll_p_freq_table,
3339 .lock_delay = 300,
3340 },
3341};
3342
3343static struct clk tegra_pll_p_out1 = {
3344 .name = "pll_p_out1",
3345 .ops = &tegra_pll_div_ops,
3346 .flags = DIV_U71 | DIV_U71_FIXED,
3347 .parent = &tegra_pll_p,
3348 .reg = 0xa4,
3349 .reg_shift = 0,
3350 .max_rate = 432000000,
3351};
3352
3353static struct clk tegra_pll_p_out2 = {
3354 .name = "pll_p_out2",
3355 .ops = &tegra_pll_div_ops,
3356 .flags = DIV_U71 | DIV_U71_FIXED,
3357 .parent = &tegra_pll_p,
3358 .reg = 0xa4,
3359 .reg_shift = 16,
3360 .max_rate = 432000000,
3361};
3362
3363static struct clk tegra_pll_p_out3 = {
3364 .name = "pll_p_out3",
3365 .ops = &tegra_pll_div_ops,
3366 .flags = DIV_U71 | DIV_U71_FIXED,
3367 .parent = &tegra_pll_p,
3368 .reg = 0xa8,
3369 .reg_shift = 0,
3370 .max_rate = 432000000,
3371};
3372
3373static struct clk tegra_pll_p_out4 = {
3374 .name = "pll_p_out4",
3375 .ops = &tegra_pll_div_ops,
3376 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
3377 .parent = &tegra_pll_p,
3378 .reg = 0xa8,
3379 .reg_shift = 16,
3380 .max_rate = 432000000,
3381};
3382
3383static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
3384 { 9600000, 564480000, 294, 5, 1, 4},
3385 { 9600000, 552960000, 288, 5, 1, 4},
3386 { 9600000, 24000000, 5, 2, 1, 1},
3387
3388 { 28800000, 56448000, 49, 25, 1, 1},
3389 { 28800000, 73728000, 64, 25, 1, 1},
3390 { 28800000, 24000000, 5, 6, 1, 1},
3391 { 0, 0, 0, 0, 0, 0 },
3392};
3393
3394static struct clk tegra_pll_a = {
3395 .name = "pll_a",
3396 .flags = PLL_HAS_CPCON,
3397 .ops = &tegra_pll_ops,
3398 .reg = 0xb0,
3399 .parent = &tegra_pll_p_out1,
3400 .max_rate = 700000000,
3401 .u.pll = {
3402 .input_min = 2000000,
3403 .input_max = 31000000,
3404 .cf_min = 1000000,
3405 .cf_max = 6000000,
3406 .vco_min = 20000000,
3407 .vco_max = 1400000000,
3408 .freq_table = tegra_pll_a_freq_table,
3409 .lock_delay = 300,
3410 },
3411};
3412
3413static struct clk tegra_pll_a_out0 = {
3414 .name = "pll_a_out0",
3415 .ops = &tegra_pll_div_ops,
3416 .flags = DIV_U71,
3417 .parent = &tegra_pll_a,
3418 .reg = 0xb4,
3419 .reg_shift = 0,
3420 .max_rate = 100000000,
3421};
3422
3423static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
3424 { 12000000, 216000000, 216, 12, 1, 4},
3425 { 13000000, 216000000, 216, 13, 1, 4},
3426 { 16800000, 216000000, 180, 14, 1, 4},
3427 { 19200000, 216000000, 180, 16, 1, 4},
3428 { 26000000, 216000000, 216, 26, 1, 4},
3429
3430 { 12000000, 594000000, 594, 12, 1, 8},
3431 { 13000000, 594000000, 594, 13, 1, 8},
3432 { 16800000, 594000000, 495, 14, 1, 8},
3433 { 19200000, 594000000, 495, 16, 1, 8},
3434 { 26000000, 594000000, 594, 26, 1, 8},
3435
3436 { 12000000, 1000000000, 1000, 12, 1, 12},
3437 { 13000000, 1000000000, 1000, 13, 1, 12},
3438 { 19200000, 1000000000, 625, 12, 1, 8},
3439 { 26000000, 1000000000, 1000, 26, 1, 12},
3440
3441 { 0, 0, 0, 0, 0, 0 },
3442};
3443
3444static struct clk tegra_pll_d = {
3445 .name = "pll_d",
3446 .flags = PLL_HAS_CPCON | PLLD,
3447 .ops = &tegra_plld_ops,
3448 .reg = 0xd0,
3449 .parent = &tegra_pll_ref,
3450 .max_rate = 1000000000,
3451 .u.pll = {
3452 .input_min = 2000000,
3453 .input_max = 40000000,
3454 .cf_min = 1000000,
3455 .cf_max = 6000000,
3456 .vco_min = 40000000,
3457 .vco_max = 1000000000,
3458 .freq_table = tegra_pll_d_freq_table,
3459 .lock_delay = 1000,
3460 },
3461};
3462
3463static struct clk tegra_pll_d_out0 = {
3464 .name = "pll_d_out0",
3465 .ops = &tegra_pll_div_ops,
3466 .flags = DIV_2 | PLLD,
3467 .parent = &tegra_pll_d,
3468 .max_rate = 500000000,
3469};
3470
3471static struct clk tegra_pll_d2 = {
3472 .name = "pll_d2",
3473 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD,
3474 .ops = &tegra_plld_ops,
3475 .reg = 0x4b8,
3476 .parent = &tegra_pll_ref,
3477 .max_rate = 1000000000,
3478 .u.pll = {
3479 .input_min = 2000000,
3480 .input_max = 40000000,
3481 .cf_min = 1000000,
3482 .cf_max = 6000000,
3483 .vco_min = 40000000,
3484 .vco_max = 1000000000,
3485 .freq_table = tegra_pll_d_freq_table,
3486 .lock_delay = 1000,
3487 },
3488};
3489
3490static struct clk tegra_pll_d2_out0 = {
3491 .name = "pll_d2_out0",
3492 .ops = &tegra_pll_div_ops,
3493 .flags = DIV_2 | PLLD,
3494 .parent = &tegra_pll_d2,
3495 .max_rate = 500000000,
3496};
3497
3498static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
3499 { 12000000, 480000000, 960, 12, 2, 12},
3500 { 13000000, 480000000, 960, 13, 2, 12},
3501 { 16800000, 480000000, 400, 7, 2, 5},
3502 { 19200000, 480000000, 200, 4, 2, 3},
3503 { 26000000, 480000000, 960, 26, 2, 12},
3504 { 0, 0, 0, 0, 0, 0 },
3505};
3506
3507static struct clk tegra_pll_u = {
3508 .name = "pll_u",
3509 .flags = PLL_HAS_CPCON | PLLU,
3510 .ops = &tegra_pll_ops,
3511 .reg = 0xc0,
3512 .parent = &tegra_pll_ref,
3513 .max_rate = 480000000,
3514 .u.pll = {
3515 .input_min = 2000000,
3516 .input_max = 40000000,
3517 .cf_min = 1000000,
3518 .cf_max = 6000000,
3519 .vco_min = 480000000,
3520 .vco_max = 960000000,
3521 .freq_table = tegra_pll_u_freq_table,
3522 .lock_delay = 1000,
3523 },
3524};
3525
3526static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
3527 /* 1.7 GHz */
3528 { 12000000, 1700000000, 850, 6, 1, 8},
3529 { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */
3530 { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */
3531 { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */
3532 { 26000000, 1700000000, 850, 13, 1, 8},
3533
3534 /* 1.6 GHz */
3535 { 12000000, 1600000000, 800, 6, 1, 8},
3536 { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */
3537 { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */
3538 { 19200000, 1600000000, 500, 6, 1, 8},
3539 { 26000000, 1600000000, 800, 13, 1, 8},
3540
3541 /* 1.5 GHz */
3542 { 12000000, 1500000000, 750, 6, 1, 8},
3543 { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */
3544 { 16800000, 1500000000, 625, 7, 1, 8},
3545 { 19200000, 1500000000, 625, 8, 1, 8},
3546 { 26000000, 1500000000, 750, 13, 1, 8},
3547
3548 /* 1.4 GHz */
3549 { 12000000, 1400000000, 700, 6, 1, 8},
3550 { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */
3551 { 16800000, 1400000000, 1000, 12, 1, 8},
3552 { 19200000, 1400000000, 875, 12, 1, 8},
3553 { 26000000, 1400000000, 700, 13, 1, 8},
3554
3555 /* 1.3 GHz */
3556 { 12000000, 1300000000, 975, 9, 1, 8},
3557 { 13000000, 1300000000, 1000, 10, 1, 8},
3558 { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */
3559 { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */
3560 { 26000000, 1300000000, 650, 13, 1, 8},
3561
3562 /* 1.2 GHz */
3563 { 12000000, 1200000000, 1000, 10, 1, 8},
3564 { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */
3565 { 16800000, 1200000000, 1000, 14, 1, 8},
3566 { 19200000, 1200000000, 1000, 16, 1, 8},
3567 { 26000000, 1200000000, 600, 13, 1, 8},
3568
3569 /* 1.1 GHz */
3570 { 12000000, 1100000000, 825, 9, 1, 8},
3571 { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */
3572 { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */
3573 { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */
3574 { 26000000, 1100000000, 550, 13, 1, 8},
3575
3576 /* 1 GHz */
3577 { 12000000, 1000000000, 1000, 12, 1, 8},
3578 { 13000000, 1000000000, 1000, 13, 1, 8},
3579 { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */
3580 { 19200000, 1000000000, 625, 12, 1, 8},
3581 { 26000000, 1000000000, 1000, 26, 1, 8},
3582
3583 { 0, 0, 0, 0, 0, 0 },
3584};
3585
3586static struct clk tegra_pll_x = {
3587 .name = "pll_x",
3588 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX,
3589 .ops = &tegra_pll_ops,
3590 .reg = 0xe0,
3591 .parent = &tegra_pll_ref,
3592 .max_rate = 1700000000,
3593 .u.pll = {
3594 .input_min = 2000000,
3595 .input_max = 31000000,
3596 .cf_min = 1000000,
3597 .cf_max = 6000000,
3598 .vco_min = 20000000,
3599 .vco_max = 1700000000,
3600 .freq_table = tegra_pll_x_freq_table,
3601 .lock_delay = 300,
3602 },
3603};
3604
3605static struct clk tegra_pll_x_out0 = {
3606 .name = "pll_x_out0",
3607 .ops = &tegra_pll_div_ops,
3608 .flags = DIV_2 | PLLX,
3609 .parent = &tegra_pll_x,
3610 .max_rate = 850000000,
3611};
3612
3613
3614static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
3615 /* PLLE special case: use cpcon field to store cml divider value */
3616 { 12000000, 100000000, 150, 1, 18, 11},
3617 { 216000000, 100000000, 200, 18, 24, 13},
3618#ifndef CONFIG_TEGRA_SILICON_PLATFORM
3619 { 13000000, 100000000, 200, 1, 26, 13},
3620#endif
3621 { 0, 0, 0, 0, 0, 0 },
3622};
3623
3624static struct clk tegra_pll_e = {
3625 .name = "pll_e",
3626 .flags = PLL_ALT_MISC_REG,
3627 .ops = &tegra_plle_ops,
3628 .reg = 0xe8,
3629 .max_rate = 100000000,
3630 .u.pll = {
3631 .input_min = 12000000,
3632 .input_max = 216000000,
3633 .cf_min = 12000000,
3634 .cf_max = 12000000,
3635 .vco_min = 1200000000,
3636 .vco_max = 2400000000U,
3637 .freq_table = tegra_pll_e_freq_table,
3638 .lock_delay = 300,
3639 .fixed_rate = 100000000,
3640 },
3641};
3642
3643static struct clk tegra_cml0_clk = {
3644 .name = "cml0",
3645 .parent = &tegra_pll_e,
3646 .ops = &tegra_cml_clk_ops,
3647 .reg = PLLE_AUX,
3648 .max_rate = 100000000,
3649 .u.periph = {
3650 .clk_num = 0,
3651 },
3652};
3653
3654static struct clk tegra_cml1_clk = {
3655 .name = "cml1",
3656 .parent = &tegra_pll_e,
3657 .ops = &tegra_cml_clk_ops,
3658 .reg = PLLE_AUX,
3659 .max_rate = 100000000,
3660 .u.periph = {
3661 .clk_num = 1,
3662 },
3663};
3664
3665static struct clk tegra_pciex_clk = {
3666 .name = "pciex",
3667 .parent = &tegra_pll_e,
3668 .ops = &tegra_pciex_clk_ops,
3669 .max_rate = 100000000,
3670 .u.periph = {
3671 .clk_num = 74,
3672 },
3673};
3674
3675/* Audio sync clocks */
3676#define SYNC_SOURCE(_id, _dev) \
3677 { \
3678 .name = #_id "_sync", \
3679 .lookup = { \
3680 .dev_id = #_dev , \
3681 .con_id = "ext_audio_sync", \
3682 }, \
3683 .rate = 24000000, \
3684 .max_rate = 24000000, \
3685 .ops = &tegra_sync_source_ops \
3686 }
3687static struct clk tegra_sync_source_list[] = {
3688 SYNC_SOURCE(spdif_in, tegra30-spdif),
3689 SYNC_SOURCE(i2s0, tegra30-i2s.0),
3690 SYNC_SOURCE(i2s1, tegra30-i2s.1),
3691 SYNC_SOURCE(i2s2, tegra30-i2s.2),
3692 SYNC_SOURCE(i2s3, tegra30-i2s.3),
3693 SYNC_SOURCE(i2s4, tegra30-i2s.4),
3694 SYNC_SOURCE(vimclk, vimclk),
3695};
3696
3697static struct clk_mux_sel mux_audio_sync_clk[] =
3698{
3699 { .input = &tegra_sync_source_list[0], .value = 0},
3700 { .input = &tegra_sync_source_list[1], .value = 1},
3701 { .input = &tegra_sync_source_list[2], .value = 2},
3702 { .input = &tegra_sync_source_list[3], .value = 3},
3703 { .input = &tegra_sync_source_list[4], .value = 4},
3704 { .input = &tegra_sync_source_list[5], .value = 5},
3705 { .input = &tegra_pll_a_out0, .value = 6},
3706 { .input = &tegra_sync_source_list[6], .value = 7},
3707 { 0, 0 }
3708};
3709
3710#define AUDIO_SYNC_CLK(_id, _dev, _index) \
3711 { \
3712 .name = #_id, \
3713 .lookup = { \
3714 .dev_id = #_dev, \
3715 .con_id = "audio_sync", \
3716 }, \
3717 .inputs = mux_audio_sync_clk, \
3718 .reg = 0x4A0 + (_index) * 4, \
3719 .max_rate = 24000000, \
3720 .ops = &tegra_audio_sync_clk_ops \
3721 }
3722static struct clk tegra_clk_audio_list[] = {
3723 AUDIO_SYNC_CLK(audio0, tegra30-i2s.0, 0),
3724 AUDIO_SYNC_CLK(audio1, tegra30-i2s.1, 1),
3725 AUDIO_SYNC_CLK(audio2, tegra30-i2s.2, 2),
3726 AUDIO_SYNC_CLK(audio3, tegra30-i2s.3, 3),
3727 AUDIO_SYNC_CLK(audio4, tegra30-i2s.4, 4),
3728 AUDIO_SYNC_CLK(audio, tegra30-spdif, 5),
3729};
3730
3731#define AUDIO_SYNC_2X_CLK(_id, _dev, _index) \
3732 { \
3733 .name = #_id "_2x", \
3734 .lookup = { \
3735 .dev_id = #_dev, \
3736 .con_id = "audio_sync_2x" \
3737 }, \
3738 .flags = PERIPH_NO_RESET, \
3739 .max_rate = 48000000, \
3740 .ops = &tegra_clk_double_ops, \
3741 .reg = 0x49C, \
3742 .reg_shift = 24 + (_index), \
3743 .parent = &tegra_clk_audio_list[(_index)], \
3744 .u.periph = { \
3745 .clk_num = 113 + (_index), \
3746 }, \
3747 }
3748static struct clk tegra_clk_audio_2x_list[] = {
3749 AUDIO_SYNC_2X_CLK(audio0, tegra30-i2s.0, 0),
3750 AUDIO_SYNC_2X_CLK(audio1, tegra30-i2s.1, 1),
3751 AUDIO_SYNC_2X_CLK(audio2, tegra30-i2s.2, 2),
3752 AUDIO_SYNC_2X_CLK(audio3, tegra30-i2s.3, 3),
3753 AUDIO_SYNC_2X_CLK(audio4, tegra30-i2s.4, 4),
3754 AUDIO_SYNC_2X_CLK(audio, tegra30-spdif, 5),
3755};
3756
3757#define MUX_I2S_SPDIF(_id, _index) \
3758static struct clk_mux_sel mux_pllaout0_##_id##_2x_pllp_clkm[] = { \
3759 {.input = &tegra_pll_a_out0, .value = 0}, \
3760 {.input = &tegra_clk_audio_2x_list[(_index)], .value = 1}, \
3761 {.input = &tegra_pll_p, .value = 2}, \
3762 {.input = &tegra_clk_m, .value = 3}, \
3763 { 0, 0}, \
3764}
3765MUX_I2S_SPDIF(audio0, 0);
3766MUX_I2S_SPDIF(audio1, 1);
3767MUX_I2S_SPDIF(audio2, 2);
3768MUX_I2S_SPDIF(audio3, 3);
3769MUX_I2S_SPDIF(audio4, 4);
3770MUX_I2S_SPDIF(audio, 5); /* SPDIF */
3771
3772/* External clock outputs (through PMC) */
3773#define MUX_EXTERN_OUT(_id) \
3774static struct clk_mux_sel mux_clkm_clkm2_clkm4_extern##_id[] = { \
3775 {.input = &tegra_clk_m, .value = 0}, \
3776 {.input = &tegra_clk_m_div2, .value = 1}, \
3777 {.input = &tegra_clk_m_div4, .value = 2}, \
3778 {.input = NULL, .value = 3}, /* placeholder */ \
3779 { 0, 0}, \
3780}
3781MUX_EXTERN_OUT(1);
3782MUX_EXTERN_OUT(2);
3783MUX_EXTERN_OUT(3);
3784
3785static struct clk_mux_sel *mux_extern_out_list[] = {
3786 mux_clkm_clkm2_clkm4_extern1,
3787 mux_clkm_clkm2_clkm4_extern2,
3788 mux_clkm_clkm2_clkm4_extern3,
3789};
3790
3791#define CLK_OUT_CLK(_id) \
3792 { \
3793 .name = "clk_out_" #_id, \
3794 .lookup = { \
3795 .dev_id = "clk_out_" #_id, \
3796 .con_id = "extern" #_id, \
3797 }, \
3798 .ops = &tegra_clk_out_ops, \
3799 .reg = 0x1a8, \
3800 .inputs = mux_clkm_clkm2_clkm4_extern##_id, \
3801 .flags = MUX_CLK_OUT, \
3802 .max_rate = 216000000, \
3803 .u.periph = { \
3804 .clk_num = (_id - 1) * 8 + 2, \
3805 }, \
3806 }
3807static struct clk tegra_clk_out_list[] = {
3808 CLK_OUT_CLK(1),
3809 CLK_OUT_CLK(2),
3810 CLK_OUT_CLK(3),
3811};
3812
3813/* called after peripheral external clocks are initialized */
3814static void init_clk_out_mux(void)
3815{
3816 int i;
3817 struct clk *c;
3818
3819 /* output clock con_id is the name of peripheral
3820 external clock connected to input 3 of the output mux */
3821 for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) {
3822 c = tegra_get_clock_by_name(
3823 tegra_clk_out_list[i].lookup.con_id);
3824 if (!c)
3825 pr_err("%s: could not find clk %s\n", __func__,
3826 tegra_clk_out_list[i].lookup.con_id);
3827 mux_extern_out_list[i][3].input = c;
3828 }
3829}
3830
3831/* Peripheral muxes */
3832static struct clk_mux_sel mux_cclk_g[] = {
3833 { .input = &tegra_clk_m, .value = 0},
3834 { .input = &tegra_pll_c, .value = 1},
3835 { .input = &tegra_clk_32k, .value = 2},
3836 { .input = &tegra_pll_m, .value = 3},
3837 { .input = &tegra_pll_p, .value = 4},
3838 { .input = &tegra_pll_p_out4, .value = 5},
3839 { .input = &tegra_pll_p_out3, .value = 6},
3840 /* { .input = &tegra_clk_d, .value = 7}, - no use on tegra3 */
3841 { .input = &tegra_pll_x, .value = 8},
3842 { 0, 0},
3843};
3844
3845static struct clk_mux_sel mux_cclk_lp[] = {
3846 { .input = &tegra_clk_m, .value = 0},
3847 { .input = &tegra_pll_c, .value = 1},
3848 { .input = &tegra_clk_32k, .value = 2},
3849 { .input = &tegra_pll_m, .value = 3},
3850 { .input = &tegra_pll_p, .value = 4},
3851 { .input = &tegra_pll_p_out4, .value = 5},
3852 { .input = &tegra_pll_p_out3, .value = 6},
3853 /* { .input = &tegra_clk_d, .value = 7}, - no use on tegra3 */
3854 { .input = &tegra_pll_x_out0, .value = 8},
3855 { .input = &tegra_pll_x, .value = 8 | SUPER_LP_DIV2_BYPASS},
3856 { 0, 0},
3857};
3858
3859static struct clk_mux_sel mux_sclk[] = {
3860 { .input = &tegra_clk_m, .value = 0},
3861 { .input = &tegra_pll_c_out1, .value = 1},
3862 { .input = &tegra_pll_p_out4, .value = 2},
3863 { .input = &tegra_pll_p_out3, .value = 3},
3864 { .input = &tegra_pll_p_out2, .value = 4},
3865 /* { .input = &tegra_clk_d, .value = 5}, - no use on tegra3 */
3866 { .input = &tegra_clk_32k, .value = 6},
3867 { .input = &tegra_pll_m_out1, .value = 7},
3868 { 0, 0},
3869};
3870
3871static struct clk tegra_clk_cclk_g = {
3872 .name = "cclk_g",
3873 .flags = DIV_U71 | DIV_U71_INT,
3874 .inputs = mux_cclk_g,
3875 .reg = 0x368,
3876 .ops = &tegra_super_ops,
3877 .max_rate = 1700000000,
3878};
3879
3880static struct clk tegra_clk_cclk_lp = {
3881 .name = "cclk_lp",
3882 .flags = DIV_2 | DIV_U71 | DIV_U71_INT,
3883 .inputs = mux_cclk_lp,
3884 .reg = 0x370,
3885 .ops = &tegra_super_ops,
3886 .max_rate = 620000000,
3887};
3888
3889static struct clk tegra_clk_sclk = {
3890 .name = "sclk",
3891 .inputs = mux_sclk,
3892 .reg = 0x28,
3893 .ops = &tegra_super_ops,
3894 .max_rate = 378000000,
3895 .min_rate = 40000000,
3896};
3897
3898static struct clk tegra_clk_virtual_cpu_g = {
3899 .name = "cpu_g",
3900 .parent = &tegra_clk_cclk_g,
3901 .ops = &tegra_cpu_ops,
3902 .max_rate = 1700000000,
3903 .u.cpu = {
3904 .main = &tegra_pll_x,
3905 .backup = &tegra_pll_p,
3906 .mode = MODE_G,
3907 },
3908};
3909
3910static struct clk tegra_clk_virtual_cpu_lp = {
3911 .name = "cpu_lp",
3912 .parent = &tegra_clk_cclk_lp,
3913 .ops = &tegra_cpu_ops,
3914 .max_rate = 620000000,
3915 .u.cpu = {
3916 .main = &tegra_pll_x,
3917 .backup = &tegra_pll_p,
3918 .mode = MODE_LP,
3919 },
3920};
3921
3922static struct clk_mux_sel mux_cpu_cmplx[] = {
3923 { .input = &tegra_clk_virtual_cpu_g, .value = 0},
3924 { .input = &tegra_clk_virtual_cpu_lp, .value = 1},
3925 { 0, 0},
3926};
3927
3928static struct clk tegra_clk_cpu_cmplx = {
3929 .name = "cpu",
3930 .inputs = mux_cpu_cmplx,
3931 .ops = &tegra_cpu_cmplx_ops,
3932 .max_rate = 1700000000,
3933};
3934
3935static struct clk tegra_clk_cop = {
3936 .name = "cop",
3937 .parent = &tegra_clk_sclk,
3938 .ops = &tegra_cop_ops,
3939 .max_rate = 378000000,
3940};
3941
3942static struct clk tegra_clk_hclk = {
3943 .name = "hclk",
3944 .flags = DIV_BUS,
3945 .parent = &tegra_clk_sclk,
3946 .reg = 0x30,
3947 .reg_shift = 4,
3948 .ops = &tegra_bus_ops,
3949 .max_rate = 378000000,
3950 .min_rate = 40000000,
3951};
3952
3953static struct clk tegra_clk_pclk = {
3954 .name = "pclk",
3955 .flags = DIV_BUS,
3956 .parent = &tegra_clk_hclk,
3957 .reg = 0x30,
3958 .reg_shift = 0,
3959 .ops = &tegra_bus_ops,
3960 .max_rate = 167000000,
3961 .min_rate = 40000000,
3962};
3963
3964static struct raw_notifier_head sbus_rate_change_nh;
3965
3966static struct clk tegra_clk_sbus_cmplx = {
3967 .name = "sbus",
3968 .parent = &tegra_clk_sclk,
3969 .ops = &tegra_sbus_cmplx_ops,
3970 .u.system = {
3971 .pclk = &tegra_clk_pclk,
3972 .hclk = &tegra_clk_hclk,
3973 .sclk_low = &tegra_pll_p_out4,
3974 .sclk_high = &tegra_pll_m_out1,
3975 },
3976 .rate_change_nh = &sbus_rate_change_nh,
3977};
3978
3979static struct clk tegra_clk_blink = {
3980 .name = "blink",
3981 .parent = &tegra_clk_32k,
3982 .reg = 0x40,
3983 .ops = &tegra_blink_clk_ops,
3984 .max_rate = 32768,
3985};
3986
3987static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
3988 { .input = &tegra_pll_m, .value = 0},
3989 { .input = &tegra_pll_c, .value = 1},
3990 { .input = &tegra_pll_p, .value = 2},
3991 { .input = &tegra_pll_a_out0, .value = 3},
3992 { 0, 0},
3993};
3994
3995static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
3996 { .input = &tegra_pll_m, .value = 0},
3997 /* { .input = &tegra_pll_c, .value = 1}, not used on tegra3 */
3998 { .input = &tegra_pll_p, .value = 2},
3999 { .input = &tegra_clk_m, .value = 3},
4000 { 0, 0},
4001};
4002
4003static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
4004 { .input = &tegra_pll_p, .value = 0},
4005 { .input = &tegra_pll_c, .value = 1},
4006#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
4007 { .input = &tegra_pll_m, .value = 2},
4008#endif
4009 { .input = &tegra_clk_m, .value = 3},
4010 { 0, 0},
4011};
4012
4013static struct clk_mux_sel mux_pllp_clkm[] = {
4014 { .input = &tegra_pll_p, .value = 0},
4015 { .input = &tegra_clk_m, .value = 3},
4016 { 0, 0},
4017};
4018
4019static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
4020 {.input = &tegra_pll_p, .value = 0},
4021 {.input = &tegra_pll_d_out0, .value = 1},
4022 {.input = &tegra_pll_c, .value = 2},
4023 {.input = &tegra_clk_m, .value = 3},
4024 { 0, 0},
4025};
4026
4027static struct clk_mux_sel mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
4028 {.input = &tegra_pll_p, .value = 0},
4029#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
4030 {.input = &tegra_pll_m, .value = 1},
4031#endif
4032 {.input = &tegra_pll_d_out0, .value = 2},
4033 {.input = &tegra_pll_a_out0, .value = 3},
4034 {.input = &tegra_pll_c, .value = 4},
4035 {.input = &tegra_pll_d2_out0, .value = 5},
4036 {.input = &tegra_clk_m, .value = 6},
4037 { 0, 0},
4038};
4039
4040static struct clk_mux_sel mux_plla_pllc_pllp_clkm[] = {
4041 { .input = &tegra_pll_a_out0, .value = 0},
4042 /* { .input = &tegra_pll_c, .value = 1}, no use on tegra3 */
4043 { .input = &tegra_pll_p, .value = 2},
4044 { .input = &tegra_clk_m, .value = 3},
4045 { 0, 0},
4046};
4047
4048static struct clk_mux_sel mux_pllp_pllc_clk32_clkm[] = {
4049 {.input = &tegra_pll_p, .value = 0},
4050 {.input = &tegra_pll_c, .value = 1},
4051 {.input = &tegra_clk_32k, .value = 2},
4052 {.input = &tegra_clk_m, .value = 3},
4053 { 0, 0},
4054};
4055
4056static struct clk_mux_sel mux_pllp_pllc_clkm_clk32[] = {
4057 {.input = &tegra_pll_p, .value = 0},
4058 {.input = &tegra_pll_c, .value = 1},
4059 {.input = &tegra_clk_m, .value = 2},
4060 {.input = &tegra_clk_32k, .value = 3},
4061 { 0, 0},
4062};
4063
4064static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
4065 {.input = &tegra_pll_p, .value = 0},
4066 {.input = &tegra_pll_c, .value = 1},
4067#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
4068 {.input = &tegra_pll_m, .value = 2},
4069#endif
4070 { 0, 0},
4071};
4072
4073static struct clk_mux_sel mux_clk_m[] = {
4074 { .input = &tegra_clk_m, .value = 0},
4075 { 0, 0},
4076};
4077
4078static struct clk_mux_sel mux_pllp_out3[] = {
4079 { .input = &tegra_pll_p_out3, .value = 0},
4080 { 0, 0},
4081};
4082
4083static struct clk_mux_sel mux_plld_out0[] = {
4084 { .input = &tegra_pll_d_out0, .value = 0},
4085 { 0, 0},
4086};
4087
4088static struct clk_mux_sel mux_plld_out0_plld2_out0[] = {
4089 { .input = &tegra_pll_d_out0, .value = 0},
4090 { .input = &tegra_pll_d2_out0, .value = 1},
4091 { 0, 0},
4092};
4093
4094static struct clk_mux_sel mux_clk_32k[] = {
4095 { .input = &tegra_clk_32k, .value = 0},
4096 { 0, 0},
4097};
4098
4099static struct clk_mux_sel mux_plla_clk32_pllp_clkm_plle[] = {
4100 { .input = &tegra_pll_a_out0, .value = 0},
4101 { .input = &tegra_clk_32k, .value = 1},
4102 { .input = &tegra_pll_p, .value = 2},
4103 { .input = &tegra_clk_m, .value = 3},
4104 { .input = &tegra_pll_e, .value = 4},
4105 { 0, 0},
4106};
4107
4108static struct raw_notifier_head emc_rate_change_nh;
4109
4110static struct clk tegra_clk_emc = {
4111 .name = "emc",
4112 .ops = &tegra_emc_clk_ops,
4113 .reg = 0x19c,
4114 .max_rate = 900000000,
4115 .min_rate = 12000000,
4116 .inputs = mux_pllm_pllc_pllp_clkm,
4117 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
4118 .u.periph = {
4119 .clk_num = 57,
4120 },
4121 .rate_change_nh = &emc_rate_change_nh,
4122};
4123
4124static struct clk tegra_clk_emc_bridge = {
4125 .name = "bridge.emc",
4126 .ops = &tegra_clk_emc_bridge_ops,
4127 .parent = &tegra_clk_emc,
4128};
4129
4130static struct clk tegra_clk_cbus = {
4131 .name = "cbus",
4132 .parent = &tegra_pll_c,
4133 .ops = &tegra_clk_cbus_ops,
4134 .max_rate = 700000000,
4135 .mul = 1,
4136 .div = 2,
4137 .flags = PERIPH_ON_CBUS,
4138 .shared_bus_backup = {
4139 .input = &tegra_pll_p,
4140 .value = 2,
4141 }
4142};
4143
4144#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
4145 { \
4146 .name = _name, \
4147 .lookup = { \
4148 .dev_id = _dev, \
4149 .con_id = _con, \
4150 }, \
4151 .ops = &tegra_periph_clk_ops, \
4152 .reg = _reg, \
4153 .inputs = _inputs, \
4154 .flags = _flags, \
4155 .max_rate = _max, \
4156 .u.periph = { \
4157 .clk_num = _clk_num, \
4158 }, \
4159 }
4160
4161#define PERIPH_CLK_EX(_name, _dev, _con, _clk_num, _reg, _max, _inputs, \
4162 _flags, _ops) \
4163 { \
4164 .name = _name, \
4165 .lookup = { \
4166 .dev_id = _dev, \
4167 .con_id = _con, \
4168 }, \
4169 .ops = _ops, \
4170 .reg = _reg, \
4171 .inputs = _inputs, \
4172 .flags = _flags, \
4173 .max_rate = _max, \
4174 .u.periph = { \
4175 .clk_num = _clk_num, \
4176 }, \
4177 }
4178
4179#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\
4180 { \
4181 .name = _name, \
4182 .lookup = { \
4183 .dev_id = _dev, \
4184 .con_id = _con, \
4185 }, \
4186 .ops = &tegra_clk_shared_bus_ops, \
4187 .parent = _parent, \
4188 .u.shared_bus_user = { \
4189 .client_id = _id, \
4190 .client_div = _div, \
4191 .mode = _mode, \
4192 }, \
4193 }
4194struct clk tegra_list_clks[] = {
4195 PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 26000000, mux_clk_m, 0),
4196 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB),
4197 PERIPH_CLK("kbc", "tegra-kbc", NULL, 36, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB),
4198 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
4199 PERIPH_CLK("kfuse", "kfuse-tegra", NULL, 40, 0, 26000000, mux_clk_m, 0),
4200 PERIPH_CLK("fuse", "fuse-tegra", "fuse", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB),
4201 PERIPH_CLK("fuse_burn", "fuse-tegra", "fuse_burn", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB),
4202 PERIPH_CLK("apbif", "tegra30-ahub", "apbif", 107, 0, 26000000, mux_clk_m, PERIPH_ON_APB),
4203 PERIPH_CLK("i2s0", "tegra30-i2s.0", "i2s", 30, 0x1d8, 26000000, mux_pllaout0_audio0_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4204 PERIPH_CLK("i2s1", "tegra30-i2s.1", "i2s", 11, 0x100, 26000000, mux_pllaout0_audio1_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4205 PERIPH_CLK("i2s2", "tegra30-i2s.2", "i2s", 18, 0x104, 26000000, mux_pllaout0_audio2_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4206 PERIPH_CLK("i2s3", "tegra30-i2s.3", "i2s", 101, 0x3bc, 26000000, mux_pllaout0_audio3_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4207 PERIPH_CLK("i2s4", "tegra30-i2s.4", "i2s", 102, 0x3c0, 26000000, mux_pllaout0_audio4_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4208 PERIPH_CLK("spdif_out", "tegra30-spdif", "spdif_out", 10, 0x108, 26000000, mux_pllaout0_audio_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4209 PERIPH_CLK("spdif_in", "tegra30-spdif", "spdif_in", 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71 | PERIPH_ON_APB),
4210 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 408000000, mux_pllp_pllc_clk32_clkm, MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
4211 PERIPH_CLK("d_audio", "tegra30-ahub", "d_audio", 106, 0x3d0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4212 PERIPH_CLK("dam0", "tegra30-dam.0", NULL, 108, 0x3d8, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
4213 PERIPH_CLK("dam1", "tegra30-dam.1", NULL, 109, 0x3dc, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
4214 PERIPH_CLK("dam2", "tegra30-dam.2", NULL, 110, 0x3e0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
4215 PERIPH_CLK("hda", "tegra30-hda", "hda", 125, 0x428, 108000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4216 PERIPH_CLK("hda2codec_2x", "tegra30-hda", "hda2codec", 111, 0x3e4, 48000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4217 PERIPH_CLK("hda2hdmi", "tegra30-hda", "hda2hdmi", 128, 0, 48000000, mux_clk_m, PERIPH_ON_APB),
4218 PERIPH_CLK("sbc1", "spi_tegra.0", "spi", 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4219 PERIPH_CLK("sbc2", "spi_tegra.1", "spi", 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4220 PERIPH_CLK("sbc3", "spi_tegra.2", "spi", 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4221 PERIPH_CLK("sbc4", "spi_tegra.3", "spi", 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4222 PERIPH_CLK("sbc5", "spi_tegra.4", "spi", 104, 0x3c8, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4223 PERIPH_CLK("sbc6", "spi_tegra.5", "spi", 105, 0x3cc, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4224 PERIPH_CLK("sata_oob", "tegra_sata_oob", NULL, 123, 0x420, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
4225 PERIPH_CLK("sata", "tegra_sata", NULL, 124, 0x424, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
4226 PERIPH_CLK("sata_cold", "tegra_sata_cold", NULL, 129, 0, 48000000, mux_clk_m, 0),
4227 PERIPH_CLK_EX("ndflash","tegra_nand", NULL, 13, 0x160, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71, &tegra_nand_clk_ops),
4228 PERIPH_CLK("ndspeed", "tegra_nand_speed", NULL, 80, 0x3f8, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
4229 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4230 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
4231 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
4232 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
4233 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
4234 PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0),
4235 PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0),
4236 PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0),
4237 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 600000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT),
4238 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
4239 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
4240 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4241 PERIPH_CLK("nor", "tegra-nor", NULL, 42, 0x1d0, 127000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
4242 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */
4243 PERIPH_CLK("i2c1", "tegra-i2c.0", "i2c-div", 12, 0x124, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
4244 PERIPH_CLK("i2c2", "tegra-i2c.1", "i2c-div", 54, 0x198, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
4245 PERIPH_CLK("i2c3", "tegra-i2c.2", "i2c-div", 67, 0x1b8, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
4246 PERIPH_CLK("i2c4", "tegra-i2c.3", "i2c-div", 103, 0x3c4, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
4247 PERIPH_CLK("i2c5", "tegra-i2c.4", "i2c-div", 47, 0x128, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
4248 PERIPH_CLK("i2c1-fast", "tegra-i2c.0", "i2c-fast", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
4249 PERIPH_CLK("i2c2-fast", "tegra-i2c.1", "i2c-fast", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
4250 PERIPH_CLK("i2c3-fast", "tegra-i2c.2", "i2c-fast", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
4251 PERIPH_CLK("i2c4-fast", "tegra-i2c.3", "i2c-fast", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
4252 PERIPH_CLK("i2c5-fast", "tegra-i2c.4", "i2c-fast", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
4253 PERIPH_CLK("uarta", "tegra_uart.0", NULL, 6, 0x178, 900000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4254 PERIPH_CLK("uartb", "tegra_uart.1", NULL, 7, 0x17c, 900000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4255 PERIPH_CLK("uartc", "tegra_uart.2", NULL, 55, 0x1a0, 900000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4256 PERIPH_CLK("uartd", "tegra_uart.3", NULL, 65, 0x1c0, 900000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4257 PERIPH_CLK("uarte", "tegra_uart.4", NULL, 66, 0x1c4, 900000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4258 PERIPH_CLK("uarta_dbg", "serial8250.0", "uarta", 6, 0x178, 900000000, mux_pllp_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4259 PERIPH_CLK("uartb_dbg", "serial8250.0", "uartb", 7, 0x17c, 900000000, mux_pllp_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4260 PERIPH_CLK("uartc_dbg", "serial8250.0", "uartc", 55, 0x1a0, 900000000, mux_pllp_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4261 PERIPH_CLK("uartd_dbg", "serial8250.0", "uartd", 65, 0x1c0, 900000000, mux_pllp_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4262 PERIPH_CLK("uarte_dbg", "serial8250.0", "uarte", 66, 0x1c4, 900000000, mux_pllp_clkm, MUX | DIV_U151 | DIV_U151_UART | PERIPH_ON_APB),
4263 PERIPH_CLK_EX("vi", "tegra_camera", "vi", 20, 0x148, 470000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT, &tegra_vi_clk_ops),
4264 PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET),
4265 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 600000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
4266 PERIPH_CLK("3d2", "3d2", NULL, 98, 0x3b0, 600000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
4267 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 600000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE),
4268 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 600000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
4269 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 600000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
4270 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
4271 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
4272 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
4273 PERIPH_CLK_EX("dtv", "dtv", NULL, 79, 0x1dc, 250000000, mux_clk_m, 0, &tegra_dtv_clk_ops),
4274 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8 | DIV_U71),
4275 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 220000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
4276 PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8),
4277 PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8),
4278 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
4279 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
4280 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
4281 PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0),
4282 PERIPH_CLK_EX("dsib", "tegradc.1", "dsib", 82, 0xd0, 500000000, mux_plld_out0_plld2_out0, MUX | PLLD, &tegra_dsib_clk_ops),
4283 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0),
4284 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
4285 PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
4286
4287 PERIPH_CLK("tsensor", "tegra-tsensor", NULL, 100, 0x3b8, 216000000, mux_pllp_pllc_clkm_clk32, MUX | DIV_U71),
4288 PERIPH_CLK("actmon", "actmon", NULL, 119, 0x3e8, 216000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71),
4289 PERIPH_CLK("extern1", "extern1", NULL, 120, 0x3ec, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71),
4290 PERIPH_CLK("extern2", "extern2", NULL, 121, 0x3f0, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71),
4291 PERIPH_CLK("extern3", "extern3", NULL, 122, 0x3f4, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71),
4292 PERIPH_CLK("i2cslow", "i2cslow", NULL, 81, 0x3fc, 26000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
4293 PERIPH_CLK("pcie", "tegra-pcie", "pcie", 70, 0, 250000000, mux_clk_m, 0),
4294 PERIPH_CLK("afi", "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0),
4295 PERIPH_CLK("se", "se", NULL, 127, 0x42c, 625000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT),
4296 PERIPH_CLK("mselect", "mselect", NULL, 99, 0x3b4, 108000000, mux_pllp_clkm, MUX | DIV_U71),
4297
4298 SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4299 SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4300 SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4301 SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4302 SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4303 SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4304 SHARED_CLK("mon.avp", "tegra_actmon", "avp", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4305 SHARED_CLK("cap.sclk", "cap_sclk", NULL, &tegra_clk_sbus_cmplx, NULL, 0, SHARED_CEILING),
4306 SHARED_CLK("floor.sclk", "floor_sclk", NULL, &tegra_clk_sbus_cmplx, NULL, 0, 0),
4307 SHARED_CLK("sbc1.sclk", "spi_tegra.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4308 SHARED_CLK("sbc2.sclk", "spi_tegra.1", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4309 SHARED_CLK("sbc3.sclk", "spi_tegra.2", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4310 SHARED_CLK("sbc4.sclk", "spi_tegra.3", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4311 SHARED_CLK("sbc5.sclk", "spi_tegra.4", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4312 SHARED_CLK("sbc6.sclk", "spi_tegra.5", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
4313
4314 SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc, NULL, 0, 0),
4315 SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc, NULL, 0, 0),
4316 SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc, NULL, 0, SHARED_BW),
4317 SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc, NULL, 0, SHARED_BW),
4318 SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc, NULL, 0, 0),
4319 SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc, NULL, 0, 0),
4320 SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc, NULL, 0, 0),
4321 SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc, NULL, 0, 0),
4322 SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc, NULL, 0, 0),
4323 SHARED_CLK("mon.emc", "tegra_actmon", "emc", &tegra_clk_emc, NULL, 0, 0),
4324 SHARED_CLK("cap.emc", "cap.emc", NULL, &tegra_clk_emc, NULL, 0, SHARED_CEILING),
4325 SHARED_CLK("3d.emc", "tegra_gr3d", "emc", &tegra_clk_emc, NULL, 0, 0),
4326 SHARED_CLK("2d.emc", "tegra_gr2d", "emc", &tegra_clk_emc, NULL, 0, 0),
4327 SHARED_CLK("mpe.emc", "tegra_mpe", "emc", &tegra_clk_emc, NULL, 0, 0),
4328 SHARED_CLK("camera.emc", "tegra_camera", "emc", &tegra_clk_emc, NULL, 0, 0),
4329 SHARED_CLK("floor.emc", "floor.emc", NULL, &tegra_clk_emc, NULL, 0, 0),
4330
4331 SHARED_CLK("host1x.cbus", "tegra_host1x", "host1x", &tegra_clk_cbus, "host1x", 2, SHARED_AUTO),
4332 SHARED_CLK("3d.cbus", "tegra_gr3d", "gr3d", &tegra_clk_cbus, "3d", 0, 0),
4333 SHARED_CLK("3d2.cbus", "tegra_gr3d", "gr3d2", &tegra_clk_cbus, "3d2", 0, 0),
4334 SHARED_CLK("2d.cbus", "tegra_gr2d", "gr2d", &tegra_clk_cbus, "2d", 0, 0),
4335 SHARED_CLK("epp.cbus", "tegra_gr2d", "epp", &tegra_clk_cbus, "epp", 0, 0),
4336 SHARED_CLK("mpe.cbus", "tegra_mpe", "mpe", &tegra_clk_cbus, "mpe", 0, 0),
4337 SHARED_CLK("vde.cbus", "tegra-avp", "vde", &tegra_clk_cbus, "vde", 0, 0),
4338 SHARED_CLK("se.cbus", "tegra-se", NULL, &tegra_clk_cbus, "se", 0, 0),
4339 SHARED_CLK("cap.cbus", "cap.cbus", NULL, &tegra_clk_cbus, NULL, 0, SHARED_CEILING),
4340 SHARED_CLK("floor.cbus", "floor.cbus", NULL, &tegra_clk_cbus, NULL, 0, 0),
4341};
4342
4343#define CLK_DUPLICATE(_name, _dev, _con) \
4344 { \
4345 .name = _name, \
4346 .lookup = { \
4347 .dev_id = _dev, \
4348 .con_id = _con, \
4349 }, \
4350 }
4351
4352/* Some clocks may be used by different drivers depending on the board
4353 * configuration. List those here to register them twice in the clock lookup
4354 * table under two names.
4355 */
4356struct clk_duplicate tegra_clk_duplicates[] = {
4357 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
4358 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
4359 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
4360 CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
4361 CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
4362 CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
4363 CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
4364 CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
4365 CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
4366 CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
4367 CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
4368 CLK_DUPLICATE("cop", "tegra-avp", "cop"),
4369 CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
4370 CLK_DUPLICATE("cop", "nvavp", "cop"),
4371 CLK_DUPLICATE("bsev", "nvavp", "bsev"),
4372 CLK_DUPLICATE("vde", "tegra-aes", "vde"),
4373 CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
4374 CLK_DUPLICATE("bsea", "nvavp", "bsea"),
4375 CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
4376 CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
4377 CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
4378 CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
4379 CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
4380 CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
4381 CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
4382 CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
4383 CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
4384 CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
4385 CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
4386 CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
4387 CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
4388 CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
4389 CLK_DUPLICATE("twd", "smp_twd", NULL),
4390 CLK_DUPLICATE("vcp", "nvavp", "vcp"),
4391 CLK_DUPLICATE("avp.sclk", "nvavp", "sclk"),
4392 CLK_DUPLICATE("avp.emc", "nvavp", "emc"),
4393 CLK_DUPLICATE("vde.cbus", "nvavp", "vde"),
4394};
4395
4396struct clk *tegra_ptr_clks[] = {
4397 &tegra_clk_32k,
4398 &tegra_clk_m,
4399 &tegra_clk_m_div2,
4400 &tegra_clk_m_div4,
4401 &tegra_pll_ref,
4402 &tegra_pll_m,
4403 &tegra_pll_m_out1,
4404 &tegra_pll_c,
4405 &tegra_pll_c_out1,
4406 &tegra_pll_p,
4407 &tegra_pll_p_out1,
4408 &tegra_pll_p_out2,
4409 &tegra_pll_p_out3,
4410 &tegra_pll_p_out4,
4411 &tegra_pll_a,
4412 &tegra_pll_a_out0,
4413 &tegra_pll_d,
4414 &tegra_pll_d_out0,
4415 &tegra_pll_d2,
4416 &tegra_pll_d2_out0,
4417 &tegra_pll_u,
4418 &tegra_pll_x,
4419 &tegra_pll_x_out0,
4420 &tegra_pll_e,
4421 &tegra_cml0_clk,
4422 &tegra_cml1_clk,
4423 &tegra_pciex_clk,
4424 &tegra_clk_cclk_g,
4425 &tegra_clk_cclk_lp,
4426 &tegra_clk_sclk,
4427 &tegra_clk_hclk,
4428 &tegra_clk_pclk,
4429 &tegra_clk_virtual_cpu_g,
4430 &tegra_clk_virtual_cpu_lp,
4431 &tegra_clk_cpu_cmplx,
4432 &tegra_clk_blink,
4433 &tegra_clk_cop,
4434 &tegra_clk_sbus_cmplx,
4435 &tegra_clk_emc,
4436 &tegra3_clk_twd,
4437 &tegra_clk_emc_bridge,
4438 &tegra_clk_cbus,
4439};
4440
4441/*
4442 * Backup rate targets for each CPU mode is selected below Fmax(Vmin), and
4443 * high enough to avoid voltage droop when CPU clock is switched between
4444 * backup and main clock sources. Actual backup rates will be rounded based
4445 * on backup source fixed frequency. Maximum stay-on-backup rate will be set
4446 * as a minimum of G and LP backup rates to be supported in both modes.
4447 *
4448 * Sbus threshold must be exact factor of pll_p rate.
4449 */
4450#define CPU_G_BACKUP_RATE_TARGET 440000000
4451#define CPU_LP_BACKUP_RATE_TARGET 220000000
4452
4453static void tegra3_pllp_init_dependencies(unsigned long pllp_rate)
4454{
4455 u32 div;
4456 unsigned long backup_rate;
4457
4458 switch (pllp_rate) {
4459 case 216000000:
4460 tegra_pll_p_out1.u.pll_div.default_rate = 28800000;
4461 tegra_pll_p_out3.u.pll_div.default_rate = 72000000;
4462 tegra_clk_sbus_cmplx.u.system.threshold = 108000000;
4463 break;
4464 case 408000000:
4465 tegra_pll_p_out1.u.pll_div.default_rate = 9600000;
4466 tegra_pll_p_out3.u.pll_div.default_rate = 102000000;
4467 tegra_clk_sbus_cmplx.u.system.threshold = 204000000;
4468 break;
4469 case 204000000:
4470 tegra_pll_p_out1.u.pll_div.default_rate = 4800000;
4471 tegra_pll_p_out3.u.pll_div.default_rate = 102000000;
4472 tegra_clk_sbus_cmplx.u.system.threshold = 204000000;
4473 break;
4474 default:
4475 pr_err("tegra: PLLP rate: %lu is not supported\n", pllp_rate);
4476 BUG();
4477 }
4478 pr_info("tegra: PLLP fixed rate: %lu\n", pllp_rate);
4479
4480 div = DIV_ROUND_UP(pllp_rate, CPU_G_BACKUP_RATE_TARGET);
4481 backup_rate = pllp_rate / div;
4482 tegra_clk_cclk_g.u.cclk.div71 = 2 * div - 2;
4483 tegra_clk_virtual_cpu_g.u.cpu.backup_rate = backup_rate;
4484 cpu_stay_on_backup_max = backup_rate;
4485
4486 div = DIV_ROUND_UP(pllp_rate, CPU_LP_BACKUP_RATE_TARGET);
4487 backup_rate = pllp_rate / div;
4488 tegra_clk_cclk_lp.u.cclk.div71 = 2 * div - 2;
4489 tegra_clk_virtual_cpu_lp.u.cpu.backup_rate = backup_rate;
4490 cpu_stay_on_backup_max = min(cpu_stay_on_backup_max, backup_rate);
4491}
4492
4493bool tegra_clk_is_parent_allowed(struct clk *c, struct clk *p)
4494{
4495 if (c->flags & PERIPH_ON_CBUS)
4496 return p != &tegra_pll_m;
4497 else
4498 return p != &tegra_pll_c;
4499
4500 return true;
4501}
4502
4503static void tegra3_init_one_clock(struct clk *c)
4504{
4505 clk_init(c);
4506 INIT_LIST_HEAD(&c->shared_bus_list);
4507 if (!c->lookup.dev_id && !c->lookup.con_id)
4508 c->lookup.con_id = c->name;
4509 c->lookup.clk = c;
4510 clkdev_add(&c->lookup);
4511}
4512
4513/*
4514 * Emergency throttle of G-CPU by setting G-super clock skipper underneath
4515 * clock framework, dvfs, and cpufreq driver s/w layers. Can be called in
4516 * ISR context for EDP events. When releasing throttle, LP-divider is cleared
4517 * just in case it was set as a result of save/restore operations across
4518 * cluster switch (should not happen)
4519 */
4520void tegra_edp_throttle_cpu_now(u8 factor)
4521{
4522 if (factor > 1) {
4523 if (!is_lp_cluster())
4524 tegra3_super_clk_skipper_update(
4525 &tegra_clk_cclk_g, 1, factor);
4526 } else if (factor == 0) {
4527 tegra3_super_clk_skipper_update(&tegra_clk_cclk_g, 0, 0);
4528 tegra3_super_clk_skipper_update(&tegra_clk_cclk_lp, 0, 0);
4529 }
4530}
4531
4532#ifdef CONFIG_CPU_FREQ
4533
4534/*
4535 * Frequency table index must be sequential starting at 0 and frequencies
4536 * must be ascending. Re-configurable PLLX is used as a source for rates
4537 * above 204MHz. Rates 204MHz and below are divided down from fixed frequency
4538 * PLLP that may run either at 408MHz or at 204MHz on Tegra3 silicon platforms
4539 * (on FPGA platform PLLP output is reported as 216MHz, but no respective
4540 * tables are provided, since there is no clock scaling on FPGA at all).
4541 */
4542
4543static struct cpufreq_frequency_table freq_table_300MHz[] = {
4544 { 0, 204000 },
4545 { 1, 300000 },
4546 { 2, CPUFREQ_TABLE_END },
4547};
4548
4549static struct cpufreq_frequency_table freq_table_1p0GHz[] = {
4550 { 0, 51000 },
4551 { 1, 102000 },
4552 { 2, 204000 },
4553 { 3, 312000 },
4554 { 4, 456000 },
4555 { 5, 608000 },
4556 { 6, 760000 },
4557 { 7, 816000 },
4558 { 8, 912000 },
4559 { 9, 1000000 },
4560 {10, CPUFREQ_TABLE_END },
4561};
4562
4563static struct cpufreq_frequency_table freq_table_1p3GHz[] = {
4564 { 0, 51000 },
4565 { 1, 102000 },
4566 { 2, 204000 },
4567 { 3, 340000 },
4568 { 4, 475000 },
4569 { 5, 640000 },
4570 { 6, 760000 },
4571 { 7, 860000 },
4572 { 8, 1000000 },
4573 { 9, 1100000 },
4574 {10, 1200000 },
4575 {11, 1300000 },
4576 {12, CPUFREQ_TABLE_END },
4577};
4578
4579static struct cpufreq_frequency_table freq_table_1p4GHz[] = {
4580 { 0, 51000 },
4581 { 1, 102000 },
4582 { 2, 204000 },
4583 { 3, 370000 },
4584 { 4, 475000 },
4585 { 5, 620000 },
4586 { 6, 760000 },
4587 { 7, 860000 },
4588 { 8, 1000000 },
4589 { 9, 1100000 },
4590 {10, 1200000 },
4591 {11, 1300000 },
4592 {12, 1400000 },
4593 {13, CPUFREQ_TABLE_END },
4594};
4595
4596static struct cpufreq_frequency_table freq_table_1p5GHz[] = {
4597 { 0, 51000 },
4598 { 1, 102000 },
4599 { 2, 204000 },
4600 { 3, 340000 },
4601 { 4, 475000 },
4602 { 5, 640000 },
4603 { 6, 760000 },
4604 { 7, 860000 },
4605 { 8, 1000000 },
4606 { 9, 1100000 },
4607 {10, 1200000 },
4608 {11, 1300000 },
4609 {12, 1400000 },
4610 {13, 1500000 },
4611 {14, CPUFREQ_TABLE_END },
4612};
4613
4614static struct cpufreq_frequency_table freq_table_1p7GHz[] = {
4615 { 0, 51000 },
4616 { 1, 102000 },
4617 { 2, 204000 },
4618 { 3, 370000 },
4619 { 4, 475000 },
4620 { 5, 620000 },
4621 { 6, 760000 },
4622 { 7, 910000 },
4623 { 8, 1150000 },
4624 { 9, 1300000 },
4625 {10, 1400000 },
4626 {11, 1500000 },
4627 {12, 1600000 },
4628 {13, 1700000 },
4629 {14, CPUFREQ_TABLE_END },
4630};
4631
4632static struct tegra_cpufreq_table_data cpufreq_tables[] = {
4633 { freq_table_300MHz, 0, 1 },
4634 { freq_table_1p0GHz, 2, 8 },
4635 { freq_table_1p3GHz, 2, 10 },
4636 { freq_table_1p4GHz, 2, 11 },
4637 { freq_table_1p5GHz, 2, 12 },
4638 { freq_table_1p7GHz, 2, 12 },
4639};
4640
4641static int clip_cpu_rate_limits(
4642 struct tegra_cpufreq_table_data *data,
4643 struct cpufreq_policy *policy,
4644 struct clk *cpu_clk_g,
4645 struct clk *cpu_clk_lp)
4646{
4647 int idx, ret;
4648 struct cpufreq_frequency_table *freq_table = data->freq_table;
4649
4650 /* clip CPU G mode maximum frequency to table entry */
4651 ret = cpufreq_frequency_table_target(policy, freq_table,
4652 cpu_clk_g->max_rate / 1000, CPUFREQ_RELATION_H, &idx);
4653 if (ret) {
4654 pr_err("%s: G CPU max rate %lu outside of cpufreq table",
4655 __func__, cpu_clk_g->max_rate);
4656 return ret;
4657 }
4658 cpu_clk_g->max_rate = freq_table[idx].frequency * 1000;
4659 if (cpu_clk_g->max_rate < cpu_clk_lp->max_rate) {
4660 pr_err("%s: G CPU max rate %lu is below LP CPU max rate %lu",
4661 __func__, cpu_clk_g->max_rate, cpu_clk_lp->max_rate);
4662 return -EINVAL;
4663 }
4664
4665 /* clip CPU LP mode maximum frequency to table entry, and
4666 set CPU G mode minimum frequency one table step below */
4667 ret = cpufreq_frequency_table_target(policy, freq_table,
4668 cpu_clk_lp->max_rate / 1000, CPUFREQ_RELATION_H, &idx);
4669 if (ret || !idx) {
4670 pr_err("%s: LP CPU max rate %lu %s of cpufreq table", __func__,
4671 cpu_clk_lp->max_rate, ret ? "outside" : "at the bottom");
4672 return ret;
4673 }
4674 cpu_clk_lp->max_rate = freq_table[idx].frequency * 1000;
4675 cpu_clk_g->min_rate = freq_table[idx-1].frequency * 1000;
4676 data->suspend_index = idx;
4677 return 0;
4678}
4679
4680struct tegra_cpufreq_table_data *tegra_cpufreq_table_get(void)
4681{
4682 int i, ret;
4683 unsigned long selection_rate;
4684 struct clk *cpu_clk_g = tegra_get_clock_by_name("cpu_g");
4685 struct clk *cpu_clk_lp = tegra_get_clock_by_name("cpu_lp");
4686
4687 /* For table selection use top cpu_g rate in dvfs ladder; selection
4688 rate may exceed cpu max_rate (e.g., because of edp limitations on
4689 cpu voltage) - in any case max_rate will be clipped to the table */
4690 if (cpu_clk_g->dvfs && cpu_clk_g->dvfs->num_freqs)
4691 selection_rate =
4692 cpu_clk_g->dvfs->freqs[cpu_clk_g->dvfs->num_freqs - 1];
4693 else
4694 selection_rate = cpu_clk_g->max_rate;
4695
4696 for (i = 0; i < ARRAY_SIZE(cpufreq_tables); i++) {
4697 struct cpufreq_policy policy;
4698 policy.cpu = 0; /* any on-line cpu */
4699 ret = cpufreq_frequency_table_cpuinfo(
4700 &policy, cpufreq_tables[i].freq_table);
4701 if (!ret) {
4702 if ((policy.max * 1000) == selection_rate) {
4703 ret = clip_cpu_rate_limits(
4704 &cpufreq_tables[i],
4705 &policy, cpu_clk_g, cpu_clk_lp);
4706 if (!ret)
4707 return &cpufreq_tables[i];
4708 }
4709 }
4710 }
4711 WARN(1, "%s: No cpufreq table matching G & LP cpu ranges", __func__);
4712 return NULL;
4713}
4714
4715/* On DDR3 platforms there is an implicit dependency in this mapping: when cpu
4716 * exceeds max dvfs level for LP CPU clock at TEGRA_EMC_BRIDGE_MVOLTS_MIN, the
4717 * respective emc rate should be above TEGRA_EMC_BRIDGE_RATE_MIN
4718 */
4719/* FIXME: explicitly check this dependency */
4720unsigned long tegra_emc_to_cpu_ratio(unsigned long cpu_rate)
4721{
4722 static unsigned long emc_max_rate = 0;
4723
4724 if (emc_max_rate == 0)
4725 emc_max_rate = clk_round_rate(
4726 tegra_get_clock_by_name("emc"), ULONG_MAX);
4727
4728 /* Vote on memory bus frequency based on cpu frequency;
4729 cpu rate is in kHz, emc rate is in Hz */
4730 if (cpu_rate >= 750000)
4731 return emc_max_rate; /* cpu >= 750 MHz, emc max */
4732 else if (cpu_rate >= 450000)
4733 return emc_max_rate/2; /* cpu >= 500 MHz, emc max/2 */
4734 else if (cpu_rate >= 250000)
4735 return 100000000; /* cpu >= 250 MHz, emc 100 MHz */
4736 else
4737 return 0; /* emc min */
4738}
4739
4740int tegra_update_mselect_rate(unsigned long cpu_rate)
4741{
4742 static struct clk *mselect = NULL;
4743
4744 unsigned long mselect_rate;
4745
4746 if (!mselect) {
4747 mselect = tegra_get_clock_by_name("mselect");
4748 if (!mselect)
4749 return -ENODEV;
4750 }
4751
4752 /* Vote on mselect frequency based on cpu frequency:
4753 keep mselect at half of cpu rate up to 102 MHz;
4754 cpu rate is in kHz, mselect rate is in Hz */
4755 mselect_rate = DIV_ROUND_UP(cpu_rate, 2) * 1000;
4756 mselect_rate = min(mselect_rate, 102000000UL);
4757
4758 if (mselect_rate != clk_get_rate(mselect))
4759 return clk_set_rate(mselect, mselect_rate);
4760
4761 return 0;
4762}
4763#endif
4764
4765#ifdef CONFIG_PM_SLEEP
4766static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
4767 PERIPH_CLK_SOURCE_NUM + 24];
4768
4769static int tegra_clk_suspend(void)
4770{
4771 unsigned long off;
4772 u32 *ctx = clk_rst_suspend;
4773
4774 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
4775 *ctx++ = clk_readl(CPU_SOFTRST_CTRL);
4776
4777 *ctx++ = clk_readl(tegra_pll_p_out1.reg);
4778 *ctx++ = clk_readl(tegra_pll_p_out3.reg);
4779
4780 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
4781 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
4782 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
4783 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
4784 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
4785 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
4786 *ctx++ = clk_readl(tegra_pll_d2.reg + PLL_BASE);
4787 *ctx++ = clk_readl(tegra_pll_d2.reg + PLL_MISC(&tegra_pll_d2));
4788
4789 *ctx++ = clk_readl(tegra_pll_m_out1.reg);
4790 *ctx++ = clk_readl(tegra_pll_a_out0.reg);
4791 *ctx++ = clk_readl(tegra_pll_c_out1.reg);
4792
4793 *ctx++ = clk_readl(tegra_clk_cclk_g.reg);
4794 *ctx++ = clk_readl(tegra_clk_cclk_g.reg + SUPER_CLK_DIVIDER);
4795 *ctx++ = clk_readl(tegra_clk_cclk_lp.reg);
4796 *ctx++ = clk_readl(tegra_clk_cclk_lp.reg + SUPER_CLK_DIVIDER);
4797
4798 *ctx++ = clk_readl(tegra_clk_sclk.reg);
4799 *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
4800 *ctx++ = clk_readl(tegra_clk_pclk.reg);
4801
4802 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
4803 off += 4) {
4804 if (off == PERIPH_CLK_SOURCE_EMC)
4805 continue;
4806 *ctx++ = clk_readl(off);
4807 }
4808 for (off = PERIPH_CLK_SOURCE_G3D2; off <= PERIPH_CLK_SOURCE_SE;
4809 off+=4) {
4810 *ctx++ = clk_readl(off);
4811 }
4812 for (off = AUDIO_DLY_CLK; off <= AUDIO_SYNC_CLK_SPDIF; off+=4) {
4813 *ctx++ = clk_readl(off);
4814 }
4815
4816 *ctx++ = clk_readl(RST_DEVICES_L);
4817 *ctx++ = clk_readl(RST_DEVICES_H);
4818 *ctx++ = clk_readl(RST_DEVICES_U);
4819 *ctx++ = clk_readl(RST_DEVICES_V);
4820 *ctx++ = clk_readl(RST_DEVICES_W);
4821
4822 *ctx++ = clk_readl(CLK_OUT_ENB_L);
4823 *ctx++ = clk_readl(CLK_OUT_ENB_H);
4824 *ctx++ = clk_readl(CLK_OUT_ENB_U);
4825 *ctx++ = clk_readl(CLK_OUT_ENB_V);
4826 *ctx++ = clk_readl(CLK_OUT_ENB_W);
4827
4828 *ctx++ = clk_readl(MISC_CLK_ENB);
4829 *ctx++ = clk_readl(CLK_MASK_ARM);
4830
4831 return 0;
4832}
4833
4834static void tegra_clk_resume(void)
4835{
4836 unsigned long off;
4837 const u32 *ctx = clk_rst_suspend;
4838 u32 val;
4839 u32 pllc_base;
4840 u32 plla_base;
4841 u32 plld_base;
4842 u32 plld2_base;
4843 u32 pll_p_out12, pll_p_out34;
4844 u32 pll_a_out0, pll_m_out1, pll_c_out1;
4845 struct clk *p;
4846
4847 val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
4848 val |= *ctx++;
4849 clk_writel(val, OSC_CTRL);
4850 clk_writel(*ctx++, CPU_SOFTRST_CTRL);
4851
4852 /* Since we are going to reset devices and switch clock sources in this
4853 * function, plls and secondary dividers is required to be enabled. The
4854 * actual value will be restored back later. Note that boot plls: pllm,
4855 * pllp, and pllu are already configured and enabled.
4856 */
4857 val = PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
4858 val |= val << 16;
4859 pll_p_out12 = *ctx++;
4860 clk_writel(pll_p_out12 | val, tegra_pll_p_out1.reg);
4861 pll_p_out34 = *ctx++;
4862 clk_writel(pll_p_out34 | val, tegra_pll_p_out3.reg);
4863
4864 pllc_base = *ctx++;
4865 clk_writel(pllc_base | PLL_BASE_ENABLE, tegra_pll_c.reg + PLL_BASE);
4866 clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
4867
4868 plla_base = *ctx++;
4869 clk_writel(plla_base | PLL_BASE_ENABLE, tegra_pll_a.reg + PLL_BASE);
4870 clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
4871
4872 plld_base = *ctx++;
4873 clk_writel(plld_base | PLL_BASE_ENABLE, tegra_pll_d.reg + PLL_BASE);
4874 clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
4875
4876 plld2_base = *ctx++;
4877 clk_writel(plld2_base | PLL_BASE_ENABLE, tegra_pll_d2.reg + PLL_BASE);
4878 clk_writel(*ctx++, tegra_pll_d2.reg + PLL_MISC(&tegra_pll_d2));
4879
4880 udelay(1000);
4881
4882 val = PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
4883 pll_m_out1 = *ctx++;
4884 clk_writel(pll_m_out1 | val, tegra_pll_m_out1.reg);
4885 pll_a_out0 = *ctx++;
4886 clk_writel(pll_a_out0 | val, tegra_pll_a_out0.reg);
4887 pll_c_out1 = *ctx++;
4888 clk_writel(pll_c_out1 | val, tegra_pll_c_out1.reg);
4889
4890 clk_writel(*ctx++, tegra_clk_cclk_g.reg);
4891 clk_writel(*ctx++, tegra_clk_cclk_g.reg + SUPER_CLK_DIVIDER);
4892 clk_writel(*ctx++, tegra_clk_cclk_lp.reg);
4893 clk_writel(*ctx++, tegra_clk_cclk_lp.reg + SUPER_CLK_DIVIDER);
4894
4895 clk_writel(*ctx++, tegra_clk_sclk.reg);
4896 clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
4897 clk_writel(*ctx++, tegra_clk_pclk.reg);
4898
4899 /* enable all clocks before configuring clock sources */
4900 clk_writel(0xfdfffff1ul, CLK_OUT_ENB_L);
4901 clk_writel(0xfefff7f7ul, CLK_OUT_ENB_H);
4902 clk_writel(0x75f79bfful, CLK_OUT_ENB_U);
4903 clk_writel(0xfffffffful, CLK_OUT_ENB_V);
4904 clk_writel(0x00003ffful, CLK_OUT_ENB_W);
4905 wmb();
4906
4907 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
4908 off += 4) {
4909 if (off == PERIPH_CLK_SOURCE_EMC)
4910 continue;
4911 clk_writel(*ctx++, off);
4912 }
4913 for (off = PERIPH_CLK_SOURCE_G3D2; off <= PERIPH_CLK_SOURCE_SE;
4914 off += 4) {
4915 clk_writel(*ctx++, off);
4916 }
4917 for (off = AUDIO_DLY_CLK; off <= AUDIO_SYNC_CLK_SPDIF; off+=4) {
4918 clk_writel(*ctx++, off);
4919 }
4920 wmb();
4921
4922 clk_writel(*ctx++, RST_DEVICES_L);
4923 clk_writel(*ctx++, RST_DEVICES_H);
4924 clk_writel(*ctx++, RST_DEVICES_U);
4925
4926 /* For LP0 resume, don't reset lpcpu, since we are running from it */
4927 val = *ctx++;
4928 val &= ~RST_DEVICES_V_SWR_CPULP_RST_DIS;
4929 clk_writel(val, RST_DEVICES_V);
4930
4931 clk_writel(*ctx++, RST_DEVICES_W);
4932 wmb();
4933
4934 clk_writel(*ctx++, CLK_OUT_ENB_L);
4935 clk_writel(*ctx++, CLK_OUT_ENB_H);
4936 clk_writel(*ctx++, CLK_OUT_ENB_U);
4937
4938 /* For LP0 resume, clk to lpcpu is required to be on */
4939 val = *ctx++;
4940 val |= CLK_OUT_ENB_V_CLK_ENB_CPULP_EN;
4941 clk_writel(val, CLK_OUT_ENB_V);
4942
4943 clk_writel(*ctx++, CLK_OUT_ENB_W);
4944 wmb();
4945
4946 clk_writel(*ctx++, MISC_CLK_ENB);
4947 clk_writel(*ctx++, CLK_MASK_ARM);
4948
4949 /* Restore back the actual pll and secondary divider values */
4950 /* FIXME: need to root cause why pllc is required to be on
4951 * clk_writel(pllc_base, tegra_pll_c.reg + PLL_BASE);
4952 */
4953 clk_writel(pll_p_out12, tegra_pll_p_out1.reg);
4954 clk_writel(pll_p_out34, tegra_pll_p_out3.reg);
4955
4956 clk_writel(plla_base, tegra_pll_a.reg + PLL_BASE);
4957 clk_writel(plld_base, tegra_pll_d.reg + PLL_BASE);
4958 clk_writel(plld2_base, tegra_pll_d2.reg + PLL_BASE);
4959
4960 clk_writel(pll_m_out1, tegra_pll_m_out1.reg);
4961 clk_writel(pll_a_out0, tegra_pll_a_out0.reg);
4962 clk_writel(pll_c_out1, tegra_pll_c_out1.reg);
4963
4964 /* Since EMC clock is not restored, and may not preserve parent across
4965 suspend, update current state, and mark EMC DFS as out of sync */
4966 p = tegra_clk_emc.parent;
4967 tegra3_periph_clk_init(&tegra_clk_emc);
4968
4969 if (p != tegra_clk_emc.parent) {
4970 /* FIXME: old parent is left enabled here even if EMC was its
4971 only child before suspend (never happens on Tegra3) */
4972 pr_debug("EMC parent(refcount) across suspend: %s(%d) : %s(%d)",
4973 p->name, p->refcnt, tegra_clk_emc.parent->name,
4974 tegra_clk_emc.parent->refcnt);
4975
4976 BUG_ON(!p->refcnt);
4977 p->refcnt--;
4978
4979 /* the new parent is enabled by low level code, but ref count
4980 need to be updated up to the root */
4981 p = tegra_clk_emc.parent;
4982 while (p && ((p->refcnt++) == 0))
4983 p = p->parent;
4984 }
4985 tegra_emc_timing_invalidate();
4986
4987 tegra3_pll_clk_init(&tegra_pll_u); /* Re-init utmi parameters */
4988 tegra3_pllp_clk_resume(&tegra_pll_p); /* Fire a bug if not restored */
4989}
4990#else
4991#define tegra_clk_suspend NULL
4992#define tegra_clk_resume NULL
4993#endif
4994
4995static struct syscore_ops tegra_clk_syscore_ops = {
4996 .suspend = tegra_clk_suspend,
4997 .resume = tegra_clk_resume,
4998};
4999
5000#ifdef CONFIG_TEGRA_PREINIT_CLOCKS
5001
5002#define CLK_RSTENB_DEV_V_0_DAM2_BIT (1 << 14)
5003#define CLK_RSTENB_DEV_V_0_DAM1_BIT (1 << 13)
5004#define CLK_RSTENB_DEV_V_0_DAM0_BIT (1 << 12)
5005#define CLK_RSTENB_DEV_V_0_AUDIO_BIT (1 << 10)
5006
5007#define CLK_RSTENB_DEV_L_0_HOST1X_BIT (1 << 28)
5008#define CLK_RSTENB_DEV_L_0_DISP1_BIT (1 << 27)
5009
5010#define DISP1_CLK_REG_OFFSET 0x138
5011#define DISP1_CLK_SRC_SHIFT 29
5012#define DISP1_CLK_SRC_MASK (0x7 << DISP1_CLK_SRC_SHIFT)
5013#define DISP1_CLK_SRC_PLLP_OUT0 0
5014#define DISP1_CLK_SRC_PLLM_OUT0 1
5015#define DISP1_CLK_SRC_PLLD_OUT0 2
5016#define DISP1_CLK_SRC_PLLA_OUT0 3
5017#define DISP1_CLK_SRC_PLLC_OUT0 4
5018#define DISP1_CLK_SRC_PLLD2_OUT0 5
5019#define DISP1_CLK_SRC_CLKM 6
5020#define DISP1_CLK_SRC_DEFAULT (DISP1_CLK_SRC_PLLP_OUT0 << DISP1_CLK_SRC_SHIFT)
5021
5022#define HOST1X_CLK_REG_OFFSET 0x180
5023#define HOST1X_CLK_SRC_SHIFT 30
5024#define HOST1X_CLK_SRC_MASK (0x3 << HOST1X_CLK_SRC_SHIFT)
5025#define HOST1X_CLK_SRC_PLLM_OUT0 0
5026#define HOST1X_CLK_SRC_PLLC_OUT0 1
5027#define HOST1X_CLK_SRC_PLLP_OUT0 2
5028#define HOST1X_CLK_SRC_PLLA_OUT0 3
5029#define HOST1X_CLK_SRC_DEFAULT (\
5030 HOST1X_CLK_SRC_PLLP_OUT0 << HOST1X_CLK_SRC_SHIFT)
5031#define HOST1X_CLK_IDLE_DIV_SHIFT 8
5032#define HOST1X_CLK_IDLE_DIV_MASK (0xff << HOST1X_CLK_IDLE_DIV_SHIFT)
5033#define HOST1X_CLK_IDLE_DIV_DEFAULT (0 << HOST1X_CLK_IDLE_DIV_SHIFT)
5034#define HOST1X_CLK_DIV_SHIFT 0
5035#define HOST1X_CLK_DIV_MASK (0xff << HOST1X_CLK_DIV_SHIFT)
5036#define HOST1X_CLK_DIV_DEFAULT (3 << HOST1X_CLK_DIV_SHIFT)
5037
5038#define AUDIO_CLK_REG_OFFSET 0x3d0
5039#define DAM0_CLK_REG_OFFSET 0x3d8
5040#define DAM1_CLK_REG_OFFSET 0x3dc
5041#define DAM2_CLK_REG_OFFSET 0x3e0
5042#define AUDIO_CLK_SRC_SHIFT 28
5043#define AUDIO_CLK_SRC_MASK (0x0f << AUDIO_CLK_SRC_SHIFT)
5044#define AUDIO_CLK_SRC_PLLA_OUT0 0x01
5045#define AUDIO_CLK_SRC_PLLC_OUT0 0x05
5046#define AUDIO_CLK_SRC_PLLP_OUT0 0x09
5047#define AUDIO_CLK_SRC_CLKM 0x0d
5048#define AUDIO_CLK_SRC_DEFAULT (\
5049 AUDIO_CLK_SRC_CLKM << AUDIO_CLK_SRC_SHIFT)
5050#define AUDIO_CLK_DIV_SHIFT 0
5051#define AUDIO_CLK_DIV_MASK (0xff << AUDIO_CLK_DIV_SHIFT)
5052#define AUDIO_CLK_DIV_DEFAULT (\
5053 (0 << AUDIO_CLK_DIV_SHIFT))
5054
5055static void __init clk_setbit(u32 reg, u32 bit)
5056{
5057 u32 val = clk_readl(reg);
5058
5059 if ((val & bit) == bit)
5060 return;
5061 val |= bit;
5062 clk_writel(val, reg);
5063 udelay(2);
5064}
5065
5066static void __init clk_clrbit(u32 reg, u32 bit)
5067{
5068 u32 val = clk_readl(reg);
5069
5070 if ((val & bit) == 0)
5071 return;
5072 val &= ~bit;
5073 clk_writel(val, reg);
5074 udelay(2);
5075}
5076
5077static void __init clk_setbits(u32 reg, u32 bits, u32 mask)
5078{
5079 u32 val = clk_readl(reg);
5080
5081 if ((val & mask) == bits)
5082 return;
5083 val &= ~mask;
5084 val |= bits;
5085 clk_writel(val, reg);
5086 udelay(2);
5087}
5088
5089static int __init tegra_soc_preinit_clocks(void)
5090{
5091 /*
5092 * Make sure host1x clock configuration has:
5093 * HOST1X_CLK_SRC : PLLP_OUT0.
5094 * HOST1X_CLK_DIVISOR: >2 to start from safe enough frequency.
5095 */
5096 clk_setbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_HOST1X_BIT);
5097 clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_DEV_L_0_HOST1X_BIT);
5098 clk_setbits(HOST1X_CLK_REG_OFFSET,
5099 HOST1X_CLK_DIV_DEFAULT, HOST1X_CLK_DIV_MASK);
5100 clk_setbits(HOST1X_CLK_REG_OFFSET,
5101 HOST1X_CLK_IDLE_DIV_DEFAULT, HOST1X_CLK_IDLE_DIV_MASK);
5102 clk_setbits(HOST1X_CLK_REG_OFFSET,
5103 HOST1X_CLK_SRC_DEFAULT, HOST1X_CLK_SRC_MASK);
5104 clk_clrbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_HOST1X_BIT);
5105
5106 /*
5107 * Make sure disp1 clock configuration ha:
5108 * DISP1_CLK_SRC: DISP1_CLK_SRC_PLLP_OUT0
5109 */
5110 clk_setbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_DISP1_BIT);
5111 clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_DEV_L_0_DISP1_BIT);
5112 clk_setbits(DISP1_CLK_REG_OFFSET,
5113 DISP1_CLK_SRC_DEFAULT, DISP1_CLK_SRC_MASK);
5114 clk_clrbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_DISP1_BIT);
5115
5116 /*
5117 * Make sure dam2 clock configuration has:
5118 * DAM2_CLK_SRC: AUDIO_CLK_SRC_CLKM
5119 */
5120 clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM2_BIT);
5121 clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_DAM2_BIT);
5122 clk_setbits(DAM2_CLK_REG_OFFSET,
5123 AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK);
5124 clk_setbits(DAM2_CLK_REG_OFFSET,
5125 AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK);
5126 clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM2_BIT);
5127
5128 /*
5129 * Make sure dam1 clock configuration has:
5130 * DAM1_CLK_SRC: AUDIO_CLK_SRC_CLKM
5131 */
5132 clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM1_BIT);
5133 clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_DAM1_BIT);
5134 clk_setbits(DAM1_CLK_REG_OFFSET,
5135 AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK);
5136 clk_setbits(DAM1_CLK_REG_OFFSET,
5137 AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK);
5138 clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM1_BIT);
5139
5140 /*
5141 * Make sure dam0 clock configuration has:
5142 * DAM0_CLK_SRC: AUDIO_CLK_SRC_CLKM
5143 */
5144 clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM0_BIT);
5145 clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_DAM0_BIT);
5146 clk_setbits(DAM0_CLK_REG_OFFSET,
5147 AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK);
5148 clk_setbits(DAM0_CLK_REG_OFFSET,
5149 AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK);
5150 clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM0_BIT);
5151
5152 /*
5153 * Make sure d_audio clock configuration has:
5154 * AUDIO_CLK_SRC: AUDIO_CLK_SRC_CLKM
5155 */
5156 clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_AUDIO_BIT);
5157 clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_AUDIO_BIT);
5158 clk_setbits(AUDIO_CLK_REG_OFFSET,
5159 AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK);
5160 clk_setbits(AUDIO_CLK_REG_OFFSET,
5161 AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK);
5162 clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_AUDIO_BIT);
5163
5164 return 0;
5165}
5166#endif /* CONFIG_TEGRA_PREINIT_CLOCKS */
5167
5168void __init tegra_soc_init_clocks(void)
5169{
5170 int i;
5171 struct clk *c;
5172
5173#ifdef CONFIG_TEGRA_PREINIT_CLOCKS
5174 tegra_soc_preinit_clocks();
5175#endif /* CONFIG_TEGRA_PREINIT_CLOCKS */
5176
5177 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
5178 tegra3_init_one_clock(tegra_ptr_clks[i]);
5179
5180 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
5181 tegra3_init_one_clock(&tegra_list_clks[i]);
5182
5183 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
5184 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
5185 if (!c) {
5186 pr_err("%s: Unknown duplicate clock %s\n", __func__,
5187 tegra_clk_duplicates[i].name);
5188 continue;
5189 }
5190
5191 tegra_clk_duplicates[i].lookup.clk = c;
5192 clkdev_add(&tegra_clk_duplicates[i].lookup);
5193 }
5194
5195 for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
5196 tegra3_init_one_clock(&tegra_sync_source_list[i]);
5197 for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
5198 tegra3_init_one_clock(&tegra_clk_audio_list[i]);
5199 for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
5200 tegra3_init_one_clock(&tegra_clk_audio_2x_list[i]);
5201
5202 init_clk_out_mux();
5203 for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
5204 tegra3_init_one_clock(&tegra_clk_out_list[i]);
5205
5206 emc_bridge = &tegra_clk_emc_bridge;
5207
5208 /* Initialize to default */
5209 tegra_init_cpu_edp_limits(0);
5210
5211 register_syscore_ops(&tegra_clk_syscore_ops);
5212}
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
new file mode 100644
index 00000000000..48c4384b1aa
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -0,0 +1,968 @@
1/*
2 * arch/arm/mach-tegra/tegra3_dvfs.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/string.h>
20#include <linux/module.h>
21#include <linux/clk.h>
22#include <linux/kobject.h>
23#include <linux/err.h>
24
25#include "clock.h"
26#include "dvfs.h"
27#include "fuse.h"
28#include "board.h"
29#include "tegra3_emc.h"
30
31static bool tegra_dvfs_cpu_disabled;
32static bool tegra_dvfs_core_disabled;
33static struct dvfs *cpu_dvfs;
34
35static const int cpu_millivolts[MAX_DVFS_FREQS] = {
36 800, 825, 850, 875, 900, 912, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237};
37
38static const unsigned int cpu_cold_offs_mhz[MAX_DVFS_FREQS] = {
39 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
40
41static const int core_millivolts[MAX_DVFS_FREQS] = {
42 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350};
43
44#define KHZ 1000
45#define MHZ 1000000
46
47/* VDD_CPU >= (VDD_CORE - cpu_below_core) */
48/* VDD_CORE >= min_level(VDD_CPU), see tegra3_get_core_floor_mv() below */
49#define VDD_CPU_BELOW_VDD_CORE 300
50static int cpu_below_core = VDD_CPU_BELOW_VDD_CORE;
51
52#define VDD_SAFE_STEP 100
53
54static struct dvfs_rail tegra3_dvfs_rail_vdd_cpu = {
55 .reg_id = "vdd_cpu",
56 .max_millivolts = 1250,
57 .min_millivolts = 800,
58 .step = VDD_SAFE_STEP,
59 .jmp_to_zero = true,
60};
61
62static struct dvfs_rail tegra3_dvfs_rail_vdd_core = {
63 .reg_id = "vdd_core",
64 .max_millivolts = 1350,
65 .min_millivolts = 950,
66 .step = VDD_SAFE_STEP,
67};
68
69static struct dvfs_rail *tegra3_dvfs_rails[] = {
70 &tegra3_dvfs_rail_vdd_cpu,
71 &tegra3_dvfs_rail_vdd_core,
72};
73
74static int tegra3_get_core_floor_mv(int cpu_mv)
75{
76 if (cpu_mv < 800)
77 return 950;
78 if (cpu_mv < 900)
79 return 1000;
80 if (cpu_mv < 1000)
81 return 1100;
82 if ((tegra_cpu_speedo_id() < 2) ||
83 (tegra_cpu_speedo_id() == 4) ||
84 (tegra_cpu_speedo_id() == 7) ||
85 (tegra_cpu_speedo_id() == 8))
86 return 1200;
87 if (cpu_mv < 1100)
88 return 1200;
89 if (cpu_mv <= 1250)
90 return 1300;
91 BUG();
92}
93
94/* vdd_core must be >= min_level as a function of vdd_cpu */
95static int tegra3_dvfs_rel_vdd_cpu_vdd_core(struct dvfs_rail *vdd_cpu,
96 struct dvfs_rail *vdd_core)
97{
98 int core_floor = max(vdd_cpu->new_millivolts, vdd_cpu->millivolts);
99 core_floor = tegra3_get_core_floor_mv(core_floor);
100 return max(vdd_core->new_millivolts, core_floor);
101}
102
103/* vdd_cpu must be >= (vdd_core - cpu_below_core) */
104static int tegra3_dvfs_rel_vdd_core_vdd_cpu(struct dvfs_rail *vdd_core,
105 struct dvfs_rail *vdd_cpu)
106{
107 int cpu_floor;
108
109 if (vdd_cpu->new_millivolts == 0)
110 return 0; /* If G CPU is off, core relations can be ignored */
111
112 cpu_floor = max(vdd_core->new_millivolts, vdd_core->millivolts) -
113 cpu_below_core;
114 return max(vdd_cpu->new_millivolts, cpu_floor);
115}
116
117static struct dvfs_relationship tegra3_dvfs_relationships[] = {
118 {
119 .from = &tegra3_dvfs_rail_vdd_cpu,
120 .to = &tegra3_dvfs_rail_vdd_core,
121 .solve = tegra3_dvfs_rel_vdd_cpu_vdd_core,
122 .solved_at_nominal = true,
123 },
124 {
125 .from = &tegra3_dvfs_rail_vdd_core,
126 .to = &tegra3_dvfs_rail_vdd_cpu,
127 .solve = tegra3_dvfs_rel_vdd_core_vdd_cpu,
128 },
129};
130
131#define CPU_DVFS(_clk_name, _speedo_id, _process_id, _mult, _freqs...) \
132 { \
133 .clk_name = _clk_name, \
134 .speedo_id = _speedo_id, \
135 .process_id = _process_id, \
136 .freqs = {_freqs}, \
137 .freqs_mult = _mult, \
138 .millivolts = cpu_millivolts, \
139 .auto_dvfs = true, \
140 .dvfs_rail = &tegra3_dvfs_rail_vdd_cpu, \
141 }
142
143static struct dvfs cpu_dvfs_table[] = {
144 /* Cpu voltages (mV): 800, 825, 850, 875, 900, 912, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237 */
145 CPU_DVFS("cpu_g", 0, 0, MHZ, 1, 1, 684, 684, 817, 817, 1026, 1102, 1149, 1187, 1225, 1282, 1300),
146 CPU_DVFS("cpu_g", 0, 1, MHZ, 1, 1, 807, 807, 948, 948, 1117, 1171, 1206, 1300),
147 CPU_DVFS("cpu_g", 0, 2, MHZ, 1, 1, 883, 883, 1039, 1039, 1178, 1206, 1300),
148 CPU_DVFS("cpu_g", 0, 3, MHZ, 1, 1, 931, 931, 1102, 1102, 1216, 1300),
149
150 CPU_DVFS("cpu_g", 1, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1280, 1300),
151 CPU_DVFS("cpu_g", 1, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1300),
152 CPU_DVFS("cpu_g", 1, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1300),
153 CPU_DVFS("cpu_g", 1, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1300),
154
155 CPU_DVFS("cpu_g", 2, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1250, 1300, 1330, 1400),
156 CPU_DVFS("cpu_g", 2, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1280, 1300, 1350, 1400),
157 CPU_DVFS("cpu_g", 2, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1300, 1350, 1400),
158
159 CPU_DVFS("cpu_g", 3, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1250, 1300, 1330, 1400),
160 CPU_DVFS("cpu_g", 3, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1280, 1300, 1350, 1400),
161 CPU_DVFS("cpu_g", 3, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1300, 1350, 1400),
162
163 CPU_DVFS("cpu_g", 4, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1240, 1280, 1320, 1360, 1360, 1500),
164 CPU_DVFS("cpu_g", 4, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1250, 1300, 1330, 1360, 1400, 1500),
165 CPU_DVFS("cpu_g", 4, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1280, 1300, 1340, 1380, 1500),
166 CPU_DVFS("cpu_g", 4, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1500),
167
168 CPU_DVFS("cpu_g", 5, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
169 CPU_DVFS("cpu_g", 5, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
170
171 CPU_DVFS("cpu_g", 6, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
172 CPU_DVFS("cpu_g", 6, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
173
174 CPU_DVFS("cpu_g", 7, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1280, 1300),
175 CPU_DVFS("cpu_g", 7, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1300),
176 CPU_DVFS("cpu_g", 7, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1300),
177 CPU_DVFS("cpu_g", 7, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1300),
178 CPU_DVFS("cpu_g", 7, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1300),
179
180 CPU_DVFS("cpu_g", 8, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1280, 1300),
181 CPU_DVFS("cpu_g", 8, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1300),
182 CPU_DVFS("cpu_g", 8, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1300),
183 CPU_DVFS("cpu_g", 8, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1300),
184 CPU_DVFS("cpu_g", 8, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1300),
185
186 CPU_DVFS("cpu_g", 9, -1, MHZ, 1, 1, 1, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900),
187 CPU_DVFS("cpu_g", 10, -1, MHZ, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900),
188 CPU_DVFS("cpu_g", 11, -1, MHZ, 1, 1, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600),
189
190 CPU_DVFS("cpu_g", 12, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
191 CPU_DVFS("cpu_g", 12, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
192
193 CPU_DVFS("cpu_g", 13, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
194 CPU_DVFS("cpu_g", 13, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
195
196 /*
197 * "Safe entry" to be used when no match for chip speedo, process
198 * corner is found (just to boot at low rate); must be the last one
199 */
200 CPU_DVFS("cpu_g", -1, -1, MHZ, 1, 1, 216, 216, 300),
201};
202
203#define CORE_DVFS(_clk_name, _speedo_id, _auto, _mult, _freqs...) \
204 { \
205 .clk_name = _clk_name, \
206 .speedo_id = _speedo_id, \
207 .process_id = -1, \
208 .freqs = {_freqs}, \
209 .freqs_mult = _mult, \
210 .millivolts = core_millivolts, \
211 .auto_dvfs = _auto, \
212 .dvfs_rail = &tegra3_dvfs_rail_vdd_core, \
213 }
214
215static struct dvfs core_dvfs_table[] = {
216 /* Core voltages (mV): 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350 */
217 /* Clock limits for internal blocks, PLLs */
218 CORE_DVFS("cpu_lp", 0, 1, KHZ, 1, 294000, 342000, 427000, 475000, 500000, 500000, 500000, 500000),
219 CORE_DVFS("cpu_lp", 1, 1, KHZ, 204000, 294000, 342000, 427000, 475000, 500000, 500000, 500000, 500000),
220 CORE_DVFS("cpu_lp", 2, 1, KHZ, 204000, 295000, 370000, 428000, 475000, 513000, 579000, 620000, 620000),
221 CORE_DVFS("cpu_lp", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 450000, 450000, 450000),
222
223 CORE_DVFS("emc", 0, 1, KHZ, 1, 266500, 266500, 266500, 266500, 533000, 533000, 533000, 533000),
224 CORE_DVFS("emc", 1, 1, KHZ, 102000, 408000, 408000, 408000, 408000, 667000, 667000, 667000, 667000),
225 CORE_DVFS("emc", 2, 1, KHZ, 102000, 408000, 408000, 408000, 408000, 667000, 667000, 800000, 900000),
226 CORE_DVFS("emc", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 625000, 625000, 625000),
227
228 CORE_DVFS("sbus", 0, 1, KHZ, 1, 136000, 164000, 191000, 216000, 216000, 216000, 216000, 216000),
229 CORE_DVFS("sbus", 1, 1, KHZ, 51000, 205000, 205000, 227000, 227000, 267000, 267000, 267000, 267000),
230 CORE_DVFS("sbus", 2, 1, KHZ, 51000, 205000, 205000, 227000, 227000, 267000, 334000, 334000, 334000),
231 CORE_DVFS("sbus", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 378000, 378000, 378000),
232
233 CORE_DVFS("vi", 0, 1, KHZ, 1, 216000, 285000, 300000, 300000, 300000, 300000, 300000, 300000),
234 CORE_DVFS("vi", 1, 1, KHZ, 1, 216000, 267000, 300000, 371000, 409000, 409000, 409000, 409000),
235 CORE_DVFS("vi", 2, 1, KHZ, 1, 219000, 267000, 300000, 371000, 409000, 425000, 425000, 425000),
236 CORE_DVFS("vi", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 470000, 470000, 470000),
237
238 CORE_DVFS("vde", 0, 1, KHZ, 1, 228000, 275000, 332000, 380000, 416000, 416000, 416000, 416000),
239 CORE_DVFS("mpe", 0, 1, KHZ, 1, 234000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
240 CORE_DVFS("2d", 0, 1, KHZ, 1, 267000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
241 CORE_DVFS("epp", 0, 1, KHZ, 1, 267000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
242 CORE_DVFS("3d", 0, 1, KHZ, 1, 234000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
243 CORE_DVFS("3d2", 0, 1, KHZ, 1, 234000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
244 CORE_DVFS("se", 0, 1, KHZ, 1, 267000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
245
246 CORE_DVFS("vde", 1, 1, KHZ, 1, 228000, 275000, 332000, 380000, 416000, 416000, 416000, 416000),
247 CORE_DVFS("mpe", 1, 1, KHZ, 1, 234000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
248 CORE_DVFS("2d", 1, 1, KHZ, 1, 267000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
249 CORE_DVFS("epp", 1, 1, KHZ, 1, 267000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
250 CORE_DVFS("3d", 1, 1, KHZ, 1, 234000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
251 CORE_DVFS("3d2", 1, 1, KHZ, 1, 234000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
252 CORE_DVFS("se", 1, 1, KHZ, 1, 267000, 285000, 332000, 380000, 416000, 416000, 416000, 416000),
253
254 CORE_DVFS("vde", 2, 1, KHZ, 1, 247000, 304000, 352000, 400000, 437000, 484000, 520000, 600000),
255 CORE_DVFS("mpe", 2, 1, KHZ, 1, 247000, 304000, 361000, 408000, 446000, 484000, 520000, 600000),
256 CORE_DVFS("2d", 2, 1, KHZ, 1, 267000, 304000, 361000, 408000, 446000, 484000, 520000, 600000),
257 CORE_DVFS("epp", 2, 1, KHZ, 1, 267000, 304000, 361000, 408000, 446000, 484000, 520000, 600000),
258 CORE_DVFS("3d", 2, 1, KHZ, 1, 247000, 304000, 361000, 408000, 446000, 484000, 520000, 600000),
259 CORE_DVFS("3d2", 2, 1, KHZ, 1, 247000, 304000, 361000, 408000, 446000, 484000, 520000, 600000),
260 CORE_DVFS("se", 2, 1, KHZ, 1, 267000, 304000, 361000, 408000, 446000, 484000, 520000, 600000),
261
262 CORE_DVFS("vde", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
263 CORE_DVFS("mpe", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
264 CORE_DVFS("2d", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
265 CORE_DVFS("epp", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
266 CORE_DVFS("3d", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
267 CORE_DVFS("3d2", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
268 CORE_DVFS("se", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 625000, 625000, 625000),
269
270 CORE_DVFS("host1x", 0, 1, KHZ, 1, 152000, 188000, 222000, 254000, 267000, 267000, 267000, 267000),
271 CORE_DVFS("host1x", 1, 1, KHZ, 1, 152000, 188000, 222000, 254000, 267000, 267000, 267000, 267000),
272 CORE_DVFS("host1x", 2, 1, KHZ, 1, 152000, 188000, 222000, 254000, 267000, 267000, 267000, 300000),
273 CORE_DVFS("host1x", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 242000, 242000, 242000),
274
275 CORE_DVFS("cbus", 0, 1, KHZ, 1, 228000, 275000, 332000, 380000, 416000, 416000, 416000, 416000),
276 CORE_DVFS("cbus", 1, 1, KHZ, 1, 228000, 275000, 332000, 380000, 416000, 416000, 416000, 416000),
277 CORE_DVFS("cbus", 2, 1, KHZ, 1, 247000, 304000, 352000, 400000, 437000, 484000, 520000, 600000),
278 CORE_DVFS("cbus", 3, 1, KHZ, 1, 484000, 484000, 484000, 484000, 484000, 484000, 484000, 484000),
279
280 CORE_DVFS("pll_c", -1, 1, KHZ, 533000, 667000, 667000, 800000, 800000, 1066000, 1066000, 1066000, 1200000),
281
282 /*
283 * PLLM dvfs is common across all speedo IDs with one special exception
284 * for T30 and T33, rev A02+, provided PLLM usage is restricted. Both
285 * common and restricted table are included, and table selection is
286 * handled by is_pllm_dvfs() below.
287 */
288 CORE_DVFS("pll_m", -1, 1, KHZ, 533000, 667000, 667000, 800000, 800000, 1066000, 1066000, 1066000, 1066000),
289#ifdef CONFIG_TEGRA_PLLM_RESTRICTED
290 CORE_DVFS("pll_m", 2, 1, KHZ, 533000, 800000, 800000, 800000, 800000, 1066000, 1066000, 1066000, 1066000),
291#endif
292 /* Core voltages (mV): 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350 */
293 /* Clock limits for I/O peripherals */
294 CORE_DVFS("mipi", 0, 1, KHZ, 1, 1, 1, 1, 1, 1, 1, 1, 1),
295 CORE_DVFS("mipi", 1, 1, KHZ, 1, 1, 1, 1, 1, 60000, 60000, 60000, 60000),
296 CORE_DVFS("mipi", 2, 1, KHZ, 1, 1, 1, 1, 1, 60000, 60000, 60000, 60000),
297 CORE_DVFS("mipi", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 1, 1, 1),
298
299 CORE_DVFS("fuse_burn", -1, 1, KHZ, 1, 1, 1, 1, 26000, 26000, 26000, 26000, 26000),
300 CORE_DVFS("sdmmc1", -1, 1, KHZ, 104000, 104000, 104000, 104000, 104000, 208000, 208000, 208000, 208000),
301 CORE_DVFS("sdmmc3", -1, 1, KHZ, 104000, 104000, 104000, 104000, 104000, 208000, 208000, 208000, 208000),
302 CORE_DVFS("ndflash", -1, 1, KHZ, 1, 120000, 120000, 120000, 200000, 200000, 200000, 200000, 200000),
303
304 CORE_DVFS("nor", 0, 1, KHZ, 1, 115000, 130000, 130000, 133000, 133000, 133000, 133000, 133000),
305 CORE_DVFS("nor", 1, 1, KHZ, 1, 115000, 130000, 130000, 133000, 133000, 133000, 133000, 133000),
306 CORE_DVFS("nor", 2, 1, KHZ, 1, 115000, 130000, 130000, 133000, 133000, 133000, 133000, 133000),
307 CORE_DVFS("nor", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 108000, 108000, 108000),
308
309 CORE_DVFS("sbc1", -1, 1, KHZ, 1, 52000, 60000, 60000, 60000, 100000, 100000, 100000, 100000),
310 CORE_DVFS("sbc2", -1, 1, KHZ, 1, 52000, 60000, 60000, 60000, 100000, 100000, 100000, 100000),
311 CORE_DVFS("sbc3", -1, 1, KHZ, 1, 52000, 60000, 60000, 60000, 100000, 100000, 100000, 100000),
312 CORE_DVFS("sbc4", -1, 1, KHZ, 1, 52000, 60000, 60000, 60000, 100000, 100000, 100000, 100000),
313 CORE_DVFS("sbc5", -1, 1, KHZ, 1, 52000, 60000, 60000, 60000, 100000, 100000, 100000, 100000),
314 CORE_DVFS("sbc6", -1, 1, KHZ, 1, 52000, 60000, 60000, 60000, 100000, 100000, 100000, 100000),
315
316 CORE_DVFS("usbd", -1, 1, KHZ, 1, 480000, 480000, 480000, 480000, 480000, 480000, 480000, 480000),
317 CORE_DVFS("usb2", -1, 1, KHZ, 1, 480000, 480000, 480000, 480000, 480000, 480000, 480000, 480000),
318 CORE_DVFS("usb3", -1, 1, KHZ, 1, 480000, 480000, 480000, 480000, 480000, 480000, 480000, 480000),
319
320 CORE_DVFS("sata", -1, 1, KHZ, 1, 216000, 216000, 216000, 216000, 216000, 216000, 216000, 216000),
321 CORE_DVFS("sata_oob", -1, 1, KHZ, 1, 216000, 216000, 216000, 216000, 216000, 216000, 216000, 216000),
322 CORE_DVFS("pcie", -1, 1, KHZ, 1, 250000, 250000, 250000, 250000, 250000, 250000, 250000, 250000),
323 CORE_DVFS("afi", -1, 1, KHZ, 1, 250000, 250000, 250000, 250000, 250000, 250000, 250000, 250000),
324 CORE_DVFS("pll_e", -1, 1, KHZ, 1, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000),
325
326 CORE_DVFS("tvdac", -1, 1, KHZ, 1, 220000, 220000, 220000, 220000, 220000, 220000, 220000, 220000),
327 CORE_DVFS("tvo", -1, 1, KHZ, 1, 1, 297000, 297000, 297000, 297000, 297000, 297000, 297000),
328 CORE_DVFS("cve", -1, 1, KHZ, 1, 1, 297000, 297000, 297000, 297000, 297000, 297000, 297000),
329 CORE_DVFS("dsia", -1, 1, KHZ, 1, 275000, 275000, 275000, 275000, 275000, 275000, 275000, 275000),
330 CORE_DVFS("dsib", -1, 1, KHZ, 1, 275000, 275000, 275000, 275000, 275000, 275000, 275000, 275000),
331 CORE_DVFS("hdmi", -1, 1, KHZ, 1, 148500, 148500, 148500, 148500, 148500, 148500, 148500, 148500),
332
333 /*
334 * The clock rate for the display controllers that determines the
335 * necessary core voltage depends on a divider that is internal
336 * to the display block. Disable auto-dvfs on the display clocks,
337 * and let the display driver call tegra_dvfs_set_rate manually
338 */
339 CORE_DVFS("disp1", 0, 0, KHZ, 1, 120000, 120000, 120000, 120000, 190000, 190000, 190000, 190000),
340 CORE_DVFS("disp1", 1, 0, KHZ, 1, 155000, 268000, 268000, 268000, 268000, 268000, 268000, 268000),
341 CORE_DVFS("disp1", 2, 0, KHZ, 1, 155000, 268000, 268000, 268000, 268000, 268000, 268000, 268000),
342 CORE_DVFS("disp1", 3, 0, KHZ, 1, 120000, 120000, 120000, 120000, 190000, 190000, 190000, 190000),
343
344 CORE_DVFS("disp2", 0, 0, KHZ, 1, 120000, 120000, 120000, 120000, 190000, 190000, 190000, 190000),
345 CORE_DVFS("disp2", 1, 0, KHZ, 1, 155000, 268000, 268000, 268000, 268000, 268000, 268000, 268000),
346 CORE_DVFS("disp2", 2, 0, KHZ, 1, 155000, 268000, 268000, 268000, 268000, 268000, 268000, 268000),
347 CORE_DVFS("disp2", 3, 0, KHZ, 1, 120000, 120000, 120000, 120000, 190000, 190000, 190000, 190000),
348
349 CORE_DVFS("pwm", -1, 1, KHZ, 1, 408000, 408000, 408000, 408000, 408000, 408000, 408000, 408000),
350 CORE_DVFS("spdif_out", -1, 1, KHZ, 1, 26000, 26000, 26000, 26000, 26000, 26000, 26000, 26000),
351};
352
353
354int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
355{
356 int ret;
357
358 ret = param_set_bool(arg, kp);
359 if (ret)
360 return ret;
361
362 if (tegra_dvfs_core_disabled)
363 tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_core);
364 else
365 tegra_dvfs_rail_enable(&tegra3_dvfs_rail_vdd_core);
366
367 return 0;
368}
369
370int tegra_dvfs_disable_cpu_set(const char *arg, const struct kernel_param *kp)
371{
372 int ret;
373
374 ret = param_set_bool(arg, kp);
375 if (ret)
376 return ret;
377
378 if (tegra_dvfs_cpu_disabled)
379 tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_cpu);
380 else
381 tegra_dvfs_rail_enable(&tegra3_dvfs_rail_vdd_cpu);
382
383 return 0;
384}
385
386int tegra_dvfs_disable_get(char *buffer, const struct kernel_param *kp)
387{
388 return param_get_bool(buffer, kp);
389}
390
391static struct kernel_param_ops tegra_dvfs_disable_core_ops = {
392 .set = tegra_dvfs_disable_core_set,
393 .get = tegra_dvfs_disable_get,
394};
395
396static struct kernel_param_ops tegra_dvfs_disable_cpu_ops = {
397 .set = tegra_dvfs_disable_cpu_set,
398 .get = tegra_dvfs_disable_get,
399};
400
401module_param_cb(disable_core, &tegra_dvfs_disable_core_ops,
402 &tegra_dvfs_core_disabled, 0644);
403module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops,
404 &tegra_dvfs_cpu_disabled, 0644);
405
406static bool __init is_pllm_dvfs(struct clk *c, struct dvfs *d)
407{
408#ifdef CONFIG_TEGRA_PLLM_RESTRICTED
409 /* Do not apply common PLLM dvfs table on T30, T33, T37 rev A02+ and
410 do not apply restricted PLLM dvfs table for other SKUs/revs */
411 int cpu = tegra_cpu_speedo_id();
412 if (((cpu == 2) || (cpu == 5) || (cpu == 13)) ==
413 (d->speedo_id == -1))
414 return false;
415#endif
416 /* Check if PLLM boot frequency can be applied to clock tree at
417 minimum voltage. If yes, no need to enable dvfs on PLLM */
418 if (clk_get_rate_all_locked(c) <= d->freqs[0] * d->freqs_mult)
419 return false;
420
421 return true;
422}
423
424static void __init init_dvfs_one(struct dvfs *d, int nominal_mv_index)
425{
426 int ret;
427 struct clk *c = tegra_get_clock_by_name(d->clk_name);
428
429 if (!c) {
430 pr_debug("tegra3_dvfs: no clock found for %s\n",
431 d->clk_name);
432 return;
433 }
434
435 /*
436 * Update max rate for auto-dvfs clocks, except EMC.
437 * EMC is a special case, since EMC dvfs is board dependent: max rate
438 * and EMC scaling frequencies are determined by tegra BCT (flashed
439 * together with the image) and board specific EMC DFS table; we will
440 * check the scaling ladder against nominal core voltage when the table
441 * is loaded (and if on particular board the table is not loaded, EMC
442 * scaling is disabled).
443 */
444 if (!(c->flags & PERIPH_EMC_ENB) && d->auto_dvfs) {
445 BUG_ON(!d->freqs[nominal_mv_index]);
446 tegra_init_max_rate(
447 c, d->freqs[nominal_mv_index] * d->freqs_mult);
448 }
449 d->max_millivolts = d->dvfs_rail->nominal_millivolts;
450
451 /*
452 * Check if we may skip enabling dvfs on PLLM. PLLM is a special case,
453 * since its frequency never exceeds boot rate, and configuration with
454 * restricted PLLM usage is possible.
455 */
456 if (!(c->flags & PLLM) || is_pllm_dvfs(c, d)) {
457 ret = tegra_enable_dvfs_on_clk(c, d);
458 if (ret)
459 pr_err("tegra3_dvfs: failed to enable dvfs on %s\n",
460 c->name);
461 }
462}
463
464static void __init init_dvfs_cold(struct dvfs *d, int nominal_mv_index)
465{
466 int i;
467 unsigned long offs;
468
469 BUG_ON((nominal_mv_index == 0) || (nominal_mv_index > d->num_freqs));
470
471 for (i = 0; i < d->num_freqs; i++) {
472 offs = cpu_cold_offs_mhz[i] * MHZ;
473 if (i > nominal_mv_index)
474 d->alt_freqs[i] = d->alt_freqs[i - 1];
475 else if (d->freqs[i] > offs)
476 d->alt_freqs[i] = d->freqs[i] - offs;
477 else {
478 d->alt_freqs[i] = d->freqs[i];
479 pr_warn("tegra3_dvfs: cold offset %lu is too high for"
480 " regular dvfs limit %lu\n", offs, d->freqs[i]);
481 }
482
483 if (i)
484 BUG_ON(d->alt_freqs[i] < d->alt_freqs[i - 1]);
485 }
486 d->alt_freqs_state = ALT_FREQS_DISABLED;
487}
488
489static bool __init match_dvfs_one(struct dvfs *d, int speedo_id, int process_id)
490{
491 if ((d->process_id != -1 && d->process_id != process_id) ||
492 (d->speedo_id != -1 && d->speedo_id != speedo_id)) {
493 pr_debug("tegra3_dvfs: rejected %s speedo %d,"
494 " process %d\n", d->clk_name, d->speedo_id,
495 d->process_id);
496 return false;
497 }
498 return true;
499}
500
501static int __init get_cpu_nominal_mv_index(
502 int speedo_id, int process_id, struct dvfs **cpu_dvfs)
503{
504 int i, j, mv;
505 struct dvfs *d;
506 struct clk *c;
507
508 /*
509 * Find maximum cpu voltage that satisfies cpu_to_core dependency for
510 * nominal core voltage ("solve from cpu to core at nominal"). Clip
511 * result to the nominal cpu level for the chips with this speedo_id.
512 */
513 mv = tegra3_dvfs_rail_vdd_core.nominal_millivolts;
514 for (i = 0; i < MAX_DVFS_FREQS; i++) {
515 if ((cpu_millivolts[i] == 0) ||
516 tegra3_get_core_floor_mv(cpu_millivolts[i]) > mv)
517 break;
518 }
519 BUG_ON(i == 0);
520 mv = cpu_millivolts[i - 1];
521 BUG_ON(mv < tegra3_dvfs_rail_vdd_cpu.min_millivolts);
522 mv = min(mv, tegra_cpu_speedo_mv());
523
524 /*
525 * Find matching cpu dvfs entry, and use it to determine index to the
526 * final nominal voltage, that satisfies the following requirements:
527 * - allows CPU to run at minimum of the maximum rates specified in
528 * the dvfs entry and clock tree
529 * - does not violate cpu_to_core dependency as determined above
530 */
531 for (i = 0, j = 0; j < ARRAY_SIZE(cpu_dvfs_table); j++) {
532 d = &cpu_dvfs_table[j];
533 if (match_dvfs_one(d, speedo_id, process_id)) {
534 c = tegra_get_clock_by_name(d->clk_name);
535 BUG_ON(!c);
536
537 for (; i < MAX_DVFS_FREQS; i++) {
538 if ((d->freqs[i] == 0) ||
539 (cpu_millivolts[i] == 0) ||
540 (mv < cpu_millivolts[i]))
541 break;
542
543 if (c->max_rate <= d->freqs[i]*d->freqs_mult) {
544 i++;
545 break;
546 }
547 }
548 break;
549 }
550 }
551
552 BUG_ON(i == 0);
553 if (j == (ARRAY_SIZE(cpu_dvfs_table) - 1))
554 pr_err("tegra3_dvfs: WARNING!!!\n"
555 "tegra3_dvfs: no cpu dvfs table found for chip speedo_id"
556 " %d and process_id %d: set CPU rate limit at %lu\n"
557 "tegra3_dvfs: WARNING!!!\n",
558 speedo_id, process_id, d->freqs[i-1] * d->freqs_mult);
559
560 *cpu_dvfs = d;
561 return (i - 1);
562}
563
564static int __init get_core_nominal_mv_index(int speedo_id)
565{
566 int i;
567 int mv = tegra_core_speedo_mv();
568 int core_edp_limit = get_core_edp();
569
570 /*
571 * Start with nominal level for the chips with this speedo_id. Then,
572 * make sure core nominal voltage is below edp limit for the board
573 * (if edp limit is set).
574 */
575 if (core_edp_limit)
576 mv = min(mv, core_edp_limit);
577
578 /* Round nominal level down to the nearest core scaling step */
579 for (i = 0; i < MAX_DVFS_FREQS; i++) {
580 if ((core_millivolts[i] == 0) || (mv < core_millivolts[i]))
581 break;
582 }
583
584 if (i == 0) {
585 pr_err("tegra3_dvfs: unable to adjust core dvfs table to"
586 " nominal voltage %d\n", mv);
587 return -ENOSYS;
588 }
589 return (i - 1);
590}
591
592void __init tegra_soc_init_dvfs(void)
593{
594 int cpu_speedo_id = tegra_cpu_speedo_id();
595 int soc_speedo_id = tegra_soc_speedo_id();
596 int cpu_process_id = tegra_cpu_process_id();
597 int core_process_id = tegra_core_process_id();
598
599 int i;
600 int core_nominal_mv_index;
601 int cpu_nominal_mv_index;
602
603#ifndef CONFIG_TEGRA_CORE_DVFS
604 tegra_dvfs_core_disabled = true;
605#endif
606#ifndef CONFIG_TEGRA_CPU_DVFS
607 tegra_dvfs_cpu_disabled = true;
608#endif
609
610 /*
611 * Find nominal voltages for core (1st) and cpu rails before rail
612 * init. Nominal voltage index in the scaling ladder will also be
613 * used to determine max dvfs frequency for the respective domains.
614 */
615 core_nominal_mv_index = get_core_nominal_mv_index(soc_speedo_id);
616 if (core_nominal_mv_index < 0) {
617 tegra3_dvfs_rail_vdd_core.disabled = true;
618 tegra_dvfs_core_disabled = true;
619 core_nominal_mv_index = 0;
620 }
621 tegra3_dvfs_rail_vdd_core.nominal_millivolts =
622 core_millivolts[core_nominal_mv_index];
623
624 cpu_nominal_mv_index = get_cpu_nominal_mv_index(
625 cpu_speedo_id, cpu_process_id, &cpu_dvfs);
626 BUG_ON((cpu_nominal_mv_index < 0) || (!cpu_dvfs));
627 tegra3_dvfs_rail_vdd_cpu.nominal_millivolts =
628 cpu_millivolts[cpu_nominal_mv_index];
629
630 /* Init rail structures and dependencies */
631 tegra_dvfs_init_rails(tegra3_dvfs_rails, ARRAY_SIZE(tegra3_dvfs_rails));
632 tegra_dvfs_add_relationships(tegra3_dvfs_relationships,
633 ARRAY_SIZE(tegra3_dvfs_relationships));
634
635 /* Search core dvfs table for speedo/process matching entries and
636 initialize dvfs-ed clocks */
637 for (i = 0; i < ARRAY_SIZE(core_dvfs_table); i++) {
638 struct dvfs *d = &core_dvfs_table[i];
639 if (!match_dvfs_one(d, soc_speedo_id, core_process_id))
640 continue;
641 init_dvfs_one(d, core_nominal_mv_index);
642 }
643
644 /* Initialize matching cpu dvfs entry already found when nominal
645 voltage was determined */
646 init_dvfs_one(cpu_dvfs, cpu_nominal_mv_index);
647 init_dvfs_cold(cpu_dvfs, cpu_nominal_mv_index);
648
649 /* Finally disable dvfs on rails if necessary */
650 if (tegra_dvfs_core_disabled)
651 tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_core);
652 if (tegra_dvfs_cpu_disabled)
653 tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_cpu);
654
655 pr_info("tegra dvfs: VDD_CPU nominal %dmV, scaling %s\n",
656 tegra3_dvfs_rail_vdd_cpu.nominal_millivolts,
657 tegra_dvfs_cpu_disabled ? "disabled" : "enabled");
658 pr_info("tegra dvfs: VDD_CORE nominal %dmV, scaling %s\n",
659 tegra3_dvfs_rail_vdd_core.nominal_millivolts,
660 tegra_dvfs_core_disabled ? "disabled" : "enabled");
661}
662
663void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update)
664{
665 bool enable = !edp_thermal_index;
666
667 if (enable != before_clk_update) {
668 int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, enable);
669 WARN_ONCE(ret, "tegra dvfs: failed to set CPU alternative"
670 " frequency limits for cold temeperature\n");
671 }
672}
673
674int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
675{
676 int ret = 0;
677
678 if (tegra_emc_get_dram_type() != DRAM_TYPE_DDR3)
679 return ret;
680
681 if (((&tegra3_dvfs_rail_vdd_core == rail) &&
682 (rail->nominal_millivolts > TEGRA_EMC_BRIDGE_MVOLTS_MIN)) ||
683 ((&tegra3_dvfs_rail_vdd_cpu == rail) &&
684 (tegra3_get_core_floor_mv(rail->nominal_millivolts) >
685 TEGRA_EMC_BRIDGE_MVOLTS_MIN))) {
686 struct clk *bridge = tegra_get_clock_by_name("bridge.emc");
687 BUG_ON(!bridge);
688
689 ret = clk_enable(bridge);
690 pr_info("%s: %s: %s bridge.emc\n", __func__,
691 rail->reg_id, ret ? "failed to enable" : "enabled");
692 }
693 return ret;
694}
695
696int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail)
697{
698 if (tegra_emc_get_dram_type() != DRAM_TYPE_DDR3)
699 return 0;
700
701 if (((&tegra3_dvfs_rail_vdd_core == rail) &&
702 (rail->nominal_millivolts > TEGRA_EMC_BRIDGE_MVOLTS_MIN)) ||
703 ((&tegra3_dvfs_rail_vdd_cpu == rail) &&
704 (tegra3_get_core_floor_mv(rail->nominal_millivolts) >
705 TEGRA_EMC_BRIDGE_MVOLTS_MIN))) {
706 struct clk *bridge = tegra_get_clock_by_name("bridge.emc");
707 BUG_ON(!bridge);
708
709 clk_disable(bridge);
710 pr_info("%s: %s: disabled bridge.emc\n",
711 __func__, rail->reg_id);
712 }
713 return 0;
714}
715
716/*
717 * sysfs and dvfs interfaces to cap tegra core domains frequencies
718 */
719static DEFINE_MUTEX(core_cap_lock);
720
721struct core_cap {
722 int refcnt;
723 int level;
724};
725static struct core_cap tegra3_core_cap;
726static struct core_cap kdvfs_core_cap;
727static struct core_cap user_core_cap;
728
729static struct kobject *cap_kobj;
730
731/* Arranged in order required for enabling/lowering the cap */
732static struct {
733 const char *cap_name;
734 struct clk *cap_clk;
735 unsigned long freqs[MAX_DVFS_FREQS];
736} core_cap_table[] = {
737 { .cap_name = "cap.cbus" },
738 { .cap_name = "cap.sclk" },
739 { .cap_name = "cap.emc" },
740};
741
742
743static void core_cap_level_set(int level)
744{
745 int i, j;
746
747 for (j = 0; j < ARRAY_SIZE(core_millivolts); j++) {
748 int v = core_millivolts[j];
749 if ((v == 0) || (level < v))
750 break;
751 }
752 j = (j == 0) ? 0 : j - 1;
753 level = core_millivolts[j];
754
755 if (level < tegra3_core_cap.level) {
756 for (i = 0; i < ARRAY_SIZE(core_cap_table); i++)
757 if (core_cap_table[i].cap_clk)
758 clk_set_rate(core_cap_table[i].cap_clk,
759 core_cap_table[i].freqs[j]);
760 } else if (level > tegra3_core_cap.level) {
761 for (i = ARRAY_SIZE(core_cap_table) - 1; i >= 0; i--)
762 if (core_cap_table[i].cap_clk)
763 clk_set_rate(core_cap_table[i].cap_clk,
764 core_cap_table[i].freqs[j]);
765 }
766 tegra3_core_cap.level = level;
767}
768
769static void core_cap_update(void)
770{
771 int new_level = tegra3_dvfs_rail_vdd_core.max_millivolts;
772
773 if (kdvfs_core_cap.refcnt)
774 new_level = min(new_level, kdvfs_core_cap.level);
775 if (user_core_cap.refcnt)
776 new_level = min(new_level, user_core_cap.level);
777
778 if (tegra3_core_cap.level != new_level)
779 core_cap_level_set(new_level);
780}
781
782static void core_cap_enable(bool enable)
783{
784 int i;
785
786 if (enable) {
787 tegra3_core_cap.refcnt++;
788 if (tegra3_core_cap.refcnt == 1)
789 for (i = 0; i < ARRAY_SIZE(core_cap_table); i++)
790 if (core_cap_table[i].cap_clk)
791 clk_enable(core_cap_table[i].cap_clk);
792 } else if (tegra3_core_cap.refcnt) {
793 tegra3_core_cap.refcnt--;
794 if (tegra3_core_cap.refcnt == 0)
795 for (i = ARRAY_SIZE(core_cap_table) - 1; i >= 0; i--)
796 if (core_cap_table[i].cap_clk)
797 clk_disable(core_cap_table[i].cap_clk);
798 }
799 core_cap_update();
800}
801
802static ssize_t
803core_cap_state_show(struct kobject *kobj, struct kobj_attribute *attr,
804 char *buf)
805{
806 return sprintf(buf, "%d (%d)\n", tegra3_core_cap.refcnt ? 1 : 0,
807 user_core_cap.refcnt ? 1 : 0);
808}
809static ssize_t
810core_cap_state_store(struct kobject *kobj, struct kobj_attribute *attr,
811 const char *buf, size_t count)
812{
813 int state;
814
815 if (sscanf(buf, "%d", &state) != 1)
816 return -1;
817
818 mutex_lock(&core_cap_lock);
819
820 if (state) {
821 user_core_cap.refcnt++;
822 if (user_core_cap.refcnt == 1)
823 core_cap_enable(true);
824 } else if (user_core_cap.refcnt) {
825 user_core_cap.refcnt--;
826 if (user_core_cap.refcnt == 0)
827 core_cap_enable(false);
828 }
829
830 mutex_unlock(&core_cap_lock);
831 return count;
832}
833
834static ssize_t
835core_cap_level_show(struct kobject *kobj, struct kobj_attribute *attr,
836 char *buf)
837{
838 return sprintf(buf, "%d (%d)\n", tegra3_core_cap.level,
839 user_core_cap.level);
840}
841static ssize_t
842core_cap_level_store(struct kobject *kobj, struct kobj_attribute *attr,
843 const char *buf, size_t count)
844{
845 int level;
846
847 if (sscanf(buf, "%d", &level) != 1)
848 return -1;
849
850 mutex_lock(&core_cap_lock);
851 user_core_cap.level = level;
852 core_cap_update();
853 mutex_unlock(&core_cap_lock);
854 return count;
855}
856
857static struct kobj_attribute cap_state_attribute =
858 __ATTR(core_cap_state, 0644, core_cap_state_show, core_cap_state_store);
859static struct kobj_attribute cap_level_attribute =
860 __ATTR(core_cap_level, 0644, core_cap_level_show, core_cap_level_store);
861
862const struct attribute *cap_attributes[] = {
863 &cap_state_attribute.attr,
864 &cap_level_attribute.attr,
865 NULL,
866};
867
868void tegra_dvfs_core_cap_enable(bool enable)
869{
870 mutex_lock(&core_cap_lock);
871
872 if (enable) {
873 kdvfs_core_cap.refcnt++;
874 if (kdvfs_core_cap.refcnt == 1)
875 core_cap_enable(true);
876 } else if (kdvfs_core_cap.refcnt) {
877 kdvfs_core_cap.refcnt--;
878 if (kdvfs_core_cap.refcnt == 0)
879 core_cap_enable(false);
880 }
881 mutex_unlock(&core_cap_lock);
882}
883
884void tegra_dvfs_core_cap_level_set(int level)
885{
886 mutex_lock(&core_cap_lock);
887 kdvfs_core_cap.level = level;
888 core_cap_update();
889 mutex_unlock(&core_cap_lock);
890}
891
892static int __init init_core_cap_one(struct clk *c, unsigned long *freqs)
893{
894 int i, v, next_v;
895 unsigned long rate, next_rate = 0;
896
897 for (i = 0; i < ARRAY_SIZE(core_millivolts); i++) {
898 v = core_millivolts[i];
899 if (v == 0)
900 break;
901
902 for (;;) {
903 rate = next_rate;
904 next_rate = clk_round_rate(c, rate + 1000);
905 if (IS_ERR_VALUE(next_rate)) {
906 pr_debug("tegra3_dvfs: failed to round %s"
907 " rate %lu", c->name, rate);
908 return -EINVAL;
909 }
910 if (rate == next_rate)
911 break;
912
913 next_v = tegra_dvfs_predict_millivolts(
914 c->parent, next_rate);
915 if (IS_ERR_VALUE(next_rate)) {
916 pr_debug("tegra3_dvfs: failed to predict %s mV"
917 " for rate %lu", c->name, next_rate);
918 return -EINVAL;
919 }
920 if (next_v > v)
921 break;
922 }
923
924 if (rate == 0) {
925 rate = next_rate;
926 pr_warn("tegra3_dvfs: minimum %s rate %lu requires"
927 " %d mV", c->name, rate, next_v);
928 }
929 freqs[i] = rate;
930 next_rate = rate;
931 }
932 return 0;
933}
934
935static int __init tegra_dvfs_init_core_cap(void)
936{
937 int i;
938 struct clk *c = NULL;
939
940 tegra3_core_cap.level = kdvfs_core_cap.level = user_core_cap.level =
941 tegra3_dvfs_rail_vdd_core.max_millivolts;
942
943 for (i = 0; i < ARRAY_SIZE(core_cap_table); i++) {
944 c = tegra_get_clock_by_name(core_cap_table[i].cap_name);
945 if (!c || !c->parent ||
946 init_core_cap_one(c, core_cap_table[i].freqs)) {
947 pr_err("tegra3_dvfs: failed to initialize %s frequency"
948 " table", core_cap_table[i].cap_name);
949 continue;
950 }
951 core_cap_table[i].cap_clk = c;
952 }
953
954 cap_kobj = kobject_create_and_add("tegra_cap", kernel_kobj);
955 if (!cap_kobj) {
956 pr_err("tegra3_dvfs: failed to create sysfs cap object");
957 return 0;
958 }
959
960 if (sysfs_create_files(cap_kobj, cap_attributes)) {
961 pr_err("tegra3_dvfs: failed to create sysfs cap interface");
962 return 0;
963 }
964 pr_info("tegra dvfs: tegra sysfs cap interface is initialized\n");
965
966 return 0;
967}
968late_initcall(tegra_dvfs_init_core_cap);
diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c
new file mode 100644
index 00000000000..0ceed669fa5
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_emc.c
@@ -0,0 +1,1254 @@
1/*
2 * arch/arm/mach-tegra/tegra3_emc.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include <linux/kernel.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/io.h>
26#include <linux/module.h>
27#include <linux/delay.h>
28#include <linux/suspend.h>
29#include <linux/debugfs.h>
30#include <linux/seq_file.h>
31
32#include <asm/cputime.h>
33#include <asm/cacheflush.h>
34
35#include <mach/iomap.h>
36
37#include "clock.h"
38#include "dvfs.h"
39#include "tegra3_emc.h"
40
41#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
42static bool emc_enable = true;
43#else
44static bool emc_enable;
45#endif
46module_param(emc_enable, bool, 0644);
47
48#define EMC_MIN_RATE_DDR3 50000000
49#define EMC_STATUS_UPDATE_TIMEOUT 100
50#define TEGRA_EMC_TABLE_MAX_SIZE 16
51
52enum {
53 DLL_CHANGE_NONE = 0,
54 DLL_CHANGE_ON,
55 DLL_CHANGE_OFF,
56};
57
58#define EMC_CLK_DIV_SHIFT 0
59#define EMC_CLK_DIV_MASK (0xFF << EMC_CLK_DIV_SHIFT)
60#define EMC_CLK_SOURCE_SHIFT 30
61#define EMC_CLK_SOURCE_MASK (0x3 << EMC_CLK_SOURCE_SHIFT)
62#define EMC_CLK_LOW_JITTER_ENABLE (0x1 << 29)
63#define EMC_CLK_MC_SAME_FREQ (0x1 << 16)
64
65#define BURST_REG_LIST \
66 DEFINE_REG(TEGRA_EMC_BASE, EMC_RC), \
67 DEFINE_REG(TEGRA_EMC_BASE, EMC_RFC), \
68 DEFINE_REG(TEGRA_EMC_BASE, EMC_RAS), \
69 DEFINE_REG(TEGRA_EMC_BASE, EMC_RP), \
70 DEFINE_REG(TEGRA_EMC_BASE, EMC_R2W), \
71 DEFINE_REG(TEGRA_EMC_BASE, EMC_W2R), \
72 DEFINE_REG(TEGRA_EMC_BASE, EMC_R2P), \
73 DEFINE_REG(TEGRA_EMC_BASE, EMC_W2P), \
74 DEFINE_REG(TEGRA_EMC_BASE, EMC_RD_RCD), \
75 DEFINE_REG(TEGRA_EMC_BASE, EMC_WR_RCD), \
76 DEFINE_REG(TEGRA_EMC_BASE, EMC_RRD), \
77 DEFINE_REG(TEGRA_EMC_BASE, EMC_REXT), \
78 DEFINE_REG(TEGRA_EMC_BASE, EMC_WEXT), \
79 DEFINE_REG(TEGRA_EMC_BASE, EMC_WDV), \
80 DEFINE_REG(TEGRA_EMC_BASE, EMC_QUSE), \
81 DEFINE_REG(TEGRA_EMC_BASE, EMC_QRST), \
82 DEFINE_REG(TEGRA_EMC_BASE, EMC_QSAFE), \
83 DEFINE_REG(TEGRA_EMC_BASE, EMC_RDV), \
84 DEFINE_REG(TEGRA_EMC_BASE, EMC_REFRESH), \
85 DEFINE_REG(TEGRA_EMC_BASE, EMC_BURST_REFRESH_NUM), \
86 DEFINE_REG(TEGRA_EMC_BASE, EMC_PRE_REFRESH_REQ_CNT), \
87 DEFINE_REG(TEGRA_EMC_BASE, EMC_PDEX2WR), \
88 DEFINE_REG(TEGRA_EMC_BASE, EMC_PDEX2RD), \
89 DEFINE_REG(TEGRA_EMC_BASE, EMC_PCHG2PDEN), \
90 DEFINE_REG(TEGRA_EMC_BASE, EMC_ACT2PDEN), \
91 DEFINE_REG(TEGRA_EMC_BASE, EMC_AR2PDEN), \
92 DEFINE_REG(TEGRA_EMC_BASE, EMC_RW2PDEN), \
93 DEFINE_REG(TEGRA_EMC_BASE, EMC_TXSR), \
94 DEFINE_REG(TEGRA_EMC_BASE, EMC_TXSRDLL), \
95 DEFINE_REG(TEGRA_EMC_BASE, EMC_TCKE), \
96 DEFINE_REG(TEGRA_EMC_BASE, EMC_TFAW), \
97 DEFINE_REG(TEGRA_EMC_BASE, EMC_TRPAB), \
98 DEFINE_REG(TEGRA_EMC_BASE, EMC_TCLKSTABLE), \
99 DEFINE_REG(TEGRA_EMC_BASE, EMC_TCLKSTOP), \
100 DEFINE_REG(TEGRA_EMC_BASE, EMC_TREFBW), \
101 DEFINE_REG(TEGRA_EMC_BASE, EMC_QUSE_EXTRA), \
102 DEFINE_REG(TEGRA_EMC_BASE, EMC_FBIO_CFG6), \
103 DEFINE_REG(TEGRA_EMC_BASE, EMC_ODT_WRITE), \
104 DEFINE_REG(TEGRA_EMC_BASE, EMC_ODT_READ), \
105 DEFINE_REG(TEGRA_EMC_BASE, EMC_FBIO_CFG5), \
106 DEFINE_REG(TEGRA_EMC_BASE, EMC_CFG_DIG_DLL), \
107 DEFINE_REG(TEGRA_EMC_BASE, EMC_CFG_DIG_DLL_PERIOD), \
108 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS0), \
109 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS1), \
110 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS2), \
111 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS3), \
112 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS4), \
113 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS5), \
114 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS6), \
115 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQS7), \
116 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE0), \
117 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE1), \
118 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE2), \
119 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE3), \
120 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE4), \
121 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE5), \
122 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE6), \
123 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_QUSE7), \
124 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS0), \
125 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS1), \
126 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS2), \
127 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS3), \
128 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS4), \
129 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS5), \
130 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS6), \
131 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLI_TRIM_TXDQS7), \
132 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQ0), \
133 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQ1), \
134 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQ2), \
135 DEFINE_REG(TEGRA_EMC_BASE, EMC_DLL_XFORM_DQ3), \
136 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2CMDPADCTRL), \
137 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2DQSPADCTRL2), \
138 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2DQPADCTRL2), \
139 DEFINE_REG(0 , EMC_XM2CLKPADCTRL), \
140 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2COMPPADCTRL), \
141 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2VTTGENPADCTRL), \
142 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2VTTGENPADCTRL2), \
143 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2QUSEPADCTRL), \
144 DEFINE_REG(TEGRA_EMC_BASE, EMC_XM2DQSPADCTRL3), \
145 DEFINE_REG(TEGRA_EMC_BASE, EMC_CTT_TERM_CTRL), \
146 DEFINE_REG(TEGRA_EMC_BASE, EMC_ZCAL_INTERVAL), \
147 DEFINE_REG(TEGRA_EMC_BASE, EMC_ZCAL_WAIT_CNT), \
148 DEFINE_REG(TEGRA_EMC_BASE, EMC_MRS_WAIT_CNT), \
149 DEFINE_REG(TEGRA_EMC_BASE, EMC_AUTO_CAL_CONFIG), \
150 DEFINE_REG(TEGRA_EMC_BASE, EMC_CTT), \
151 DEFINE_REG(TEGRA_EMC_BASE, EMC_CTT_DURATION), \
152 DEFINE_REG(TEGRA_EMC_BASE, EMC_DYN_SELF_REF_CONTROL), \
153 \
154 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_CFG), \
155 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_OUTSTANDING_REQ), \
156 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_RCD), \
157 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_RP), \
158 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_RC), \
159 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_RAS), \
160 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_FAW), \
161 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_RRD), \
162 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_RAP2PRE), \
163 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_WAP2PRE), \
164 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_R2R), \
165 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_W2W), \
166 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_R2W), \
167 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_TIMING_W2R), \
168 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_DA_TURNS), \
169 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_DA_COVERS), \
170 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_MISC0), \
171 DEFINE_REG(TEGRA_MC_BASE, MC_EMEM_ARB_RING1_THROTTLE), \
172 \
173 DEFINE_REG(TEGRA_EMC_BASE, EMC_FBIO_SPARE), \
174 DEFINE_REG(TEGRA_EMC_BASE, EMC_CFG_RSV),
175
176#define DEFINE_REG(base, reg) ((base) ? ((u32)IO_ADDRESS((base)) + (reg)) : 0)
177static const u32 burst_reg_addr[TEGRA_EMC_NUM_REGS] = {
178 BURST_REG_LIST
179};
180#undef DEFINE_REG
181
182#define DEFINE_REG(base, reg) reg##_INDEX
183enum {
184 BURST_REG_LIST
185};
186#undef DEFINE_REG
187
188static int emc_num_burst_regs;
189
190static struct clk_mux_sel tegra_emc_clk_sel[TEGRA_EMC_TABLE_MAX_SIZE];
191static struct tegra_emc_table start_timing;
192static const struct tegra_emc_table *emc_timing;
193static unsigned long dram_over_temp_state = DRAM_OVER_TEMP_NONE;
194
195static const u32 *dram_to_soc_bit_map;
196static const struct tegra_emc_table *tegra_emc_table;
197static int tegra_emc_table_size;
198
199static u32 dram_dev_num;
200static u32 emc_cfg_saved;
201static u32 dram_type = -1;
202
203static struct clk *emc;
204static struct clk *bridge;
205
206static struct {
207 cputime64_t time_at_clock[TEGRA_EMC_TABLE_MAX_SIZE];
208 int last_sel;
209 u64 last_update;
210 u64 clkchange_count;
211 spinlock_t spinlock;
212} emc_stats;
213
214static DEFINE_SPINLOCK(emc_access_lock);
215
216static void __iomem *emc_base = IO_ADDRESS(TEGRA_EMC_BASE);
217static void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE);
218static void __iomem *clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
219
220static inline void emc_writel(u32 val, unsigned long addr)
221{
222 writel(val, (u32)emc_base + addr);
223 barrier();
224}
225static inline u32 emc_readl(unsigned long addr)
226{
227 return readl((u32)emc_base + addr);
228}
229static inline void mc_writel(u32 val, unsigned long addr)
230{
231 writel(val, (u32)mc_base + addr);
232 barrier();
233}
234static inline u32 mc_readl(unsigned long addr)
235{
236 return readl((u32)mc_base + addr);
237}
238
239static void emc_last_stats_update(int last_sel)
240{
241 unsigned long flags;
242 u64 cur_jiffies = get_jiffies_64();
243
244 spin_lock_irqsave(&emc_stats.spinlock, flags);
245
246 if (emc_stats.last_sel < TEGRA_EMC_TABLE_MAX_SIZE)
247 emc_stats.time_at_clock[emc_stats.last_sel] = cputime64_add(
248 emc_stats.time_at_clock[emc_stats.last_sel],
249 cputime64_sub(cur_jiffies, emc_stats.last_update));
250
251 emc_stats.last_update = cur_jiffies;
252
253 if (last_sel < TEGRA_EMC_TABLE_MAX_SIZE) {
254 emc_stats.clkchange_count++;
255 emc_stats.last_sel = last_sel;
256 }
257 spin_unlock_irqrestore(&emc_stats.spinlock, flags);
258}
259
260static int wait_for_update(u32 status_reg, u32 bit_mask, bool updated_state)
261{
262 int i;
263 for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++) {
264 if (!!(emc_readl(status_reg) & bit_mask) == updated_state)
265 return 0;
266 udelay(1);
267 }
268 return -ETIMEDOUT;
269}
270
271static inline void emc_timing_update(void)
272{
273 int err;
274
275 emc_writel(0x1, EMC_TIMING_CONTROL);
276 err = wait_for_update(EMC_STATUS,
277 EMC_STATUS_TIMING_UPDATE_STALLED, false);
278 if (err) {
279 pr_err("%s: timing update error: %d", __func__, err);
280 BUG();
281 }
282}
283
284static inline void auto_cal_disable(void)
285{
286 int err;
287
288 emc_writel(0, EMC_AUTO_CAL_INTERVAL);
289 err = wait_for_update(EMC_AUTO_CAL_STATUS,
290 EMC_AUTO_CAL_STATUS_ACTIVE, false);
291 if (err) {
292 pr_err("%s: disable auto-cal error: %d", __func__, err);
293 BUG();
294 }
295}
296
297static inline void set_over_temp_timing(
298 const struct tegra_emc_table *next_timing, unsigned long state)
299{
300#define REFRESH_SPEEDUP(val) \
301 do { \
302 val = ((val) & 0xFFFF0000) | (((val) & 0xFFFF) >> 2); \
303 } while (0)
304
305 u32 ref = next_timing->burst_regs[EMC_REFRESH_INDEX];
306 u32 pre_ref = next_timing->burst_regs[EMC_PRE_REFRESH_REQ_CNT_INDEX];
307 u32 dsr_cntrl = next_timing->burst_regs[EMC_DYN_SELF_REF_CONTROL_INDEX];
308
309 switch (state) {
310 case DRAM_OVER_TEMP_NONE:
311 break;
312 case DRAM_OVER_TEMP_REFRESH:
313 REFRESH_SPEEDUP(ref);
314 REFRESH_SPEEDUP(pre_ref);
315 REFRESH_SPEEDUP(dsr_cntrl);
316 break;
317 default:
318 pr_err("%s: Failed to set dram over temp state %lu\n",
319 __func__, state);
320 BUG();
321 }
322
323 __raw_writel(ref, burst_reg_addr[EMC_REFRESH_INDEX]);
324 __raw_writel(pre_ref, burst_reg_addr[EMC_PRE_REFRESH_REQ_CNT_INDEX]);
325 __raw_writel(dsr_cntrl, burst_reg_addr[EMC_DYN_SELF_REF_CONTROL_INDEX]);
326}
327
328static inline void set_mc_arbiter_limits(void)
329{
330 u32 reg = mc_readl(MC_EMEM_ARB_OUTSTANDING_REQ);
331 u32 max_val = 0x50 << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT;
332
333 if (!(reg & MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE) ||
334 ((reg & MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK) > max_val)) {
335 reg = MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE |
336 MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE | max_val;
337 mc_writel(reg, MC_EMEM_ARB_OUTSTANDING_REQ);
338 mc_writel(0x1, MC_TIMING_CONTROL);
339 }
340}
341
342static inline void disable_early_ack(u32 mc_override)
343{
344 static u32 override_val;
345
346 override_val = mc_override & (~MC_EMEM_ARB_OVERRIDE_EACK_MASK);
347 mc_writel(override_val, MC_EMEM_ARB_OVERRIDE);
348 __cpuc_flush_dcache_area(&override_val, sizeof(override_val));
349 outer_clean_range(__pa(&override_val), __pa(&override_val + 1));
350 override_val |= mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK;
351}
352
353static inline bool dqs_preset(const struct tegra_emc_table *next_timing,
354 const struct tegra_emc_table *last_timing)
355{
356 bool ret = false;
357
358#define DQS_SET(reg, bit) \
359 do { \
360 if ((next_timing->burst_regs[EMC_##reg##_INDEX] & \
361 EMC_##reg##_##bit##_ENABLE) && \
362 (!(last_timing->burst_regs[EMC_##reg##_INDEX] & \
363 EMC_##reg##_##bit##_ENABLE))) { \
364 emc_writel(last_timing->burst_regs[EMC_##reg##_INDEX] \
365 | EMC_##reg##_##bit##_ENABLE, EMC_##reg); \
366 ret = true; \
367 } \
368 } while (0)
369
370 DQS_SET(XM2DQSPADCTRL2, VREF);
371 DQS_SET(XM2DQSPADCTRL3, VREF);
372 DQS_SET(XM2QUSEPADCTRL, IVREF);
373
374 return ret;
375}
376
377static inline void overwrite_mrs_wait_cnt(
378 const struct tegra_emc_table *next_timing,
379 bool zcal_long)
380{
381 u32 reg;
382 u32 cnt = 512;
383
384 /* For ddr3 when DLL is re-started: overwrite EMC DFS table settings
385 for MRS_WAIT_LONG with maximum of MRS_WAIT_SHORT settings and
386 expected operation length. Reduce the latter by the overlapping
387 zq-calibration, if any */
388 if (zcal_long)
389 cnt -= dram_dev_num * 256;
390
391 reg = (next_timing->burst_regs[EMC_MRS_WAIT_CNT_INDEX] &
392 EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK) >>
393 EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT;
394 if (cnt < reg)
395 cnt = reg;
396
397 reg = (next_timing->burst_regs[EMC_MRS_WAIT_CNT_INDEX] &
398 (~EMC_MRS_WAIT_CNT_LONG_WAIT_MASK));
399 reg |= (cnt << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) &
400 EMC_MRS_WAIT_CNT_LONG_WAIT_MASK;
401
402 emc_writel(reg, EMC_MRS_WAIT_CNT);
403}
404
405static inline bool need_qrst(const struct tegra_emc_table *next_timing,
406 const struct tegra_emc_table *last_timing,
407 u32 emc_dpd_reg)
408{
409 u32 last_mode = (last_timing->burst_regs[EMC_FBIO_CFG5_INDEX] &
410 EMC_CFG5_QUSE_MODE_MASK) >> EMC_CFG5_QUSE_MODE_SHIFT;
411 u32 next_mode = (next_timing->burst_regs[EMC_FBIO_CFG5_INDEX] &
412 EMC_CFG5_QUSE_MODE_MASK) >> EMC_CFG5_QUSE_MODE_SHIFT;
413
414 /* QUSE DPD is disabled */
415 bool ret = !(emc_dpd_reg & EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE) &&
416
417 /* QUSE uses external mode before or after clock change */
418 (((last_mode != EMC_CFG5_QUSE_MODE_PULSE_INTERN) &&
419 (last_mode != EMC_CFG5_QUSE_MODE_INTERNAL_LPBK)) ||
420 ((next_mode != EMC_CFG5_QUSE_MODE_PULSE_INTERN) &&
421 (next_mode != EMC_CFG5_QUSE_MODE_INTERNAL_LPBK))) &&
422
423 /* QUSE pad switches from schmitt to vref mode */
424 (((last_timing->burst_regs[EMC_XM2QUSEPADCTRL_INDEX] &
425 EMC_XM2QUSEPADCTRL_IVREF_ENABLE) == 0) &&
426 ((next_timing->burst_regs[EMC_XM2QUSEPADCTRL_INDEX] &
427 EMC_XM2QUSEPADCTRL_IVREF_ENABLE) != 0));
428
429 return ret;
430}
431
432static inline void periodic_qrst_enable(u32 emc_cfg_reg, u32 emc_dbg_reg)
433{
434 /* enable write mux => enable periodic QRST => restore mux */
435 emc_writel(emc_dbg_reg | EMC_DBG_WRITE_MUX_ACTIVE, EMC_DBG);
436 emc_writel(emc_cfg_reg | EMC_CFG_PERIODIC_QRST, EMC_CFG);
437 emc_writel(emc_dbg_reg, EMC_DBG);
438}
439
440static inline int get_dll_change(const struct tegra_emc_table *next_timing,
441 const struct tegra_emc_table *last_timing)
442{
443 bool next_dll_enabled = !(next_timing->emc_mode_1 & 0x1);
444 bool last_dll_enabled = !(last_timing->emc_mode_1 & 0x1);
445
446 if (next_dll_enabled == last_dll_enabled)
447 return DLL_CHANGE_NONE;
448 else if (next_dll_enabled)
449 return DLL_CHANGE_ON;
450 else
451 return DLL_CHANGE_OFF;
452}
453
454static inline void set_dram_mode(const struct tegra_emc_table *next_timing,
455 const struct tegra_emc_table *last_timing,
456 int dll_change)
457{
458 if (dram_type == DRAM_TYPE_DDR3) {
459 /* first mode_1, then mode_2, then mode_reset*/
460 if (next_timing->emc_mode_1 != last_timing->emc_mode_1)
461 emc_writel(next_timing->emc_mode_1, EMC_EMRS);
462 if (next_timing->emc_mode_2 != last_timing->emc_mode_2)
463 emc_writel(next_timing->emc_mode_2, EMC_EMRS);
464
465 if ((next_timing->emc_mode_reset !=
466 last_timing->emc_mode_reset) ||
467 (dll_change == DLL_CHANGE_ON))
468 {
469 u32 reg = next_timing->emc_mode_reset &
470 (~EMC_MODE_SET_DLL_RESET);
471 if (dll_change == DLL_CHANGE_ON) {
472 reg |= EMC_MODE_SET_DLL_RESET;
473 reg |= EMC_MODE_SET_LONG_CNT;
474 }
475 emc_writel(reg, EMC_MRS);
476 }
477 } else {
478 /* first mode_2, then mode_1; mode_reset is not applicable */
479 if (next_timing->emc_mode_2 != last_timing->emc_mode_2)
480 emc_writel(next_timing->emc_mode_2, EMC_MRW);
481 if (next_timing->emc_mode_1 != last_timing->emc_mode_1)
482 emc_writel(next_timing->emc_mode_1, EMC_MRW);
483 }
484}
485
486static inline void do_clock_change(u32 clk_setting)
487{
488 int err;
489
490 mc_readl(MC_EMEM_ADR_CFG); /* completes prev writes */
491 writel(clk_setting, (u32)clk_base + emc->reg);
492
493 err = wait_for_update(EMC_INTSTATUS,
494 EMC_INTSTATUS_CLKCHANGE_COMPLETE, true);
495 if (err) {
496 pr_err("%s: clock change completion error: %d", __func__, err);
497 BUG();
498 }
499}
500
501static noinline void emc_set_clock(const struct tegra_emc_table *next_timing,
502 const struct tegra_emc_table *last_timing,
503 u32 clk_setting)
504{
505 int i, dll_change, pre_wait;
506 bool dyn_sref_enabled, vref_cal_toggle, qrst_used, zcal_long;
507
508 u32 mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
509 u32 emc_cfg_reg = emc_readl(EMC_CFG);
510 u32 emc_dbg_reg = emc_readl(EMC_DBG);
511
512 dyn_sref_enabled = emc_cfg_reg & EMC_CFG_DYN_SREF_ENABLE;
513 dll_change = get_dll_change(next_timing, last_timing);
514 zcal_long = (next_timing->burst_regs[EMC_ZCAL_INTERVAL_INDEX] != 0) &&
515 (last_timing->burst_regs[EMC_ZCAL_INTERVAL_INDEX] == 0);
516
517 /* FIXME: remove steps enumeration below? */
518
519 /* 1. clear clkchange_complete interrupts */
520 emc_writel(EMC_INTSTATUS_CLKCHANGE_COMPLETE, EMC_INTSTATUS);
521
522 /* 2. disable dynamic self-refresh and preset dqs vref, then wait for
523 possible self-refresh entry/exit and/or dqs vref settled - waiting
524 before the clock change decreases worst case change stall time */
525 pre_wait = 0;
526 if (dyn_sref_enabled) {
527 emc_cfg_reg &= ~EMC_CFG_DYN_SREF_ENABLE;
528 emc_writel(emc_cfg_reg, EMC_CFG);
529 pre_wait = 5; /* 5us+ for self-refresh entry/exit */
530 }
531
532 /* 2.25 update MC arbiter settings */
533 set_mc_arbiter_limits();
534 if (mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK)
535 disable_early_ack(mc_override);
536
537 /* 2.5 check dq/dqs vref delay */
538 if (dqs_preset(next_timing, last_timing)) {
539 if (pre_wait < 3)
540 pre_wait = 3; /* 3us+ for dqs vref settled */
541 }
542 if (pre_wait) {
543 emc_timing_update();
544 udelay(pre_wait);
545 }
546
547 /* 3. disable auto-cal if vref mode is switching */
548 vref_cal_toggle = (next_timing->emc_acal_interval != 0) &&
549 ((next_timing->burst_regs[EMC_XM2COMPPADCTRL_INDEX] ^
550 last_timing->burst_regs[EMC_XM2COMPPADCTRL_INDEX]) &
551 EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE);
552 if (vref_cal_toggle)
553 auto_cal_disable();
554
555 /* 4. program burst shadow registers */
556 for (i = 0; i < emc_num_burst_regs; i++) {
557 if (!burst_reg_addr[i])
558 continue;
559 __raw_writel(next_timing->burst_regs[i], burst_reg_addr[i]);
560 }
561 if ((dram_type == DRAM_TYPE_LPDDR2) &&
562 (dram_over_temp_state != DRAM_OVER_TEMP_NONE))
563 set_over_temp_timing(next_timing, dram_over_temp_state);
564 wmb();
565 barrier();
566
567 /* On ddr3 when DLL is re-started predict MRS long wait count and
568 overwrite DFS table setting */
569 if ((dram_type == DRAM_TYPE_DDR3) && (dll_change == DLL_CHANGE_ON))
570 overwrite_mrs_wait_cnt(next_timing, zcal_long);
571
572 /* the last read below makes sure prev writes are completed */
573 qrst_used = need_qrst(next_timing, last_timing,
574 emc_readl(EMC_SEL_DPD_CTRL));
575
576 /* 5. flow control marker 1 (no EMC read access after this) */
577 emc_writel(1, EMC_STALL_BEFORE_CLKCHANGE);
578
579 /* 6. enable periodic QRST */
580 if (qrst_used)
581 periodic_qrst_enable(emc_cfg_reg, emc_dbg_reg);
582
583 /* 6.1 disable auto-refresh to save time after clock change */
584 emc_writel(EMC_REFCTRL_DISABLE_ALL(dram_dev_num), EMC_REFCTRL);
585
586 /* 7. turn Off dll and enter self-refresh on DDR3 */
587 if (dram_type == DRAM_TYPE_DDR3) {
588 if (dll_change == DLL_CHANGE_OFF)
589 emc_writel(next_timing->emc_mode_1, EMC_EMRS);
590 emc_writel(DRAM_BROADCAST(dram_dev_num) |
591 EMC_SELF_REF_CMD_ENABLED, EMC_SELF_REF);
592 }
593
594 /* 8. flow control marker 2 */
595 emc_writel(1, EMC_STALL_AFTER_CLKCHANGE);
596
597 /* 8.1 enable write mux, update unshadowed pad control */
598 emc_writel(emc_dbg_reg | EMC_DBG_WRITE_MUX_ACTIVE, EMC_DBG);
599 emc_writel(next_timing->burst_regs[EMC_XM2CLKPADCTRL_INDEX],
600 EMC_XM2CLKPADCTRL);
601
602 /* 9. restore periodic QRST, and disable write mux */
603 if ((qrst_used) || (next_timing->emc_periodic_qrst !=
604 last_timing->emc_periodic_qrst)) {
605 emc_cfg_reg = next_timing->emc_periodic_qrst ?
606 emc_cfg_reg | EMC_CFG_PERIODIC_QRST :
607 emc_cfg_reg & (~EMC_CFG_PERIODIC_QRST);
608 emc_writel(emc_cfg_reg, EMC_CFG);
609 }
610 emc_writel(emc_dbg_reg, EMC_DBG);
611
612 /* 10. exit self-refresh on DDR3 */
613 if (dram_type == DRAM_TYPE_DDR3)
614 emc_writel(DRAM_BROADCAST(dram_dev_num), EMC_SELF_REF);
615
616 /* 11. set dram mode registers */
617 set_dram_mode(next_timing, last_timing, dll_change);
618
619 /* 12. issue zcal command if turning zcal On */
620 if (zcal_long) {
621 emc_writel(EMC_ZQ_CAL_LONG_CMD_DEV0, EMC_ZQ_CAL);
622 if (dram_dev_num > 1)
623 emc_writel(EMC_ZQ_CAL_LONG_CMD_DEV1, EMC_ZQ_CAL);
624 }
625
626 /* 13. flow control marker 3 */
627 emc_writel(1, EMC_UNSTALL_RW_AFTER_CLKCHANGE);
628
629 /* 14. read any MC register to ensure the programming is done
630 change EMC clock source register (EMC read access restored)
631 wait for clk change completion */
632 do_clock_change(clk_setting);
633
634 /* 14.1 re-enable auto-refresh */
635 emc_writel(EMC_REFCTRL_ENABLE_ALL(dram_dev_num), EMC_REFCTRL);
636
637 /* 15. restore auto-cal */
638 if (vref_cal_toggle)
639 emc_writel(next_timing->emc_acal_interval,
640 EMC_AUTO_CAL_INTERVAL);
641
642 /* 16. restore dynamic self-refresh */
643 if (next_timing->rev >= 0x32)
644 dyn_sref_enabled = next_timing->emc_dsr;
645 if (dyn_sref_enabled) {
646 emc_cfg_reg |= EMC_CFG_DYN_SREF_ENABLE;
647 emc_writel(emc_cfg_reg, EMC_CFG);
648 }
649
650 /* 17. set zcal wait count */
651 if (zcal_long)
652 emc_writel(next_timing->emc_zcal_cnt_long, EMC_ZCAL_WAIT_CNT);
653
654 /* 18. update restored timing */
655 udelay(2);
656 emc_timing_update();
657
658 /* 18.a restore early ACK */
659 mc_writel(mc_override, MC_EMEM_ARB_OVERRIDE);
660}
661
662static inline void emc_get_timing(struct tegra_emc_table *timing)
663{
664 int i;
665
666 for (i = 0; i < emc_num_burst_regs; i++) {
667 if (burst_reg_addr[i])
668 timing->burst_regs[i] = __raw_readl(burst_reg_addr[i]);
669 else
670 timing->burst_regs[i] = 0;
671 }
672 timing->emc_acal_interval = 0;
673 timing->emc_zcal_cnt_long = 0;
674 timing->emc_mode_reset = 0;
675 timing->emc_mode_1 = 0;
676 timing->emc_mode_2 = 0;
677 timing->emc_periodic_qrst = (emc_readl(EMC_CFG) &
678 EMC_CFG_PERIODIC_QRST) ? 1 : 0;
679}
680
681/* After deep sleep EMC power features are not restored.
682 * Do it at run-time after the 1st clock change.
683 */
684static inline void emc_cfg_power_restore(void)
685{
686 u32 reg = emc_readl(EMC_CFG);
687 u32 pwr_mask = EMC_CFG_PWR_MASK;
688
689 if (tegra_emc_table[0].rev >= 0x32)
690 pwr_mask &= ~EMC_CFG_DYN_SREF_ENABLE;
691
692 if ((reg ^ emc_cfg_saved) & pwr_mask) {
693 reg = (reg & (~pwr_mask)) | (emc_cfg_saved & pwr_mask);
694 emc_writel(reg, EMC_CFG);
695 emc_timing_update();
696 }
697}
698
699/* The EMC registers have shadow registers. When the EMC clock is updated
700 * in the clock controller, the shadow registers are copied to the active
701 * registers, allowing glitchless memory bus frequency changes.
702 * This function updates the shadow registers for a new clock frequency,
703 * and relies on the clock lock on the emc clock to avoid races between
704 * multiple frequency changes */
705int tegra_emc_set_rate(unsigned long rate)
706{
707 int i;
708 u32 clk_setting;
709 const struct tegra_emc_table *last_timing;
710 unsigned long flags;
711
712 if (!tegra_emc_table)
713 return -EINVAL;
714
715 /* Table entries specify rate in kHz */
716 rate = rate / 1000;
717
718 for (i = 0; i < tegra_emc_table_size; i++) {
719 if (tegra_emc_clk_sel[i].input == NULL)
720 continue; /* invalid entry */
721
722 if (tegra_emc_table[i].rate == rate)
723 break;
724 }
725
726 if (i >= tegra_emc_table_size)
727 return -EINVAL;
728
729 if (!emc_timing) {
730 /* can not assume that boot timing matches dfs table even
731 if boot frequency matches one of the table nodes */
732 emc_get_timing(&start_timing);
733 last_timing = &start_timing;
734 }
735 else
736 last_timing = emc_timing;
737
738 clk_setting = tegra_emc_clk_sel[i].value;
739
740 spin_lock_irqsave(&emc_access_lock, flags);
741 emc_set_clock(&tegra_emc_table[i], last_timing, clk_setting);
742 if (!emc_timing)
743 emc_cfg_power_restore();
744 emc_timing = &tegra_emc_table[i];
745 spin_unlock_irqrestore(&emc_access_lock, flags);
746
747 emc_last_stats_update(i);
748
749 pr_debug("%s: rate %lu setting 0x%x\n", __func__, rate, clk_setting);
750
751 return 0;
752}
753
754/* Select the closest EMC rate that is higher than the requested rate */
755long tegra_emc_round_rate(unsigned long rate)
756{
757 int i;
758 int best = -1;
759 unsigned long distance = ULONG_MAX;
760
761 if (!tegra_emc_table)
762 return clk_get_rate_locked(emc); /* no table - no rate change */
763
764 if (!emc_enable)
765 return -EINVAL;
766
767 pr_debug("%s: %lu\n", __func__, rate);
768
769 /* Table entries specify rate in kHz */
770 rate = rate / 1000;
771
772 for (i = 0; i < tegra_emc_table_size; i++) {
773 if (tegra_emc_clk_sel[i].input == NULL)
774 continue; /* invalid entry */
775
776 if (tegra_emc_table[i].rate >= rate &&
777 (tegra_emc_table[i].rate - rate) < distance) {
778 distance = tegra_emc_table[i].rate - rate;
779 best = i;
780 }
781 }
782
783 if (best < 0)
784 return -EINVAL;
785
786 pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
787
788 return tegra_emc_table[best].rate * 1000;
789}
790
791struct clk *tegra_emc_predict_parent(unsigned long rate, u32 *div_value)
792{
793 int i;
794
795 if (!tegra_emc_table)
796 return NULL;
797
798 pr_debug("%s: %lu\n", __func__, rate);
799
800 /* Table entries specify rate in kHz */
801 rate = rate / 1000;
802
803 for (i = 0; i < tegra_emc_table_size; i++) {
804 if (tegra_emc_table[i].rate == rate) {
805 *div_value = (tegra_emc_clk_sel[i].value &
806 EMC_CLK_DIV_MASK) >> EMC_CLK_DIV_SHIFT;
807 return tegra_emc_clk_sel[i].input;
808 }
809 }
810
811 return NULL;
812}
813
814static const struct clk_mux_sel *find_matching_input(
815 unsigned long table_rate,
816 u32 *div_value)
817{
818 unsigned long inp_rate;
819 const struct clk_mux_sel *sel;
820
821 for (sel = emc->inputs; sel->input != NULL; sel++) {
822 /* Table entries specify rate in kHz */
823 inp_rate = clk_get_rate(sel->input) / 1000;
824
825 if ((inp_rate >= table_rate) &&
826 (inp_rate % table_rate == 0)) {
827 *div_value = 2 * inp_rate / table_rate - 2;
828 return sel;
829 }
830 }
831 return NULL;
832}
833
834static void adjust_emc_dvfs_table(const struct tegra_emc_table *table,
835 int table_size)
836{
837 int i, j;
838 unsigned long rate;
839
840 if (table[0].rev < 0x33)
841 return;
842
843 for (i = 0; i < MAX_DVFS_FREQS; i++) {
844 int mv = emc->dvfs->millivolts[i];
845 if (!mv)
846 break;
847
848 /* For each dvfs voltage find maximum supported rate;
849 use 1MHz placeholder if not found */
850 for (rate = 1000, j = 0; j < table_size; j++) {
851 if (tegra_emc_clk_sel[j].input == NULL)
852 continue; /* invalid entry */
853
854 if ((mv >= table[j].emc_min_mv) &&
855 (rate < table[j].rate))
856 rate = table[j].rate;
857 }
858 /* Table entries specify rate in kHz */
859 emc->dvfs->freqs[i] = rate * 1000;
860 }
861}
862
863static bool is_emc_bridge(void)
864{
865 int mv;
866 unsigned long rate;
867
868 bridge = tegra_get_clock_by_name("bridge.emc");
869 BUG_ON(!bridge);
870
871 /* LPDDR2 does not need a bridge entry in DFS table: just lock bridge
872 rate at minimum so it won't interfere with emc bus operations */
873 if (dram_type == DRAM_TYPE_LPDDR2) {
874 clk_set_rate(bridge, 0);
875 return true;
876 }
877
878 /* DDR3 requires EMC DFS table to include a bridge entry with frequency
879 above minimum bridge threshold, and voltage below bridge threshold */
880 rate = clk_round_rate(bridge, TEGRA_EMC_BRIDGE_RATE_MIN);
881 if (IS_ERR_VALUE(rate))
882 return false;
883
884 mv = tegra_dvfs_predict_millivolts(emc, rate);
885 if (IS_ERR_VALUE(mv) || (mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN))
886 return false;
887
888 if (clk_set_rate(bridge, rate))
889 return false;
890
891 return true;
892}
893
894static int tegra_emc_suspend_notify(struct notifier_block *nb,
895 unsigned long event, void *data)
896{
897 if (event != PM_SUSPEND_PREPARE)
898 return NOTIFY_OK;
899
900 if (dram_type == DRAM_TYPE_DDR3) {
901 if (clk_enable(bridge)) {
902 pr_info("Tegra emc suspend:"
903 " failed to enable bridge.emc\n");
904 return NOTIFY_STOP;
905 }
906 pr_info("Tegra emc suspend: enabled bridge.emc\n");
907 }
908 return NOTIFY_OK;
909};
910static struct notifier_block tegra_emc_suspend_nb = {
911 .notifier_call = tegra_emc_suspend_notify,
912 .priority = 2,
913};
914
915static int tegra_emc_resume_notify(struct notifier_block *nb,
916 unsigned long event, void *data)
917{
918 if (event != PM_POST_SUSPEND)
919 return NOTIFY_OK;
920
921 if (dram_type == DRAM_TYPE_DDR3) {
922 clk_disable(bridge);
923 pr_info("Tegra emc resume: disabled bridge.emc\n");
924 }
925 return NOTIFY_OK;
926};
927static struct notifier_block tegra_emc_resume_nb = {
928 .notifier_call = tegra_emc_resume_notify,
929 .priority = -1,
930};
931
932void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
933{
934 int i, mv;
935 u32 reg, div_value;
936 bool max_entry = false;
937 unsigned long boot_rate, max_rate;
938 const struct clk_mux_sel *sel;
939
940 emc_stats.clkchange_count = 0;
941 spin_lock_init(&emc_stats.spinlock);
942 emc_stats.last_update = get_jiffies_64();
943 emc_stats.last_sel = TEGRA_EMC_TABLE_MAX_SIZE;
944
945 boot_rate = clk_get_rate(emc) / 1000;
946 max_rate = clk_get_max_rate(emc) / 1000;
947
948 if ((dram_type != DRAM_TYPE_DDR3) && (dram_type != DRAM_TYPE_LPDDR2)) {
949 pr_err("tegra: not supported DRAM type %u\n", dram_type);
950 return;
951 }
952
953 if (emc->parent != tegra_get_clock_by_name("pll_m")) {
954 pr_err("tegra: boot parent %s is not supported by EMC DFS\n",
955 emc->parent->name);
956 return;
957 }
958
959 if (!table || !table_size) {
960 pr_err("tegra: EMC DFS table is empty\n");
961 return;
962 }
963
964 tegra_emc_table_size = min(table_size, TEGRA_EMC_TABLE_MAX_SIZE);
965 switch (table[0].rev) {
966 case 0x30:
967 emc_num_burst_regs = 105;
968 break;
969 case 0x31:
970 case 0x32:
971 case 0x33:
972 emc_num_burst_regs = 107;
973 break;
974 default:
975 pr_err("tegra: invalid EMC DFS table: unknown rev 0x%x\n",
976 table[0].rev);
977 return;
978 }
979
980 /* Match EMC source/divider settings with table entries */
981 for (i = 0; i < tegra_emc_table_size; i++) {
982 unsigned long table_rate = table[i].rate;
983 if (!table_rate)
984 continue;
985
986 BUG_ON(table[i].rev != table[0].rev);
987
988 sel = find_matching_input(table_rate, &div_value);
989 if (!sel)
990 continue;
991
992 if (table_rate == boot_rate)
993 emc_stats.last_sel = i;
994
995 if (table_rate == max_rate)
996 max_entry = true;
997
998 tegra_emc_clk_sel[i] = *sel;
999 BUG_ON(div_value >
1000 (EMC_CLK_DIV_MASK >> EMC_CLK_DIV_SHIFT));
1001 tegra_emc_clk_sel[i].value <<= EMC_CLK_SOURCE_SHIFT;
1002 tegra_emc_clk_sel[i].value |= (div_value << EMC_CLK_DIV_SHIFT);
1003
1004 if ((div_value == 0) &&
1005 (tegra_emc_clk_sel[i].input == emc->parent)) {
1006 tegra_emc_clk_sel[i].value |= EMC_CLK_LOW_JITTER_ENABLE;
1007 }
1008
1009 if (table[i].burst_regs[MC_EMEM_ARB_MISC0_INDEX] &
1010 MC_EMEM_ARB_MISC0_EMC_SAME_FREQ)
1011 tegra_emc_clk_sel[i].value |= EMC_CLK_MC_SAME_FREQ;
1012 }
1013
1014 /* Validate EMC rate and voltage limits */
1015 if (!max_entry) {
1016 pr_err("tegra: invalid EMC DFS table: entry for max rate"
1017 " %lu kHz is not found\n", max_rate);
1018 return;
1019 }
1020
1021 tegra_emc_table = table;
1022
1023 adjust_emc_dvfs_table(tegra_emc_table, tegra_emc_table_size);
1024 mv = tegra_dvfs_predict_millivolts(emc, max_rate * 1000);
1025 if ((mv <= 0) || (mv > emc->dvfs->max_millivolts)) {
1026 tegra_emc_table = NULL;
1027 pr_err("tegra: invalid EMC DFS table: maximum rate %lu kHz does"
1028 " not match nominal voltage %d\n",
1029 max_rate, emc->dvfs->max_millivolts);
1030 return;
1031 }
1032
1033 if (!is_emc_bridge()) {
1034 tegra_emc_table = NULL;
1035 pr_err("tegra: invalid EMC DFS table: emc bridge not found");
1036 return;
1037 }
1038 pr_info("tegra: validated EMC DFS table\n");
1039
1040 /* Configure clock change mode according to dram type */
1041 reg = emc_readl(EMC_CFG_2) & (~EMC_CFG_2_MODE_MASK);
1042 reg |= ((dram_type == DRAM_TYPE_LPDDR2) ? EMC_CFG_2_PD_MODE :
1043 EMC_CFG_2_SREF_MODE) << EMC_CFG_2_MODE_SHIFT;
1044 emc_writel(reg, EMC_CFG_2);
1045
1046 register_pm_notifier(&tegra_emc_suspend_nb);
1047 register_pm_notifier(&tegra_emc_resume_nb);
1048}
1049
1050void tegra_emc_timing_invalidate(void)
1051{
1052 emc_timing = NULL;
1053}
1054
1055void tegra_init_dram_bit_map(const u32 *bit_map, int map_size)
1056{
1057 BUG_ON(map_size != 32);
1058 dram_to_soc_bit_map = bit_map;
1059}
1060
1061void tegra_emc_dram_type_init(struct clk *c)
1062{
1063 emc = c;
1064
1065 dram_type = (emc_readl(EMC_FBIO_CFG5) &
1066 EMC_CFG5_TYPE_MASK) >> EMC_CFG5_TYPE_SHIFT;
1067 if (dram_type == DRAM_TYPE_DDR3)
1068 emc->min_rate = EMC_MIN_RATE_DDR3;
1069
1070 dram_dev_num = (mc_readl(MC_EMEM_ADR_CFG) & 0x1) + 1; /* 2 dev max */
1071 emc_cfg_saved = emc_readl(EMC_CFG);
1072}
1073
1074int tegra_emc_get_dram_type(void)
1075{
1076 return dram_type;
1077}
1078
1079static u32 soc_to_dram_bit_swap(u32 soc_val, u32 dram_mask, u32 dram_shift)
1080{
1081 int bit;
1082 u32 dram_val = 0;
1083
1084 /* tegra clocks definitions use shifted mask always */
1085 if (!dram_to_soc_bit_map)
1086 return soc_val & dram_mask;
1087
1088 for (bit = dram_shift; bit < 32; bit++) {
1089 u32 dram_bit_mask = 0x1 << bit;
1090 u32 soc_bit_mask = dram_to_soc_bit_map[bit];
1091
1092 if (!(dram_bit_mask & dram_mask))
1093 break;
1094
1095 if (soc_bit_mask & soc_val)
1096 dram_val |= dram_bit_mask;
1097 }
1098
1099 return dram_val;
1100}
1101
1102static int emc_read_mrr(int dev, int addr)
1103{
1104 int ret;
1105 u32 val;
1106
1107 if (dram_type != DRAM_TYPE_LPDDR2)
1108 return -ENODEV;
1109
1110 ret = wait_for_update(EMC_STATUS, EMC_STATUS_MRR_DIVLD, false);
1111 if (ret)
1112 return ret;
1113
1114 val = dev ? DRAM_DEV_SEL_1 : DRAM_DEV_SEL_0;
1115 val |= (addr << EMC_MRR_MA_SHIFT) & EMC_MRR_MA_MASK;
1116 emc_writel(val, EMC_MRR);
1117
1118 ret = wait_for_update(EMC_STATUS, EMC_STATUS_MRR_DIVLD, true);
1119 if (ret)
1120 return ret;
1121
1122 val = emc_readl(EMC_MRR) & EMC_MRR_DATA_MASK;
1123 return val;
1124}
1125
1126int tegra_emc_get_dram_temperature(void)
1127{
1128 int mr4;
1129 unsigned long flags;
1130
1131 spin_lock_irqsave(&emc_access_lock, flags);
1132
1133 mr4 = emc_read_mrr(0, 4);
1134 if (IS_ERR_VALUE(mr4)) {
1135 spin_unlock_irqrestore(&emc_access_lock, flags);
1136 return mr4;
1137 }
1138 spin_unlock_irqrestore(&emc_access_lock, flags);
1139
1140 mr4 = soc_to_dram_bit_swap(
1141 mr4, LPDDR2_MR4_TEMP_MASK, LPDDR2_MR4_TEMP_SHIFT);
1142 return mr4;
1143}
1144
1145int tegra_emc_set_over_temp_state(unsigned long state)
1146{
1147 unsigned long flags;
1148
1149 if (dram_type != DRAM_TYPE_LPDDR2)
1150 return -ENODEV;
1151
1152 spin_lock_irqsave(&emc_access_lock, flags);
1153
1154 /* Update refresh timing if state changed */
1155 if (emc_timing && (dram_over_temp_state != state)) {
1156 set_over_temp_timing(emc_timing, state);
1157 emc_timing_update();
1158 if (state != DRAM_OVER_TEMP_NONE)
1159 emc_writel(EMC_REF_FORCE_CMD, EMC_REF);
1160 dram_over_temp_state = state;
1161 }
1162 spin_unlock_irqrestore(&emc_access_lock, flags);
1163 return 0;
1164}
1165
1166#ifdef CONFIG_DEBUG_FS
1167
1168static struct dentry *emc_debugfs_root;
1169
1170static int emc_stats_show(struct seq_file *s, void *data)
1171{
1172 int i;
1173
1174 emc_last_stats_update(TEGRA_EMC_TABLE_MAX_SIZE);
1175
1176 seq_printf(s, "%-10s %-10s \n", "rate kHz", "time");
1177 for (i = 0; i < tegra_emc_table_size; i++) {
1178 if (tegra_emc_clk_sel[i].input == NULL)
1179 continue; /* invalid entry */
1180
1181 seq_printf(s, "%-10lu %-10llu \n", tegra_emc_table[i].rate,
1182 cputime64_to_clock_t(emc_stats.time_at_clock[i]));
1183 }
1184 seq_printf(s, "%-15s %llu\n", "transitions:",
1185 emc_stats.clkchange_count);
1186 seq_printf(s, "%-15s %llu\n", "time-stamp:",
1187 cputime64_to_clock_t(emc_stats.last_update));
1188
1189 return 0;
1190}
1191
1192static int emc_stats_open(struct inode *inode, struct file *file)
1193{
1194 return single_open(file, emc_stats_show, inode->i_private);
1195}
1196
1197static const struct file_operations emc_stats_fops = {
1198 .open = emc_stats_open,
1199 .read = seq_read,
1200 .llseek = seq_lseek,
1201 .release = single_release,
1202};
1203
1204static int dram_temperature_get(void *data, u64 *val)
1205{
1206 *val = tegra_emc_get_dram_temperature();
1207 return 0;
1208}
1209DEFINE_SIMPLE_ATTRIBUTE(dram_temperature_fops, dram_temperature_get,
1210 NULL, "%lld\n");
1211
1212static int over_temp_state_get(void *data, u64 *val)
1213{
1214 *val = dram_over_temp_state;
1215 return 0;
1216}
1217static int over_temp_state_set(void *data, u64 val)
1218{
1219 tegra_emc_set_over_temp_state(val);
1220 return 0;
1221}
1222DEFINE_SIMPLE_ATTRIBUTE(over_temp_state_fops, over_temp_state_get,
1223 over_temp_state_set, "%llu\n");
1224
1225static int __init tegra_emc_debug_init(void)
1226{
1227 if (!tegra_emc_table)
1228 return 0;
1229
1230 emc_debugfs_root = debugfs_create_dir("tegra_emc", NULL);
1231 if (!emc_debugfs_root)
1232 return -ENOMEM;
1233
1234 if (!debugfs_create_file(
1235 "stats", S_IRUGO, emc_debugfs_root, NULL, &emc_stats_fops))
1236 goto err_out;
1237
1238 if (!debugfs_create_file("dram_temperature", S_IRUGO, emc_debugfs_root,
1239 NULL, &dram_temperature_fops))
1240 goto err_out;
1241
1242 if (!debugfs_create_file("over_temp_state", S_IRUGO | S_IWUSR,
1243 emc_debugfs_root, NULL, &over_temp_state_fops))
1244 goto err_out;
1245
1246 return 0;
1247
1248err_out:
1249 debugfs_remove_recursive(emc_debugfs_root);
1250 return -ENOMEM;
1251}
1252
1253late_initcall(tegra_emc_debug_init);
1254#endif
diff --git a/arch/arm/mach-tegra/tegra3_emc.h b/arch/arm/mach-tegra/tegra3_emc.h
new file mode 100644
index 00000000000..cfde92c1355
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_emc.h
@@ -0,0 +1,297 @@
1/*
2 * arch/arm/mach-tegra/tegra3_emc.h
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef _MACH_TEGRA_TEGRA3_EMC_H
23#define _MACH_TEGRA_TEGRA3_EMC_H
24
25#define TEGRA_EMC_NUM_REGS 110
26
27#define TEGRA_EMC_BRIDGE_RATE_MIN 300000000
28#define TEGRA_EMC_BRIDGE_MVOLTS_MIN 1200
29
30struct tegra_emc_table {
31 u8 rev;
32 unsigned long rate;
33
34 /* unconditionally updated in one burst shot */
35 u32 burst_regs[TEGRA_EMC_NUM_REGS];
36
37 /* updated separately under some conditions */
38 u32 emc_zcal_cnt_long;
39 u32 emc_acal_interval;
40 u32 emc_periodic_qrst;
41 u32 emc_mode_reset;
42 u32 emc_mode_1;
43 u32 emc_mode_2;
44 u32 emc_dsr;
45 int emc_min_mv;
46};
47
48enum {
49 DRAM_OVER_TEMP_NONE = 0,
50 DRAM_OVER_TEMP_REFRESH,
51};
52
53struct clk;
54
55void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
56
57void tegra_init_dram_bit_map(const u32 *bit_map, int map_size);
58void tegra_emc_dram_type_init(struct clk *c);
59int tegra_emc_get_dram_type(void);
60int tegra_emc_get_dram_temperature(void);
61int tegra_emc_set_over_temp_state(unsigned long state);
62
63#ifdef CONFIG_PM_SLEEP
64void tegra_mc_timing_restore(void);
65#else
66static inline void tegra_mc_timing_restore(void)
67{ }
68#endif
69
70#define EMC_INTSTATUS 0x0
71#define EMC_INTSTATUS_CLKCHANGE_COMPLETE (0x1 << 4)
72
73#define EMC_DBG 0x8
74#define EMC_DBG_WRITE_MUX_ACTIVE (0x1 << 1)
75
76#define EMC_CFG 0xc
77#define EMC_CFG_PERIODIC_QRST (0x1 << 21)
78#define EMC_CFG_DYN_SREF_ENABLE (0x1 << 28)
79#define EMC_CFG_PWR_MASK (0xF << 28)
80
81#define EMC_REFCTRL 0x20
82#define EMC_REFCTRL_DEV_SEL_SHIFT 0
83#define EMC_REFCTRL_DEV_SEL_MASK (0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)
84#define EMC_REFCTRL_ENABLE (0x1 << 31)
85#define EMC_REFCTRL_ENABLE_ALL(num) \
86 ((((num > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) \
87 | EMC_REFCTRL_ENABLE)
88#define EMC_REFCTRL_DISABLE_ALL(num) \
89 (((num > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)
90
91#define EMC_TIMING_CONTROL 0x28
92#define EMC_RC 0x2c
93#define EMC_RFC 0x30
94#define EMC_RAS 0x34
95#define EMC_RP 0x38
96#define EMC_R2W 0x3c
97#define EMC_W2R 0x40
98#define EMC_R2P 0x44
99#define EMC_W2P 0x48
100#define EMC_RD_RCD 0x4c
101#define EMC_WR_RCD 0x50
102#define EMC_RRD 0x54
103#define EMC_REXT 0x58
104#define EMC_WDV 0x5c
105#define EMC_QUSE 0x60
106#define EMC_QRST 0x64
107#define EMC_QSAFE 0x68
108#define EMC_RDV 0x6c
109#define EMC_REFRESH 0x70
110#define EMC_BURST_REFRESH_NUM 0x74
111#define EMC_PDEX2WR 0x78
112#define EMC_PDEX2RD 0x7c
113#define EMC_PCHG2PDEN 0x80
114#define EMC_ACT2PDEN 0x84
115#define EMC_AR2PDEN 0x88
116#define EMC_RW2PDEN 0x8c
117#define EMC_TXSR 0x90
118#define EMC_TCKE 0x94
119#define EMC_TFAW 0x98
120#define EMC_TRPAB 0x9c
121#define EMC_TCLKSTABLE 0xa0
122#define EMC_TCLKSTOP 0xa4
123#define EMC_TREFBW 0xa8
124#define EMC_QUSE_EXTRA 0xac
125#define EMC_ODT_WRITE 0xb0
126#define EMC_ODT_READ 0xb4
127#define EMC_WEXT 0xb8
128#define EMC_CTT 0xbc
129
130#define EMC_MRS_WAIT_CNT 0xc8
131#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0
132#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \
133 (0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)
134#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16
135#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \
136 (0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)
137
138#define EMC_MRS 0xcc
139#define EMC_MODE_SET_DLL_RESET (0x1 << 8)
140#define EMC_MODE_SET_LONG_CNT (0x1 << 26)
141#define EMC_EMRS 0xd0
142#define EMC_REF 0xd4
143#define EMC_REF_FORCE_CMD 1
144
145#define EMC_SELF_REF 0xe0
146#define EMC_SELF_REF_CMD_ENABLED (0x1 << 0)
147#define EMC_SELF_REF_DEV_SEL_SHIFT 30
148#define EMC_SELF_REF_DEV_SEL_MASK (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
149enum {
150 DRAM_DEV_SEL_ALL = 0,
151 DRAM_DEV_SEL_0 = (2 << EMC_SELF_REF_DEV_SEL_SHIFT),
152 DRAM_DEV_SEL_1 = (1 << EMC_SELF_REF_DEV_SEL_SHIFT),
153};
154#define DRAM_BROADCAST(num) \
155 (((num) > 1) ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0)
156
157#define EMC_MRW 0xe8
158#define EMC_MRR 0xec
159#define EMC_MRR_MA_SHIFT 16
160#define EMC_MRR_MA_MASK (0xFF << EMC_MRR_MA_SHIFT)
161#define EMC_MRR_DATA_MASK ((0x1 << EMC_MRR_MA_SHIFT) - 1)
162#define LPDDR2_MR4_TEMP_SHIFT 0
163#define LPDDR2_MR4_TEMP_MASK (0x7 << LPDDR2_MR4_TEMP_SHIFT)
164
165#define EMC_XM2DQSPADCTRL3 0xf8
166#define EMC_XM2DQSPADCTRL3_VREF_ENABLE (0x1 << 5)
167#define EMC_FBIO_SPARE 0x100
168
169#define EMC_FBIO_CFG5 0x104
170#define EMC_CFG5_TYPE_SHIFT 0x0
171#define EMC_CFG5_TYPE_MASK (0x3 << EMC_CFG5_TYPE_SHIFT)
172enum {
173 DRAM_TYPE_DDR3 = 0,
174 DRAM_TYPE_LPDDR2 = 2,
175};
176#define EMC_CFG5_QUSE_MODE_SHIFT 13
177#define EMC_CFG5_QUSE_MODE_MASK (0x7 << EMC_CFG5_QUSE_MODE_SHIFT)
178enum {
179 EMC_CFG5_QUSE_MODE_NORMAL = 0,
180 EMC_CFG5_QUSE_MODE_ALWAYS_ON,
181 EMC_CFG5_QUSE_MODE_INTERNAL_LPBK,
182 EMC_CFG5_QUSE_MODE_PULSE_INTERN,
183 EMC_CFG5_QUSE_MODE_PULSE_EXTERN,
184};
185
186#define EMC_FBIO_CFG6 0x114
187#define EMC_CFG_RSV 0x120
188#define EMC_AUTO_CAL_CONFIG 0x2a4
189#define EMC_AUTO_CAL_INTERVAL 0x2a8
190#define EMC_AUTO_CAL_STATUS 0x2ac
191#define EMC_AUTO_CAL_STATUS_ACTIVE (0x1 << 31)
192#define EMC_STATUS 0x2b4
193#define EMC_STATUS_TIMING_UPDATE_STALLED (0x1 << 23)
194#define EMC_STATUS_MRR_DIVLD (0x1 << 20)
195
196#define EMC_CFG_2 0x2b8
197#define EMC_CFG_2_MODE_SHIFT 0
198#define EMC_CFG_2_MODE_MASK (0x7 << EMC_CFG_2_MODE_SHIFT)
199#define EMC_CFG_2_SREF_MODE 0x1
200#define EMC_CFG_2_PD_MODE 0x3
201
202#define EMC_CFG_DIG_DLL 0x2bc
203#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
204#define EMC_CTT_DURATION 0x2d8
205#define EMC_CTT_TERM_CTRL 0x2dc
206#define EMC_ZCAL_INTERVAL 0x2e0
207#define EMC_ZCAL_WAIT_CNT 0x2e4
208
209#define EMC_ZQ_CAL 0x2ec
210#define EMC_ZQ_CAL_CMD (0x1 << 0)
211#define EMC_ZQ_CAL_LONG (0x1 << 4)
212#define EMC_ZQ_CAL_LONG_CMD_DEV0 \
213 (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
214#define EMC_ZQ_CAL_LONG_CMD_DEV1 \
215 (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
216
217#define EMC_XM2CMDPADCTRL 0x2f0
218#define EMC_XM2DQSPADCTRL2 0x2fc
219#define EMC_XM2DQSPADCTRL2_VREF_ENABLE (0x1 << 5)
220#define EMC_XM2DQPADCTRL2 0x304
221#define EMC_XM2CLKPADCTRL 0x308
222#define EMC_XM2COMPPADCTRL 0x30c
223#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE (0x1 << 10)
224#define EMC_XM2VTTGENPADCTRL 0x310
225#define EMC_XM2VTTGENPADCTRL2 0x314
226#define EMC_XM2QUSEPADCTRL 0x318
227#define EMC_XM2QUSEPADCTRL_IVREF_ENABLE (0x1 << 4)
228#define EMC_DLL_XFORM_DQS0 0x328
229#define EMC_DLL_XFORM_DQS1 0x32c
230#define EMC_DLL_XFORM_DQS2 0x330
231#define EMC_DLL_XFORM_DQS3 0x334
232#define EMC_DLL_XFORM_DQS4 0x338
233#define EMC_DLL_XFORM_DQS5 0x33c
234#define EMC_DLL_XFORM_DQS6 0x340
235#define EMC_DLL_XFORM_DQS7 0x344
236#define EMC_DLL_XFORM_QUSE0 0x348
237#define EMC_DLL_XFORM_QUSE1 0x34c
238#define EMC_DLL_XFORM_QUSE2 0x350
239#define EMC_DLL_XFORM_QUSE3 0x354
240#define EMC_DLL_XFORM_QUSE4 0x358
241#define EMC_DLL_XFORM_QUSE5 0x35c
242#define EMC_DLL_XFORM_QUSE6 0x360
243#define EMC_DLL_XFORM_QUSE7 0x364
244#define EMC_DLL_XFORM_DQ0 0x368
245#define EMC_DLL_XFORM_DQ1 0x36c
246#define EMC_DLL_XFORM_DQ2 0x370
247#define EMC_DLL_XFORM_DQ3 0x374
248#define EMC_DLI_TRIM_TXDQS0 0x3a8
249#define EMC_DLI_TRIM_TXDQS1 0x3ac
250#define EMC_DLI_TRIM_TXDQS2 0x3b0
251#define EMC_DLI_TRIM_TXDQS3 0x3b4
252#define EMC_DLI_TRIM_TXDQS4 0x3b8
253#define EMC_DLI_TRIM_TXDQS5 0x3bc
254#define EMC_DLI_TRIM_TXDQS6 0x3c0
255#define EMC_DLI_TRIM_TXDQS7 0x3c4
256#define EMC_STALL_BEFORE_CLKCHANGE 0x3c8
257#define EMC_STALL_AFTER_CLKCHANGE 0x3cc
258#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0
259#define EMC_SEL_DPD_CTRL 0x3d8
260#define EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE (0x1 << 9)
261#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
262#define EMC_DYN_SELF_REF_CONTROL 0x3e0
263#define EMC_TXSRDLL 0x3e4
264
265#define MC_EMEM_ADR_CFG 0x54
266#define MC_EMEM_ARB_CFG 0x90
267#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
268#define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_SHIFT 0
269#define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK \
270 (0x1FF << MC_EMEM_ARB_OUTSTANDING_REQ_MAX_SHIFT)
271#define MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE (0x1 << 30)
272#define MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE (0x1 << 31)
273#define MC_EMEM_ARB_TIMING_RCD 0x98
274#define MC_EMEM_ARB_TIMING_RP 0x9c
275#define MC_EMEM_ARB_TIMING_RC 0xa0
276#define MC_EMEM_ARB_TIMING_RAS 0xa4
277#define MC_EMEM_ARB_TIMING_FAW 0xa8
278#define MC_EMEM_ARB_TIMING_RRD 0xac
279#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
280#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
281#define MC_EMEM_ARB_TIMING_R2R 0xb8
282#define MC_EMEM_ARB_TIMING_W2W 0xbc
283#define MC_EMEM_ARB_TIMING_R2W 0xc0
284#define MC_EMEM_ARB_TIMING_W2R 0xc4
285#define MC_EMEM_ARB_DA_TURNS 0xd0
286#define MC_EMEM_ARB_DA_COVERS 0xd4
287#define MC_EMEM_ARB_MISC0 0xd8
288#define MC_EMEM_ARB_MISC0_EMC_SAME_FREQ (0x1 << 27)
289#define MC_EMEM_ARB_MISC1 0xdc
290#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
291#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
292#define MC_EMEM_ARB_OVERRIDE 0xe8
293#define MC_EMEM_ARB_OVERRIDE_EACK_MASK (0x3 << 0)
294#define MC_TIMING_CONTROL 0xfc
295#define MC_RESERVED_RSV 0x3fc
296
297#endif
diff --git a/arch/arm/mach-tegra/tegra3_speedo.c b/arch/arm/mach-tegra/tegra3_speedo.c
new file mode 100644
index 00000000000..bd880bc7ca8
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_speedo.c
@@ -0,0 +1,541 @@
1/*
2 * arch/arm/mach-tegra/tegra3_speedo.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/io.h>
23#include <linux/err.h>
24#include <mach/iomap.h>
25#include <mach/tegra_fuse.h>
26
27#include "fuse.h"
28
29#define CORE_PROCESS_CORNERS_NUM 1
30#define CPU_PROCESS_CORNERS_NUM 7
31
32#define FUSE_SPEEDO_CALIB_0 0x114
33#define FUSE_PACKAGE_INFO 0X1FC
34#define FUSE_TEST_PROG_VER 0X128
35#define FUSE_SPARE_BIT_58 0x32c
36#define FUSE_SPARE_BIT_59 0x330
37#define FUSE_SPARE_BIT_60 0x334
38#define FUSE_SPARE_BIT_61 0x338
39#define FUSE_SPARE_BIT_62 0x33c
40#define FUSE_SPARE_BIT_63 0x340
41#define FUSE_SPARE_BIT_64 0x344
42#define FUSE_SPARE_BIT_65 0x348
43
44#define G_SPEEDO_BIT_MINUS1 FUSE_SPARE_BIT_58
45#define G_SPEEDO_BIT_MINUS1_R FUSE_SPARE_BIT_59
46#define G_SPEEDO_BIT_MINUS2 FUSE_SPARE_BIT_60
47#define G_SPEEDO_BIT_MINUS2_R FUSE_SPARE_BIT_61
48#define LP_SPEEDO_BIT_MINUS1 FUSE_SPARE_BIT_62
49#define LP_SPEEDO_BIT_MINUS1_R FUSE_SPARE_BIT_63
50#define LP_SPEEDO_BIT_MINUS2 FUSE_SPARE_BIT_64
51#define LP_SPEEDO_BIT_MINUS2_R FUSE_SPARE_BIT_65
52
53/* Maximum speedo levels for each core process corner */
54static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
55/* proc_id 0 */
56 {180}, /* [0]: soc_speedo_id 0: any A01 */
57
58/* T30 family */
59 {170}, /* [1]: soc_speedo_id 1: AP30 */
60 {195}, /* [2]: soc_speedo_id 2: T30 */
61 {180}, /* [3]: soc_speedo_id 2: T30S */
62
63/* Characterization SKUs */
64 {168}, /* [4]: soc_speedo_id 1: AP30 char */
65 {192}, /* [5]: soc_speedo_id 2: T30 char */
66 {180}, /* [6]: soc_speedo_id 2: T30S char */
67
68/* T33 family */
69 {170}, /* [7]: soc_speedo_id = 1 - AP33 */
70 {195}, /* [8]: soc_speedo_id = 2 - T33 */
71 {180}, /* [9]: soc_speedo_id = 2 - T33S/AP37 */
72
73/* T30 'L' family */
74 {180}, /* [10]: soc_speedo_id 1: T30L */
75 {180}, /* [11]: soc_speedo_id 1: T30SL */
76
77/* T30 Automotives */
78 {185}, /* [12]: soc_speedo_id = 3 - Automotives */
79 {185}, /* [13]: soc_speedo_id = 3 - Automotives */
80
81/* T37 Family*/
82 {210}, /* [14]: soc_speedo_id 2: T37 */
83};
84
85/* Maximum speedo levels for each CPU process corner */
86static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
87/* proc_id 0 1 2 3 4*/
88 {306, 338, 360, 376, UINT_MAX}, /* [0]: cpu_speedo_id 0: any A01 */
89
90/* T30 family */
91 {295, 336, 358, 375, UINT_MAX}, /* [1]: cpu_speedo_id 1: AP30 */
92 {325, 325, 358, 375, UINT_MAX}, /* [2]: cpu_speedo_id 2: T30 */
93 {325, 325, 358, 375, UINT_MAX}, /* [3]: cpu_speedo_id 3: T30S */
94
95/* Characterization SKUs */
96 {292, 324, 348, 364, UINT_MAX}, /* [4]: cpu_speedo_id 1: AP30char */
97 {324, 324, 348, 364, UINT_MAX}, /* [5]: cpu_speedo_id 2: T30char */
98 {324, 324, 348, 364, UINT_MAX}, /* [6]: cpu_speedo_id 3: T30Schar */
99
100/* T33 family */
101 {295, 336, 358, 375, UINT_MAX}, /* [7]: cpu_speedo_id: 4: AP33 */
102 {358, 358, 358, 358, 397, UINT_MAX}, /* [8]: cpu_speedo_id: 5: T33 */
103 {364, 364, 364, 364, 397, UINT_MAX}, /* [9]: cpu_speedo_id: 6/12: T33S/AP37 */
104
105/* T30 'L' family */
106 {295, 336, 358, 375, 391, UINT_MAX}, /* [10]: cpu_speedo_id 7: T30L */
107 {295, 336, 358, 375, 391, UINT_MAX}, /* [11]: cpu_speedo_id 8: T30SL */
108
109/* T30 Automotives */
110 /* threshold_index 12: cpu_speedo_id 9 & 10
111 * 0,1,2 values correspond to speedo_id 9
112 * 3,4,5 values correspond to speedo_id 10 */
113 {300, 311, 360, 371, 381, 415, 431},
114 {300, 311, 410, 431, UINT_MAX}, /* [13]: cpu_speedo_id 11: T30 auto */
115
116/* T37 family */
117 {358, 358, 358, 358, 397, UINT_MAX}, /* [14]: cpu_speedo_id 13: T37 */
118};
119
120/*
121 * Common speedo_value array threshold index for both core_process_speedos and
122 * cpu_process_speedos arrays. Make sure these two arrays are always in synch.
123 */
124static int threshold_index;
125
126static int cpu_process_id;
127static int core_process_id;
128static int cpu_speedo_id;
129static int soc_speedo_id;
130static int package_id;
131
132static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
133{
134 u32 reg;
135 int ate_ver, bit_minus1, bit_minus2;
136
137 BUG_ON(!speedo_g || !speedo_lp);
138 reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0);
139
140 /* Speedo LP = Lower 16-bits Multiplied by 4 */
141 *speedo_lp = (reg & 0xFFFF) * 4;
142
143 /* Speedo G = Upper 16-bits Multiplied by 4 */
144 *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
145
146 if (tegra_fuse_get_revision(&ate_ver))
147 return;
148 pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10);
149
150 pr_debug("CPU speedo base value %u (0x%3x)\n", *speedo_g, *speedo_g);
151 pr_debug("Core speedo base value %u (0x%3x)\n", *speedo_lp, *speedo_lp);
152
153 if (ate_ver >= 26) {
154 /* read lower 2 bits of LP speedo from spare fuses */
155 bit_minus1 = tegra_fuse_readl(LP_SPEEDO_BIT_MINUS1) & 0x1;
156 bit_minus1 |= tegra_fuse_readl(LP_SPEEDO_BIT_MINUS1_R) & 0x1;
157 bit_minus2 = tegra_fuse_readl(LP_SPEEDO_BIT_MINUS2) & 0x1;
158 bit_minus2 |= tegra_fuse_readl(LP_SPEEDO_BIT_MINUS2_R) & 0x1;
159 *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
160
161 /* read lower 2 bits of G speedo from spare fuses */
162 bit_minus1 = tegra_fuse_readl(G_SPEEDO_BIT_MINUS1) & 0x1;
163 bit_minus1 |= tegra_fuse_readl(G_SPEEDO_BIT_MINUS1_R) & 0x1;
164 bit_minus2 = tegra_fuse_readl(G_SPEEDO_BIT_MINUS2) & 0x1;
165 bit_minus2 |= tegra_fuse_readl(G_SPEEDO_BIT_MINUS2_R) & 0x1;
166 *speedo_g |= (bit_minus1 << 1) | bit_minus2;
167 } else {
168 /* set lower 2 bits for speedo ate-ver independent comparison */
169 *speedo_lp |= 0x3;
170 *speedo_g |= 0x3;
171 }
172}
173
174static void rev_sku_to_speedo_ids(int rev, int sku)
175{
176 switch (rev) {
177 case TEGRA_REVISION_A01: /* any A01 */
178 cpu_speedo_id = 0;
179 soc_speedo_id = 0;
180 threshold_index = 0;
181 break;
182
183 case TEGRA_REVISION_A02:
184 case TEGRA_REVISION_A03:
185 switch (sku) {
186 case 0x87: /* AP30 */
187 case 0x82: /* T30V */
188 cpu_speedo_id = 1;
189 soc_speedo_id = 1;
190 threshold_index = 1;
191 break;
192
193 case 0x81: /* T30 */
194 switch (package_id) {
195 case 1: /* MID => T30 */
196 cpu_speedo_id = 2;
197 soc_speedo_id = 2;
198 threshold_index = 2;
199 break;
200 case 2: /* DSC => AP33 */
201 cpu_speedo_id = 4;
202 soc_speedo_id = 1;
203 threshold_index = 7;
204 break;
205 default:
206 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
207 package_id);
208 BUG();
209 break;
210 }
211 break;
212
213 case 0x80: /* T33 or T33S */
214 switch (package_id) {
215 case 1: /* MID => T33 */
216 cpu_speedo_id = 5;
217 soc_speedo_id = 2;
218 threshold_index = 8;
219 break;
220 case 2: /* DSC => T33S */
221 cpu_speedo_id = 6;
222 soc_speedo_id = 2;
223 threshold_index = 9;
224 break;
225 default:
226 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
227 package_id);
228 BUG();
229 break;
230 }
231 break;
232
233 case 0x83: /* T30L or T30S */
234 switch (package_id) {
235 case 1: /* MID => T30L */
236 cpu_speedo_id = 7;
237 soc_speedo_id = 1;
238 threshold_index = 10;
239 break;
240 case 2: /* DSC => T30S */
241 cpu_speedo_id = 3;
242 soc_speedo_id = 2;
243 threshold_index = 3;
244 break;
245 default:
246 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
247 package_id);
248 BUG();
249 break;
250 }
251 break;
252
253 case 0x8F: /* T30SL */
254 cpu_speedo_id = 8;
255 soc_speedo_id = 1;
256 threshold_index = 11;
257 break;
258
259 case 0xA0: /* T37 or A37 */
260 switch (package_id) {
261 case 1: /* MID => T37 */
262 cpu_speedo_id = 13;
263 soc_speedo_id = 2;
264 threshold_index = 14;
265 break;
266 case 2: /* DSC => AP37 */
267 cpu_speedo_id = 12;
268 soc_speedo_id = 2;
269 threshold_index = 9;
270 break;
271 default:
272 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
273 package_id);
274 BUG();
275 break;
276 }
277 break;
278
279/* Characterization SKUs */
280 case 0x08: /* AP30 char */
281 cpu_speedo_id = 1;
282 soc_speedo_id = 1;
283 threshold_index = 4;
284 break;
285 case 0x02: /* T30 char */
286 cpu_speedo_id = 2;
287 soc_speedo_id = 2;
288 threshold_index = 5;
289 break;
290 case 0x04: /* T30S char */
291 cpu_speedo_id = 3;
292 soc_speedo_id = 2;
293 threshold_index = 6;
294 break;
295
296 case 0x91: /* T30AGS-Ax */
297 case 0xb0: /* T30IQS-Ax */
298 case 0xb1: /* T30MQS-Ax */
299 case 0x90: /* T30AQS-Ax */
300 soc_speedo_id = 3;
301 threshold_index = 12;
302 break;
303 case 0x93: /* T30AG-Ax */
304 cpu_speedo_id = 11;
305 soc_speedo_id = 3;
306 threshold_index = 13;
307 break;
308 case 0: /* ENG - check package_id */
309 pr_info("Tegra3 ENG SKU: Checking package_id\n");
310 switch (package_id) {
311 case 1: /* MID => assume T30 */
312 cpu_speedo_id = 2;
313 soc_speedo_id = 2;
314 threshold_index = 2;
315 break;
316 case 2: /* DSC => assume T30S */
317 cpu_speedo_id = 3;
318 soc_speedo_id = 2;
319 threshold_index = 3;
320 break;
321 default:
322 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
323 package_id);
324 BUG();
325 break;
326 }
327 break;
328
329 default:
330 /* FIXME: replace with BUG() when all SKU's valid */
331 pr_err("Tegra3 Rev-A02: Unknown SKU %d\n", sku);
332 cpu_speedo_id = 0;
333 soc_speedo_id = 0;
334 threshold_index = 0;
335 break;
336 }
337 break;
338 default:
339 BUG();
340 break;
341 }
342}
343
344void tegra_init_speedo_data(void)
345{
346 u32 cpu_speedo_val, core_speedo_val;
347 int iv;
348 int fuse_sku = tegra_sku_id();
349 int sku_override = tegra_get_sku_override();
350 int new_sku = fuse_sku;
351
352 /* Package info: 4 bits - 0,3:reserved 1:MID 2:DSC */
353 package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
354
355 /* Arrays must be of equal size - each index corresponds to a SKU */
356 BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
357 ARRAY_SIZE(core_process_speedos));
358
359 /* SKU Overrides
360 * T33 => T30, T30L
361 * T33S => T30S, T30SL
362 * T30 => T30L
363 * T30S => T30SL
364 * AP33 => AP30
365 */
366 switch (sku_override) {
367 case 1:
368 /* Base sku override */
369 if (fuse_sku == 0x80) {
370 if (package_id == 1) {
371 /* T33 to T30 */
372 pr_info("%s: SKU OR: T33->T30\n", __func__);
373 new_sku = 0x81;
374 } else if (package_id == 2) {
375 /* T33S->T30S */
376 pr_info("%s: SKU OR: T33S->T30S\n", __func__);
377 new_sku = 0x83;
378 }
379 } else if (fuse_sku == 0x81) {
380 if (package_id == 2) {
381 /* AP33->AP30 */
382 pr_info("%s: SKU OR: AP33->AP30\n", __func__);
383 new_sku = 0x87;
384 }
385 }
386 break;
387 case 2:
388 /* L sku override */
389 if (fuse_sku == 0x80) {
390 if (package_id == 1) {
391 /* T33->T30L */
392 pr_info("%s: SKU OR: T33->T30L\n", __func__);
393 new_sku = 0x83;
394 } else if (package_id == 2) {
395 /* T33S->T33SL */
396 pr_info("%s: SKU OR: T33S->T30SL\n", __func__);
397 new_sku = 0x8f;
398 }
399 } else if (fuse_sku == 0x81) {
400 if (package_id == 1) {
401 pr_info("%s: SKU OR: T30->T30L\n", __func__);
402 /* T30->T30L */
403 new_sku = 0x83;
404 }
405 } else if (fuse_sku == 0x83) {
406 if (package_id == 2) {
407 pr_info("%s: SKU OR: T30S->T30SL\n", __func__);
408 /* T30S to T30SL */
409 new_sku = 0x8f;
410 }
411 }
412 break;
413 default:
414 /* no override */
415 break;
416 }
417
418 rev_sku_to_speedo_ids(tegra_get_revision(), new_sku);
419 BUG_ON(threshold_index >= ARRAY_SIZE(cpu_process_speedos));
420
421 fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
422 pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val);
423 pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val);
424
425 for (iv = 0; iv < CPU_PROCESS_CORNERS_NUM; iv++) {
426 if (cpu_speedo_val <
427 cpu_process_speedos[threshold_index][iv]) {
428 break;
429 }
430 }
431 cpu_process_id = iv -1;
432
433 if (cpu_process_id == -1) {
434 pr_err("****************************************************");
435 pr_err("****************************************************");
436 pr_err("* tegra3_speedo: CPU speedo value %3d out of range *",
437 cpu_speedo_val);
438 pr_err("****************************************************");
439 pr_err("****************************************************");
440
441 cpu_process_id = INVALID_PROCESS_ID;
442 cpu_speedo_id = 1;
443 }
444
445 for (iv = 0; iv < CORE_PROCESS_CORNERS_NUM; iv++) {
446 if (core_speedo_val <
447 core_process_speedos[threshold_index][iv]) {
448 break;
449 }
450 }
451 core_process_id = iv -1;
452
453 if (core_process_id == -1) {
454 pr_err("****************************************************");
455 pr_err("****************************************************");
456 pr_err("* tegra3_speedo: CORE speedo value %3d out of range *",
457 core_speedo_val);
458 pr_err("****************************************************");
459 pr_err("****************************************************");
460
461 core_process_id = INVALID_PROCESS_ID;
462 soc_speedo_id = 1;
463 }
464 if (threshold_index == 12 && cpu_process_id != INVALID_PROCESS_ID) {
465 if (cpu_process_id <= 2)
466 cpu_speedo_id = 9;
467 else if (cpu_process_id >= 3 && cpu_process_id < 6)
468 cpu_speedo_id = 10;
469 }
470 pr_info("Tegra3: CPU Speedo ID %d, Soc Speedo ID %d",
471 cpu_speedo_id, soc_speedo_id);
472}
473
474int tegra_cpu_process_id(void)
475{
476 /* FIXME: remove when ready to deprecate invalid process-id boards */
477 if (cpu_process_id == INVALID_PROCESS_ID)
478 return 0;
479 else
480 return cpu_process_id;
481}
482
483int tegra_core_process_id(void)
484{
485 /* FIXME: remove when ready to deprecate invalid process-id boards */
486 if (core_process_id == INVALID_PROCESS_ID)
487 return 0;
488 else
489 return core_process_id;
490}
491
492int tegra_cpu_speedo_id(void)
493{
494 return cpu_speedo_id;
495}
496
497int tegra_soc_speedo_id(void)
498{
499 return soc_speedo_id;
500}
501
502int tegra_package_id(void)
503{
504 return package_id;
505}
506
507/*
508 * CPU and core nominal voltage levels as determined by chip SKU and speedo
509 * (not final - can be lowered by dvfs tables and rail dependencies; the
510 * latter is resolved by the dvfs code)
511 */
512static const int cpu_speedo_nominal_millivolts[] =
513/* speedo_id 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 */
514 { 1125, 1150, 1150, 1150, 1237, 1237, 1237, 1150, 1150, 912, 850, 850, 1237, 1237};
515
516int tegra_cpu_speedo_mv(void)
517{
518 BUG_ON(cpu_speedo_id >= ARRAY_SIZE(cpu_speedo_nominal_millivolts));
519 return cpu_speedo_nominal_millivolts[cpu_speedo_id];
520}
521
522int tegra_core_speedo_mv(void)
523{
524 switch (soc_speedo_id) {
525 case 0:
526 return 1200;
527 case 1:
528 if ((cpu_speedo_id != 7) && (cpu_speedo_id != 8))
529 return 1200;
530 /* fall thru for T30L or T30SL */
531 case 2:
532 if (cpu_speedo_id != 13)
533 return 1300;
534 /* T37 */
535 return 1350;
536 case 3:
537 return 1250;
538 default:
539 BUG();
540 }
541}
diff --git a/arch/arm/mach-tegra/tegra3_thermal.c b/arch/arm/mach-tegra/tegra3_thermal.c
new file mode 100644
index 00000000000..8ad7bd5b670
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_thermal.c
@@ -0,0 +1,544 @@
1/*
2 * arch/arm/mach-tegra/tegra3_thermal.c
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
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/cpufreq.h>
19#include <linux/delay.h>
20#include <linux/mutex.h>
21#include <linux/init.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24#include <linux/debugfs.h>
25#include <linux/seq_file.h>
26#include <linux/uaccess.h>
27#include <linux/thermal.h>
28#include <mach/thermal.h>
29#include <mach/edp.h>
30#include <linux/slab.h>
31
32#include "clock.h"
33#include "cpu-tegra.h"
34#include "dvfs.h"
35
36#define MAX_ZONES (16)
37
38struct tegra_thermal {
39 struct tegra_thermal_device *device;
40 long temp_throttle_tj;
41 long temp_shutdown_tj;
42#ifdef CONFIG_TEGRA_THERMAL_SYSFS
43 struct thermal_zone_device *thz;
44 int tc1;
45 int tc2;
46 long passive_delay;
47#else
48 long temp_throttle_low_tj;
49#endif
50#ifdef CONFIG_TEGRA_EDP_LIMITS
51 int edp_thermal_zone_val;
52 long edp_offset;
53 long hysteresis_edp;
54#endif
55 struct mutex mutex;
56};
57
58static struct tegra_thermal thermal_state = {
59 .device = NULL,
60#ifdef CONFIG_TEGRA_EDP_LIMITS
61 .edp_thermal_zone_val = -1,
62#endif
63};
64
65#ifndef CONFIG_TEGRA_THERMAL_SYSFS
66static bool throttle_enb;
67#endif
68
69#ifdef CONFIG_TEGRA_EDP_LIMITS
70static inline long edp2tj(struct tegra_thermal *thermal,
71 long edp_temp)
72{
73 return edp_temp + thermal->edp_offset;
74}
75
76static inline long tj2edp(struct tegra_thermal *thermal,
77 long temp_tj)
78{
79 return temp_tj - thermal->edp_offset;
80}
81#endif
82
83static inline long dev2tj(struct tegra_thermal_device *dev,
84 long dev_temp)
85{
86 return dev_temp + dev->offset;
87}
88
89static inline long tj2dev(struct tegra_thermal_device *dev,
90 long tj_temp)
91{
92 return tj_temp - dev->offset;
93}
94
95#ifdef CONFIG_TEGRA_THERMAL_SYSFS
96
97static int tegra_thermal_zone_bind(struct thermal_zone_device *thermal,
98 struct thermal_cooling_device *cdevice) {
99 /* Support only Thermal Throttling (1 trip) for now */
100 return thermal_zone_bind_cooling_device(thermal, 0, cdevice);
101}
102
103static int tegra_thermal_zone_unbind(struct thermal_zone_device *thermal,
104 struct thermal_cooling_device *cdevice) {
105 /* Support only Thermal Throttling (1 trip) for now */
106 return thermal_zone_unbind_cooling_device(thermal, 0, cdevice);
107}
108
109static int tegra_thermal_zone_get_temp(struct thermal_zone_device *thz,
110 long *temp)
111{
112 struct tegra_thermal *thermal = thz->devdata;
113 thermal->device->get_temp(thermal->device->data, temp);
114
115 return 0;
116}
117
118static int tegra_thermal_zone_get_trip_type(
119 struct thermal_zone_device *thermal,
120 int trip,
121 enum thermal_trip_type *type) {
122
123 /* Support only Thermal Throttling (1 trip) for now */
124 if (trip != 0)
125 return -EINVAL;
126
127 *type = THERMAL_TRIP_PASSIVE;
128
129 return 0;
130}
131
132static int tegra_thermal_zone_get_trip_temp(struct thermal_zone_device *thz,
133 int trip,
134 long *temp) {
135 struct tegra_thermal *thermal = thz->devdata;
136
137 /* Support only Thermal Throttling (1 trip) for now */
138 if (trip != 0)
139 return -EINVAL;
140
141 *temp = tj2dev(thermal->device, thermal->temp_throttle_tj);
142
143 return 0;
144}
145
146static struct thermal_zone_device_ops tegra_thermal_zone_ops = {
147 .bind = tegra_thermal_zone_bind,
148 .unbind = tegra_thermal_zone_unbind,
149 .get_temp = tegra_thermal_zone_get_temp,
150 .get_trip_type = tegra_thermal_zone_get_trip_type,
151 .get_trip_temp = tegra_thermal_zone_get_trip_temp,
152};
153#endif
154
155/* The thermal sysfs handles notifying the throttling
156 * cooling device */
157#ifndef CONFIG_TEGRA_THERMAL_SYSFS
158static void tegra_therm_throttle(bool enable)
159{
160 if (throttle_enb != enable) {
161 mutex_lock(&thermal_state.mutex);
162 tegra_throttling_enable(enable);
163 throttle_enb = enable;
164 mutex_unlock(&thermal_state.mutex);
165 }
166}
167#endif
168
169/* Make sure this function remains stateless */
170void tegra_thermal_alert(void *data)
171{
172 struct tegra_thermal *thermal = data;
173 int err;
174 long temp_dev, temp_tj;
175 long lo_limit_throttle_tj, hi_limit_throttle_tj;
176 long lo_limit_edp_tj = 0, hi_limit_edp_tj = 0;
177 long temp_low_dev, temp_low_tj;
178 int lo_limit_tj = 0, hi_limit_tj = 0;
179#ifdef CONFIG_TEGRA_EDP_LIMITS
180 const struct tegra_edp_limits *z;
181 int zones_sz;
182 int i;
183#endif
184
185 if (thermal != &thermal_state)
186 BUG();
187
188 mutex_lock(&thermal_state.mutex);
189
190#ifdef CONFIG_TEGRA_THERMAL_SYSFS
191 if (thermal->thz) {
192 if (!thermal->thz->passive)
193 thermal_zone_device_update(thermal->thz);
194 }
195#endif
196
197 err = thermal->device->get_temp(thermal->device->data, &temp_dev);
198 if (err) {
199 pr_err("%s: get temp fail(%d)", __func__, err);
200 goto done;
201 }
202
203 /* Convert all temps to tj and then do all work/logic in terms of
204 tj in order to avoid confusion */
205 temp_tj = dev2tj(thermal->device, temp_dev);
206 thermal->device->get_temp_low(thermal->device, &temp_low_dev);
207 temp_low_tj = dev2tj(thermal->device, temp_low_dev);
208
209 lo_limit_throttle_tj = temp_low_tj;
210 hi_limit_throttle_tj = thermal->temp_throttle_tj;
211
212#ifndef CONFIG_TEGRA_THERMAL_SYSFS
213 /* Check to see if we are currently throttling */
214 if ((tegra_is_throttling() &&
215 (temp_tj > thermal->temp_throttle_low_tj))
216 || (temp_tj >= thermal->temp_throttle_tj)) {
217 lo_limit_throttle_tj = thermal->temp_throttle_low_tj;
218 hi_limit_throttle_tj = thermal->temp_shutdown_tj;
219 }
220#else
221 if (temp_tj > thermal->temp_throttle_tj) {
222 lo_limit_throttle_tj = thermal->temp_throttle_tj;
223 hi_limit_throttle_tj = thermal->temp_shutdown_tj;
224 }
225#endif
226
227#ifdef CONFIG_TEGRA_EDP_LIMITS
228 tegra_get_cpu_edp_limits(&z, &zones_sz);
229
230/* edp table based off of tdiode measurements */
231#define EDP_TEMP_TJ(_index) edp2tj(thermal, z[_index].temperature * 1000)
232
233 if (temp_tj < EDP_TEMP_TJ(0)) {
234 lo_limit_edp_tj = temp_low_tj;
235 hi_limit_edp_tj = EDP_TEMP_TJ(0);
236 } else if (temp_tj >= EDP_TEMP_TJ(zones_sz-1)) {
237 lo_limit_edp_tj = EDP_TEMP_TJ(zones_sz-1) -
238 thermal->hysteresis_edp;
239 hi_limit_edp_tj = thermal->temp_shutdown_tj;
240 } else {
241 for (i = 0; (i + 1) < zones_sz; i++) {
242 if ((temp_tj >= EDP_TEMP_TJ(i)) &&
243 (temp_tj < EDP_TEMP_TJ(i+1))) {
244 lo_limit_edp_tj = EDP_TEMP_TJ(i) -
245 thermal->hysteresis_edp;
246 hi_limit_edp_tj = EDP_TEMP_TJ(i+1);
247 break;
248 }
249 }
250 }
251#undef EDP_TEMP_TJ
252#else
253 lo_limit_edp_tj = temp_low_tj;
254 hi_limit_edp_tj = thermal->temp_shutdown_tj;
255#endif
256
257 /* Get smallest window size */
258 lo_limit_tj = max(lo_limit_throttle_tj, lo_limit_edp_tj);
259 hi_limit_tj = min(hi_limit_throttle_tj, hi_limit_edp_tj);
260
261 thermal->device->set_limits(thermal->device->data,
262 tj2dev(thermal->device, lo_limit_tj),
263 tj2dev(thermal->device, hi_limit_tj));
264
265#ifndef CONFIG_TEGRA_THERMAL_SYSFS
266 if (temp_tj >= thermal->temp_throttle_tj) {
267 /* start throttling */
268 if (!tegra_is_throttling())
269 tegra_therm_throttle(true);
270 } else if (temp_tj <= thermal->temp_throttle_low_tj) {
271 /* switch off throttling */
272 if (tegra_is_throttling())
273 tegra_therm_throttle(false);
274 }
275#endif
276
277#ifdef CONFIG_TEGRA_EDP_LIMITS
278 /* inform edp governor */
279 if (thermal->edp_thermal_zone_val != temp_tj)
280 tegra_edp_update_thermal_zone(tj2edp(thermal, temp_tj)/1000);
281
282 thermal->edp_thermal_zone_val = temp_tj;
283#endif
284
285done:
286 mutex_unlock(&thermal_state.mutex);
287}
288
289int tegra_thermal_set_device(struct tegra_thermal_device *device)
290{
291#ifdef CONFIG_TEGRA_THERMAL_SYSFS
292 struct thermal_zone_device *thz;
293#endif
294
295 /* only support one device */
296 if (thermal_state.device)
297 return -EINVAL;
298
299 thermal_state.device = device;
300
301#ifdef CONFIG_TEGRA_THERMAL_SYSFS
302 thz = thermal_zone_device_register(thermal_state.device->name,
303 1, /* trips */
304 &thermal_state,
305 &tegra_thermal_zone_ops,
306 thermal_state.tc1, /* dT/dt */
307 thermal_state.tc2, /* throttle */
308 thermal_state.passive_delay,
309 0); /* polling delay */
310
311 if (IS_ERR(thz)) {
312 thz = NULL;
313 return -ENODEV;
314 }
315
316 thermal_state.thz = thz;
317#endif
318 thermal_state.device->set_alert(thermal_state.device->data,
319 tegra_thermal_alert,
320 &thermal_state);
321
322 thermal_state.device->set_shutdown_temp(thermal_state.device->data,
323 tj2dev(device, thermal_state.temp_shutdown_tj));
324
325 /* initialize limits */
326 tegra_thermal_alert(&thermal_state);
327
328 return 0;
329}
330
331int __init tegra_thermal_init(struct tegra_thermal_data *data)
332{
333#ifdef CONFIG_TEGRA_THERMAL_SYSFS
334 thermal_state.tc1 = data->tc1;
335 thermal_state.tc2 = data->tc2;
336 thermal_state.passive_delay = data->passive_delay;
337#else
338 thermal_state.temp_throttle_low_tj = data->temp_throttle +
339 data->temp_offset -
340 data->hysteresis_throttle;
341#endif
342 mutex_init(&thermal_state.mutex);
343#ifdef CONFIG_TEGRA_EDP_LIMITS
344 thermal_state.edp_offset = data->edp_offset;
345 thermal_state.hysteresis_edp = data->hysteresis_edp;
346#endif
347 thermal_state.temp_throttle_tj = data->temp_throttle +
348 data->temp_offset;
349 thermal_state.temp_shutdown_tj = data->temp_shutdown +
350 data->temp_offset;
351
352 return 0;
353}
354
355int tegra_thermal_exit(void)
356{
357#ifdef CONFIG_TEGRA_THERMAL_SYSFS
358 if (thermal_state.thz)
359 thermal_zone_device_unregister(thermal_state.thz);
360#endif
361
362 return 0;
363}
364
365#ifdef CONFIG_DEBUG_FS
366
367static int tegra_thermal_throttle_temp_tj_set(void *data, u64 val)
368{
369#ifndef CONFIG_TEGRA_THERMAL_SYSFS
370 long throttle_hysteresis = thermal_state.temp_throttle_tj -
371 thermal_state.temp_throttle_low_tj;
372#endif
373
374 mutex_lock(&thermal_state.mutex);
375 thermal_state.temp_throttle_tj = val;
376#ifndef CONFIG_TEGRA_THERMAL_SYSFS
377 thermal_state.temp_throttle_low_tj = thermal_state.temp_throttle_tj -
378 throttle_hysteresis;
379#endif
380 mutex_unlock(&thermal_state.mutex);
381
382 tegra_thermal_alert(&thermal_state);
383
384 return 0;
385}
386
387static int tegra_thermal_throttle_temp_tj_get(void *data, u64 *val)
388{
389 *val = (u64)thermal_state.temp_throttle_tj;
390 return 0;
391}
392
393DEFINE_SIMPLE_ATTRIBUTE(throttle_temp_tj_fops,
394 tegra_thermal_throttle_temp_tj_get,
395 tegra_thermal_throttle_temp_tj_set,
396 "%llu\n");
397
398static int tegra_thermal_shutdown_temp_tj_set(void *data, u64 val)
399{
400 thermal_state.temp_shutdown_tj = val;
401
402 if (thermal_state.device)
403 thermal_state.device->set_shutdown_temp(
404 thermal_state.device->data,
405 tj2dev(thermal_state.device,
406 thermal_state.temp_shutdown_tj));
407
408 tegra_thermal_alert(&thermal_state);
409
410 return 0;
411}
412
413static int tegra_thermal_shutdown_temp_tj_get(void *data, u64 *val)
414{
415 *val = (u64)thermal_state.temp_shutdown_tj;
416 return 0;
417}
418
419DEFINE_SIMPLE_ATTRIBUTE(shutdown_temp_tj_fops,
420 tegra_thermal_shutdown_temp_tj_get,
421 tegra_thermal_shutdown_temp_tj_set,
422 "%llu\n");
423
424
425static int tegra_thermal_temp_tj_get(void *data, u64 *val)
426{
427 long temp_tj, temp_dev;
428
429 if (thermal_state.device) {
430 thermal_state.device->get_temp(thermal_state.device->data,
431 &temp_dev);
432
433 /* Convert all temps to tj and then do all work/logic in
434 terms of tj in order to avoid confusion */
435 temp_tj = dev2tj(thermal_state.device, temp_dev);
436 } else {
437 temp_tj = -1;
438 }
439
440 *val = (u64)temp_tj;
441
442 return 0;
443}
444
445DEFINE_SIMPLE_ATTRIBUTE(temp_tj_fops,
446 tegra_thermal_temp_tj_get,
447 NULL,
448 "%llu\n");
449
450#ifdef CONFIG_TEGRA_THERMAL_SYSFS
451static int tegra_thermal_tc1_set(void *data, u64 val)
452{
453 thermal_state.thz->tc1 = val;
454 return 0;
455}
456
457static int tegra_thermal_tc1_get(void *data, u64 *val)
458{
459 *val = (u64)thermal_state.thz->tc1;
460 return 0;
461}
462
463DEFINE_SIMPLE_ATTRIBUTE(tc1_fops,
464 tegra_thermal_tc1_get,
465 tegra_thermal_tc1_set,
466 "%llu\n");
467
468static int tegra_thermal_tc2_set(void *data, u64 val)
469{
470 thermal_state.thz->tc2 = val;
471 return 0;
472}
473
474static int tegra_thermal_tc2_get(void *data, u64 *val)
475{
476 *val = (u64)thermal_state.thz->tc2;
477 return 0;
478}
479
480DEFINE_SIMPLE_ATTRIBUTE(tc2_fops,
481 tegra_thermal_tc2_get,
482 tegra_thermal_tc2_set,
483 "%llu\n");
484
485static int tegra_thermal_passive_delay_set(void *data, u64 val)
486{
487 thermal_state.thz->passive_delay = val;
488 return 0;
489}
490
491static int tegra_thermal_passive_delay_get(void *data, u64 *val)
492{
493 *val = (u64)thermal_state.thz->passive_delay;
494 return 0;
495}
496
497DEFINE_SIMPLE_ATTRIBUTE(passive_delay_fops,
498 tegra_thermal_passive_delay_get,
499 tegra_thermal_passive_delay_set,
500 "%llu\n");
501#endif
502
503
504static struct dentry *thermal_debugfs_root;
505
506static int __init tegra_thermal_debug_init(void)
507{
508 thermal_debugfs_root = debugfs_create_dir("tegra_thermal", 0);
509
510 if (!debugfs_create_file("throttle_temp_tj", 0644, thermal_debugfs_root,
511 NULL, &throttle_temp_tj_fops))
512 goto err_out;
513
514 if (!debugfs_create_file("shutdown_temp_tj", 0644, thermal_debugfs_root,
515 NULL, &shutdown_temp_tj_fops))
516 goto err_out;
517
518 if (!debugfs_create_file("temp_tj", 0644, thermal_debugfs_root,
519 NULL, &temp_tj_fops))
520 goto err_out;
521
522#ifdef CONFIG_TEGRA_THERMAL_SYSFS
523 if (!debugfs_create_file("tc1", 0644, thermal_debugfs_root,
524 NULL, &tc1_fops))
525 goto err_out;
526
527 if (!debugfs_create_file("tc2", 0644, thermal_debugfs_root,
528 NULL, &tc2_fops))
529 goto err_out;
530
531 if (!debugfs_create_file("passive_delay", 0644, thermal_debugfs_root,
532 NULL, &passive_delay_fops))
533 goto err_out;
534#endif
535
536 return 0;
537
538err_out:
539 debugfs_remove_recursive(thermal_debugfs_root);
540 return -ENOMEM;
541}
542
543late_initcall(tegra_thermal_debug_init);
544#endif
diff --git a/arch/arm/mach-tegra/tegra3_throttle.c b/arch/arm/mach-tegra/tegra3_throttle.c
new file mode 100644
index 00000000000..f927be7800d
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_throttle.c
@@ -0,0 +1,367 @@
1/*
2 * arch/arm/mach-tegra/tegra3_throttle.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/cpufreq.h>
22#include <linux/delay.h>
23#include <linux/init.h>
24#include <linux/err.h>
25#include <linux/clk.h>
26#include <linux/debugfs.h>
27#include <linux/seq_file.h>
28#include <linux/uaccess.h>
29#include <linux/thermal.h>
30
31#include "clock.h"
32#include "cpu-tegra.h"
33#include "dvfs.h"
34
35/* tegra throttling require frequencies in the table to be in ascending order */
36static struct cpufreq_frequency_table *cpu_freq_table;
37static struct mutex *cpu_throttle_lock;
38
39static struct {
40 unsigned int cpu_freq;
41 int core_cap_level;
42 int ms;
43} throttle_table[] = {
44 { 0, 1000, 2000 }, /* placeholder for cpu floor rate */
45 { 640000, 1000, 2000 },
46 { 640000, 1000, 2000 },
47 { 640000, 1000, 2000 },
48 { 640000, 1000, 2000 },
49 { 640000, 1000, 2000 },
50 { 760000, 1000, 2000 },
51 { 760000, 1050, 2000 },
52 {1000000, 1050, 2000 },
53 {1000000, 1100, 2000 },
54};
55
56static int is_throttling;
57static int throttle_index;
58static struct delayed_work throttle_work;
59static struct workqueue_struct *workqueue;
60static DEFINE_MUTEX(tegra_throttle_lock);
61#ifdef CONFIG_TEGRA_THERMAL_SYSFS
62static struct thermal_cooling_device *cdev;
63#endif
64
65static unsigned int clip_to_table(unsigned int cpu_freq)
66{
67 int i;
68
69 for (i = 0; cpu_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
70 if (cpu_freq_table[i].frequency > cpu_freq)
71 break;
72 }
73 i = (i == 0) ? 0 : i-1;
74 return cpu_freq_table[i].frequency;
75}
76
77static void tegra_throttle_work_func(struct work_struct *work)
78{
79 unsigned int cpu_freq;
80 int core_level;
81
82 mutex_lock(cpu_throttle_lock);
83 if (!is_throttling) {
84 mutex_unlock(cpu_throttle_lock);
85 return;
86 }
87
88 cpu_freq = tegra_getspeed(0);
89 throttle_index -= throttle_index ? 1 : 0;
90
91 core_level = throttle_table[throttle_index].core_cap_level;
92 if (throttle_table[throttle_index].cpu_freq < cpu_freq)
93 tegra_cpu_set_speed_cap(NULL);
94
95 if (throttle_index || (throttle_table[0].cpu_freq < cpu_freq))
96 queue_delayed_work(workqueue, &throttle_work,
97 msecs_to_jiffies(throttle_table[throttle_index].ms));
98
99 mutex_unlock(cpu_throttle_lock);
100
101 tegra_dvfs_core_cap_level_set(core_level);
102}
103
104/*
105 * tegra_throttling_enable
106 * This function may sleep
107 */
108void tegra_throttling_enable(bool enable)
109{
110 mutex_lock(&tegra_throttle_lock);
111 mutex_lock(cpu_throttle_lock);
112
113 if (enable && !(is_throttling++)) {
114 int core_level;
115 unsigned int cpu_freq = tegra_getspeed(0);
116 throttle_index = ARRAY_SIZE(throttle_table) - 1;
117
118 core_level = throttle_table[throttle_index].core_cap_level;
119 if (throttle_table[throttle_index].cpu_freq < cpu_freq)
120 tegra_cpu_set_speed_cap(NULL);
121
122 queue_delayed_work(workqueue, &throttle_work,
123 msecs_to_jiffies(throttle_table[throttle_index].ms));
124
125 mutex_unlock(cpu_throttle_lock);
126
127 tegra_dvfs_core_cap_level_set(core_level);
128 tegra_dvfs_core_cap_enable(true);
129
130 mutex_unlock(&tegra_throttle_lock);
131 return;
132 }
133
134 if (!enable && is_throttling) {
135 if (!(--is_throttling)) {
136 /* restore speed requested by governor */
137 tegra_cpu_set_speed_cap(NULL);
138 mutex_unlock(cpu_throttle_lock);
139
140 tegra_dvfs_core_cap_enable(false);
141 cancel_delayed_work_sync(&throttle_work);
142 mutex_unlock(&tegra_throttle_lock);
143 return;
144 }
145 }
146
147 mutex_unlock(cpu_throttle_lock);
148 mutex_unlock(&tegra_throttle_lock);
149}
150EXPORT_SYMBOL_GPL(tegra_throttling_enable);
151
152unsigned int tegra_throttle_governor_speed(unsigned int requested_speed)
153{
154 return is_throttling ?
155 min(requested_speed, throttle_table[throttle_index].cpu_freq) :
156 requested_speed;
157}
158
159bool tegra_is_throttling(void)
160{
161 return is_throttling;
162}
163
164#ifdef CONFIG_TEGRA_THERMAL_SYSFS
165
166static int
167tegra_throttle_get_max_state(struct thermal_cooling_device *cdev,
168 unsigned long *max_state)
169{
170 *max_state = ARRAY_SIZE(throttle_table);
171 return 0;
172}
173
174static int
175tegra_throttle_get_cur_state(struct thermal_cooling_device *cdev,
176 unsigned long *cur_state)
177{
178 mutex_lock(cpu_throttle_lock);
179 *cur_state = is_throttling ?
180 (ARRAY_SIZE(throttle_table) - throttle_index) :
181 0;
182 mutex_unlock(cpu_throttle_lock);
183
184 return 0;
185}
186
187static int
188tegra_throttle_set_cur_state(struct thermal_cooling_device *cdev,
189 unsigned long cur_state)
190{
191 int core_level;
192
193 mutex_lock(cpu_throttle_lock);
194 if (cur_state == 0) {
195 /* restore speed requested by governor */
196 if (is_throttling) {
197 tegra_dvfs_core_cap_enable(false);
198 is_throttling = false;
199 }
200
201 tegra_cpu_set_speed_cap(NULL);
202 } else {
203 if (!is_throttling) {
204 tegra_dvfs_core_cap_enable(true);
205 is_throttling = true;
206 }
207
208 throttle_index = ARRAY_SIZE(throttle_table) - cur_state;
209 core_level = throttle_table[throttle_index].core_cap_level;
210 tegra_dvfs_core_cap_level_set(core_level);
211
212 tegra_cpu_set_speed_cap(NULL);
213 }
214
215 mutex_unlock(cpu_throttle_lock);
216
217 return 0;
218}
219
220struct thermal_cooling_device_ops tegra_throttle_cooling_ops = {
221 .get_max_state = tegra_throttle_get_max_state,
222 .get_cur_state = tegra_throttle_get_cur_state,
223 .set_cur_state = tegra_throttle_set_cur_state,
224};
225#endif
226
227int __init tegra_throttle_init(struct mutex *cpu_lock)
228{
229 int i;
230 struct tegra_cpufreq_table_data *table_data =
231 tegra_cpufreq_table_get();
232 if (IS_ERR_OR_NULL(table_data))
233 return -EINVAL;
234
235 /*
236 * High-priority, others flags default: not bound to a specific
237 * CPU, has rescue worker task (in case of allocation deadlock,
238 * etc.). Single-threaded.
239 */
240 workqueue = alloc_workqueue("cpu-tegra",
241 WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
242 if (!workqueue)
243 return -ENOMEM;
244 INIT_DELAYED_WORK(&throttle_work, tegra_throttle_work_func);
245
246 cpu_throttle_lock = cpu_lock;
247 cpu_freq_table = table_data->freq_table;
248 throttle_table[0].cpu_freq =
249 cpu_freq_table[table_data->throttle_lowest_index].frequency;
250
251 for (i = 0; i < ARRAY_SIZE(throttle_table); i++) {
252 unsigned int cpu_freq = throttle_table[i].cpu_freq;
253 throttle_table[i].cpu_freq = clip_to_table(cpu_freq);
254 }
255
256#ifdef CONFIG_TEGRA_THERMAL_SYSFS
257 cdev = thermal_cooling_device_register("Throttle", NULL,
258 &tegra_throttle_cooling_ops);
259
260 if (IS_ERR(cdev)) {
261 cdev = NULL;
262 return -ENODEV;
263 }
264#endif
265
266 return 0;
267}
268
269void tegra_throttle_exit(void)
270{
271#ifdef CONFIG_TEGRA_THERMAL_SYSFS
272 if (cdev) {
273 thermal_cooling_device_unregister(cdev);
274 cdev = NULL;
275 }
276#endif
277 destroy_workqueue(workqueue);
278}
279
280#ifdef CONFIG_DEBUG_FS
281
282static int throttle_debug_set(void *data, u64 val)
283{
284 tegra_throttling_enable(val);
285 return 0;
286}
287static int throttle_debug_get(void *data, u64 *val)
288{
289 *val = (u64) is_throttling;
290 return 0;
291}
292DEFINE_SIMPLE_ATTRIBUTE(throttle_fops, throttle_debug_get, throttle_debug_set,
293 "%llu\n");
294static int table_show(struct seq_file *s, void *data)
295{
296 int i;
297
298 for (i = 0; i < ARRAY_SIZE(throttle_table); i++)
299 seq_printf(s, "[%d] = %7u %4d %5d\n",
300 i, throttle_table[i].cpu_freq,
301 throttle_table[i].core_cap_level, throttle_table[i].ms);
302 return 0;
303}
304
305static int table_open(struct inode *inode, struct file *file)
306{
307 return single_open(file, table_show, inode->i_private);
308}
309
310static ssize_t table_write(struct file *file,
311 const char __user *userbuf, size_t count, loff_t *ppos)
312{
313 char buf[80];
314 int table_idx;
315 unsigned int cpu_freq;
316 int core_cap_level;
317 int ms;
318
319 if (sizeof(buf) <= count)
320 return -EINVAL;
321
322 if (copy_from_user(buf, userbuf, count))
323 return -EFAULT;
324
325 /* terminate buffer and trim - white spaces may be appended
326 * at the end when invoked from shell command line */
327 buf[count] = '\0';
328 strim(buf);
329
330 if (sscanf(buf, "[%d] = %u %d %d",
331 &table_idx, &cpu_freq, &core_cap_level, &ms) != 4)
332 return -1;
333
334 if ((table_idx < 0) || (table_idx >= ARRAY_SIZE(throttle_table)))
335 return -EINVAL;
336
337 /* round new settings before updating table */
338 throttle_table[table_idx].cpu_freq = clip_to_table(cpu_freq);
339 throttle_table[table_idx].core_cap_level = (core_cap_level / 50) * 50;
340 throttle_table[table_idx].ms = jiffies_to_msecs(msecs_to_jiffies(ms));
341
342 return count;
343}
344
345static const struct file_operations table_fops = {
346 .open = table_open,
347 .read = seq_read,
348 .write = table_write,
349 .llseek = seq_lseek,
350 .release = single_release,
351};
352
353
354int __init tegra_throttle_debug_init(struct dentry *cpu_tegra_debugfs_root)
355{
356 if (!debugfs_create_file("throttle", 0644, cpu_tegra_debugfs_root,
357 NULL, &throttle_fops))
358 return -ENOMEM;
359
360 if (!debugfs_create_file("throttle_table", 0644, cpu_tegra_debugfs_root,
361 NULL, &table_fops))
362 return -ENOMEM;
363
364 return 0;
365}
366#endif /* CONFIG_DEBUG_FS */
367
diff --git a/arch/arm/mach-tegra/tegra3_tsensor.c b/arch/arm/mach-tegra/tegra3_tsensor.c
new file mode 100644
index 00000000000..01d3cd7ec62
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_tsensor.c
@@ -0,0 +1,187 @@
1/*
2 * arch/arm/mach-tegra/tegra3_tsensor.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation.
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/io.h>
20#include <linux/ioport.h>
21#include <linux/slab.h>
22
23#include <mach/tsensor.h>
24#include <mach/tegra_fuse.h>
25#include <mach/iomap.h>
26#include <mach/thermal.h>
27#include <mach/tsensor.h>
28
29#include "devices.h"
30#include "tegra3_tsensor.h"
31
32/* fuse revision constants used for tsensor */
33#define TSENSOR_FUSE_REVISION_DECIMAL 8
34#define TSENSOR_FUSE_REVISION_INTEGER 0
35
36/* scratch register offsets needed for powering off PMU */
37#define SCRATCH54_OFFSET 0x258
38#define SCRATCH55_OFFSET 0x25C
39
40/* scratch 54 register bit field offsets */
41#define PMU_OFF_DATA_OFFSET 8
42
43/* scratch 55 register bit field offsets */
44#define RESET_TEGRA_OFFSET 31
45#define CONTROLLER_TYPE_OFFSET 30
46#define I2C_CONTROLLER_ID_OFFSET 27
47#define PINMUX_OFFSET 24
48#define CHECKSUM_OFFSET 16
49#define PMU_16BIT_SUPPORT_OFFSET 15
50/* scratch 55 register bit field masks */
51#define RESET_TEGRA_MASK 0x1
52#define CONTROLLER_TYPE_MASK 0x1
53#define I2C_CONTROLLER_ID_MASK 0x7
54#define PINMUX_MASK 0x7
55#define CHECKSUM_MASK 0xff
56#define PMU_16BIT_SUPPORT_MASK 0x1
57
58#define TSENSOR_OFFSET (4000 + 5000)
59
60static int tsensor_get_temp(void *vdata, long *milli_temp)
61{
62 struct tegra_tsensor_data *data = vdata;
63 return tsensor_thermal_get_temp(data, milli_temp);
64}
65
66static int tsensor_get_temp_low(void *vdata, long *milli_temp)
67{
68 struct tegra_tsensor_data *data = vdata;
69 return tsensor_thermal_get_temp_low(data, milli_temp);
70}
71
72static int tsensor_set_limits(void *vdata,
73 long lo_limit_milli,
74 long hi_limit_milli)
75{
76 struct tegra_tsensor_data *data = vdata;
77 return tsensor_thermal_set_limits(data,
78 lo_limit_milli,
79 hi_limit_milli);
80}
81
82static int tsensor_set_alert(void *vdata,
83 void (*alert_func)(void *),
84 void *alert_data)
85{
86 struct tegra_tsensor_data *data = vdata;
87 return tsensor_thermal_set_alert(data, alert_func, alert_data);
88}
89
90static int tsensor_set_shutdown_temp(void *vdata, long shutdown_temp_milli)
91{
92 struct tegra_tsensor_data *data = vdata;
93 return tsensor_thermal_set_shutdown_temp(data, shutdown_temp_milli);
94}
95
96static void tegra3_tsensor_probe_callback(struct tegra_tsensor_data *data)
97{
98 struct tegra_thermal_device *thermal_device;
99
100 thermal_device = kzalloc(sizeof(struct tegra_thermal_device),
101 GFP_KERNEL);
102
103 if (!thermal_device) {
104 pr_err("unable to allocate thermal device\n");
105 return;
106 }
107
108 thermal_device->name = "tsensor";
109 thermal_device->data = data;
110 thermal_device->offset = TSENSOR_OFFSET;
111 thermal_device->get_temp = tsensor_get_temp;
112 thermal_device->get_temp_low = tsensor_get_temp_low;
113 thermal_device->set_limits = tsensor_set_limits;
114 thermal_device->set_alert = tsensor_set_alert;
115 thermal_device->set_shutdown_temp = tsensor_set_shutdown_temp;
116
117 if (tegra_thermal_set_device(thermal_device)) /* This should not fail */
118 BUG();
119}
120
121static struct tegra_tsensor_platform_data tsensor_data = {
122 .probe_callback = tegra3_tsensor_probe_callback,
123};
124
125void __init tegra3_tsensor_init(struct tegra_tsensor_pmu_data *data)
126{
127 unsigned int reg;
128 int err;
129 u32 val, checksum;
130 void __iomem *pMem = NULL;
131 /* tsensor driver is instantiated based on fuse revision */
132 err = tegra_fuse_get_revision(&reg);
133 if (err)
134 goto labelEnd;
135 pr_info("\nTegra3 fuse revision %d ", reg);
136 if (reg < TSENSOR_FUSE_REVISION_DECIMAL)
137 goto labelEnd;
138
139 if (!data)
140 goto labelSkipPowerOff;
141
142 if (!request_mem_region(TEGRA_PMC_BASE +
143 SCRATCH54_OFFSET, 8, "tegra-tsensor"))
144 pr_err(" [%s, line=%d]: Error mem busy\n",
145 __func__, __LINE__);
146
147 pMem = ioremap(TEGRA_PMC_BASE + SCRATCH54_OFFSET, 8);
148 if (!pMem) {
149 pr_err(" [%s, line=%d]: can't ioremap "
150 "pmc iomem\n", __FILE__, __LINE__);
151 goto labelEnd;
152 }
153
154 /*
155 * Fill scratch registers to power off the device
156 * in case if temperature crosses threshold TH3
157 */
158 val = (data->poweroff_reg_data << PMU_OFF_DATA_OFFSET) |
159 data->poweroff_reg_addr;
160 writel(val, pMem);
161
162 val = ((data->reset_tegra & RESET_TEGRA_MASK) << RESET_TEGRA_OFFSET) |
163 ((data->controller_type & CONTROLLER_TYPE_MASK) <<
164 CONTROLLER_TYPE_OFFSET) |
165 ((data->i2c_controller_id & I2C_CONTROLLER_ID_MASK) <<
166 I2C_CONTROLLER_ID_OFFSET) |
167 ((data->pinmux & PINMUX_MASK) << PINMUX_OFFSET) |
168 ((data->pmu_16bit_ops & PMU_16BIT_SUPPORT_MASK) <<
169 PMU_16BIT_SUPPORT_OFFSET) | data->pmu_i2c_addr;
170
171 checksum = data->poweroff_reg_addr +
172 data->poweroff_reg_data + (val & 0xFF) +
173 ((val >> 8) & 0xFF) + ((val >> 24) & 0xFF);
174 checksum &= 0xFF;
175 checksum = 0x100 - checksum;
176
177 val |= (checksum << CHECKSUM_OFFSET);
178 writel(val, pMem + 4);
179
180labelSkipPowerOff:
181 /* set platform data for device before register */
182 tegra_tsensor_device.dev.platform_data = &tsensor_data;
183 platform_device_register(&tegra_tsensor_device);
184
185labelEnd:
186 return;
187}
diff --git a/arch/arm/mach-tegra/tegra3_tsensor.h b/arch/arm/mach-tegra/tegra3_tsensor.h
new file mode 100644
index 00000000000..d6bd1182fa6
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_tsensor.h
@@ -0,0 +1,40 @@
1/*
2 * arch/arm/mach-tegra/tegra3_tsensor.h
3 *
4 * Tegra tsensor header file
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __MACH_TEGRA_TEGRA3_TSENSOR_H
20#define __MACH_TEGRA_TEGRA3_TSENSOR_H
21
22struct tegra_tsensor_pmu_data {
23 u8 poweroff_reg_data;
24 u8 poweroff_reg_addr;
25 u8 reset_tegra;
26 u8 controller_type;
27 u8 i2c_controller_id;
28 u8 pinmux;
29 u8 pmu_16bit_ops;
30 u8 pmu_i2c_addr;
31};
32
33#ifdef CONFIG_SENSORS_TEGRA_TSENSOR
34void __init tegra3_tsensor_init(struct tegra_tsensor_pmu_data *data);
35#else
36static inline void tegra3_tsensor_init(struct tegra_tsensor_pmu_data *data)
37{}
38#endif
39
40#endif
diff --git a/arch/arm/mach-tegra/tegra_fiq_debugger.c b/arch/arm/mach-tegra/tegra_fiq_debugger.c
new file mode 100644
index 00000000000..2a19a214acb
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra_fiq_debugger.c
@@ -0,0 +1,206 @@
1/*
2 * arch/arm/mach-tegra/fiq_debugger.c
3 *
4 * Serial Debugger Interface for Tegra
5 *
6 * Copyright (C) 2008 Google, Inc.
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#include <stdarg.h>
19#include <linux/module.h>
20#include <linux/io.h>
21#include <linux/interrupt.h>
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/irq.h>
25#include <linux/serial_reg.h>
26#include <linux/slab.h>
27#include <linux/stacktrace.h>
28#include <asm/fiq_debugger.h>
29#include <mach/tegra_fiq_debugger.h>
30#include <mach/system.h>
31#include <mach/fiq.h>
32
33#include <linux/uaccess.h>
34
35struct tegra_fiq_debugger {
36 struct fiq_debugger_pdata pdata;
37 void __iomem *debug_port_base;
38 bool break_seen;
39};
40
41static inline void tegra_write(struct tegra_fiq_debugger *t,
42 unsigned int val, unsigned int off)
43{
44 __raw_writeb(val, t->debug_port_base + off * 4);
45}
46
47static inline unsigned int tegra_read(struct tegra_fiq_debugger *t,
48 unsigned int off)
49{
50 return __raw_readb(t->debug_port_base + off * 4);
51}
52
53static inline unsigned int tegra_read_lsr(struct tegra_fiq_debugger *t)
54{
55 unsigned int lsr;
56
57 lsr = tegra_read(t, UART_LSR);
58 if (lsr & UART_LSR_BI)
59 t->break_seen = true;
60
61 return lsr;
62}
63
64static int debug_port_init(struct platform_device *pdev)
65{
66 struct tegra_fiq_debugger *t;
67 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
68
69 if (tegra_read(t, UART_LSR) & UART_LSR_DR)
70 (void)tegra_read(t, UART_RX);
71 /* enable rx and lsr interrupt */
72 tegra_write(t, UART_IER_RLSI | UART_IER_RDI, UART_IER);
73 /* interrupt on every character */
74 tegra_write(t, 0, UART_IIR);
75
76 return 0;
77}
78
79static int debug_getc(struct platform_device *pdev)
80{
81 unsigned int lsr;
82 struct tegra_fiq_debugger *t;
83 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
84
85 lsr = tegra_read_lsr(t);
86
87 if (lsr & UART_LSR_BI || t->break_seen) {
88 t->break_seen = false;
89 return FIQ_DEBUGGER_BREAK;
90 }
91
92 if (lsr & UART_LSR_DR)
93 return tegra_read(t, UART_RX);
94
95 return FIQ_DEBUGGER_NO_CHAR;
96}
97
98static void debug_putc(struct platform_device *pdev, unsigned int c)
99{
100 struct tegra_fiq_debugger *t;
101 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
102
103 while (!(tegra_read_lsr(t) & UART_LSR_THRE))
104 cpu_relax();
105
106 tegra_write(t, c, UART_TX);
107}
108
109static void debug_flush(struct platform_device *pdev)
110{
111 struct tegra_fiq_debugger *t;
112 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
113
114 while (!(tegra_read_lsr(t) & UART_LSR_TEMT))
115 cpu_relax();
116}
117
118static void fiq_enable(struct platform_device *pdev, unsigned int irq, bool on)
119{
120 if (on)
121 tegra_fiq_enable(irq);
122 else
123 tegra_fiq_disable(irq);
124}
125
126static int tegra_fiq_debugger_id;
127
128void tegra_serial_debug_init(unsigned int base, int irq,
129 struct clk *clk, int signal_irq, int wakeup_irq)
130{
131 struct tegra_fiq_debugger *t;
132 struct platform_device *pdev;
133 struct resource *res;
134 int res_count;
135
136 t = kzalloc(sizeof(struct tegra_fiq_debugger), GFP_KERNEL);
137 if (!t) {
138 pr_err("Failed to allocate for fiq debugger\n");
139 return;
140 }
141
142 t->pdata.uart_init = debug_port_init;
143 t->pdata.uart_getc = debug_getc;
144 t->pdata.uart_putc = debug_putc;
145 t->pdata.uart_flush = debug_flush;
146 t->pdata.fiq_enable = fiq_enable;
147
148 t->debug_port_base = ioremap(base, PAGE_SIZE);
149 if (!t->debug_port_base) {
150 pr_err("Failed to ioremap for fiq debugger\n");
151 goto out1;
152 }
153
154 res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL);
155 if (!res) {
156 pr_err("Failed to alloc fiq debugger resources\n");
157 goto out2;
158 }
159
160 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
161 if (!pdev) {
162 pr_err("Failed to alloc fiq debugger platform device\n");
163 goto out3;
164 };
165
166 res[0].flags = IORESOURCE_IRQ;
167 res[0].start = irq;
168 res[0].end = irq;
169 res[0].name = "fiq";
170
171 res[1].flags = IORESOURCE_IRQ;
172 res[1].start = signal_irq;
173 res[1].end = signal_irq;
174 res[1].name = "signal";
175 res_count = 2;
176
177 if (wakeup_irq >= 0) {
178 res[2].flags = IORESOURCE_IRQ;
179 res[2].start = wakeup_irq;
180 res[2].end = wakeup_irq;
181 res[2].name = "wakeup";
182 res_count++;
183 }
184
185 pdev->name = "fiq_debugger";
186 pdev->id = tegra_fiq_debugger_id++;
187 pdev->dev.platform_data = &t->pdata;
188 pdev->resource = res;
189 pdev->num_resources = res_count;
190
191 if (platform_device_register(pdev)) {
192 pr_err("Failed to register fiq debugger\n");
193 goto out4;
194 }
195
196 return;
197
198out4:
199 kfree(pdev);
200out3:
201 kfree(res);
202out2:
203 iounmap(t->debug_port_base);
204out1:
205 kfree(t);
206}
diff --git a/arch/arm/mach-tegra/tegra_odm_fuses.c b/arch/arm/mach-tegra/tegra_odm_fuses.c
new file mode 100644
index 00000000000..5dcf24e497b
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra_odm_fuses.c
@@ -0,0 +1,998 @@
1/*
2 * arch/arm/mach-tegra/tegra_odm_fuses.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21/*
22 * Fuses are one time programmable bits on the chip which are used by
23 * the chip manufacturer and device manufacturers to store chip/device
24 * configurations. The fuse bits are encapsulated in a 32 x 64 array.
25 * If a fuse bit is programmed to 1, it cannot be reverted to 0. Either
26 * another fuse bit has to be used for the same purpose or a new chip
27 * needs to be used.
28 *
29 * Each and every fuse word has its own shadow word which resides adjacent to
30 * a particular fuse word. e.g. Fuse words 0-1 form a fuse-shadow pair.
31 * So in theory we have only 32 fuse words to work with.
32 * The shadow fuse word is a mirror of the actual fuse word at all times
33 * and this is maintained while programming a particular fuse.
34 */
35
36#include <linux/kernel.h>
37#include <linux/io.h>
38#include <linux/mutex.h>
39#include <linux/err.h>
40#include <linux/delay.h>
41#include <linux/slab.h>
42#include <linux/sysfs.h>
43#include <linux/kobject.h>
44#include <linux/regulator/consumer.h>
45#include <linux/ctype.h>
46#include <linux/wakelock.h>
47#include <linux/clk.h>
48
49#include <mach/tegra_odm_fuses.h>
50#include <mach/iomap.h>
51
52#include "fuse.h"
53
54#define NFUSES 64
55#define STATE_IDLE (0x4 << 16)
56
57/* since fuse burning is irreversible, use this for testing */
58#define ENABLE_FUSE_BURNING 1
59
60/* fuse registers */
61#define FUSE_CTRL 0x000
62#define FUSE_REG_ADDR 0x004
63#define FUSE_REG_READ 0x008
64#define FUSE_REG_WRITE 0x00C
65#define FUSE_TIME_PGM 0x01C
66#define FUSE_PRIV2INTFC 0x020
67#define FUSE_DIS_PGM 0x02C
68#define FUSE_WRITE_ACCESS 0x030
69#define FUSE_PWR_GOOD_SW 0x034
70
71static struct kobject *fuse_kobj;
72
73static ssize_t fuse_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
74static ssize_t fuse_store(struct kobject *kobj, struct kobj_attribute *attr,
75 const char *buf, size_t count);
76
77static struct kobj_attribute devkey_attr =
78 __ATTR(device_key, 0440, fuse_show, fuse_store);
79
80static struct kobj_attribute jtagdis_attr =
81 __ATTR(jtag_disable, 0440, fuse_show, fuse_store);
82
83static struct kobj_attribute odm_prod_mode_attr =
84 __ATTR(odm_production_mode, 0444, fuse_show, fuse_store);
85
86static struct kobj_attribute sec_boot_dev_cfg_attr =
87 __ATTR(sec_boot_dev_cfg, 0440, fuse_show, fuse_store);
88
89static struct kobj_attribute sec_boot_dev_sel_attr =
90 __ATTR(sec_boot_dev_sel, 0440, fuse_show, fuse_store);
91
92static struct kobj_attribute sbk_attr =
93 __ATTR(secure_boot_key, 0440, fuse_show, fuse_store);
94
95static struct kobj_attribute sw_rsvd_attr =
96 __ATTR(sw_reserved, 0440, fuse_show, fuse_store);
97
98static struct kobj_attribute ignore_dev_sel_straps_attr =
99 __ATTR(ignore_dev_sel_straps, 0440, fuse_show, fuse_store);
100
101static struct kobj_attribute odm_rsvd_attr =
102 __ATTR(odm_reserved, 0440, fuse_show, fuse_store);
103
104static u32 fuse_pgm_data[NFUSES / 2];
105static u32 fuse_pgm_mask[NFUSES / 2];
106static u32 tmp_fuse_pgm_data[NFUSES / 2];
107
108DEFINE_MUTEX(fuse_lock);
109
110static struct fuse_data fuse_info;
111struct regulator *vdd_fuse;
112struct clk *clk_fuse;
113
114#define FUSE_NAME_LEN 30
115
116struct param_info {
117 u32 *addr;
118 int sz;
119 u32 start_off;
120 int start_bit;
121 int nbits;
122 int data_offset;
123 char sysfs_name[FUSE_NAME_LEN];
124};
125
126#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
127
128/* private_key4 */
129#define DEVKEY_START_OFFSET 0x12
130#define DEVKEY_START_BIT 8
131
132/* arm_debug_dis */
133#define JTAG_START_OFFSET 0x0
134#define JTAG_START_BIT 24
135
136/* security_mode */
137#define ODM_PROD_START_OFFSET 0x0
138#define ODM_PROD_START_BIT 23
139
140/* boot_device_info */
141#define SB_DEVCFG_START_OFFSET 0x14
142#define SB_DEVCFG_START_BIT 8
143
144/* reserved_sw[2:0] */
145#define SB_DEVSEL_START_OFFSET 0x14
146#define SB_DEVSEL_START_BIT 24
147
148/* private_key0 -> private_key3 */
149#define SBK_START_OFFSET 0x0A
150#define SBK_START_BIT 8
151
152/* reserved_sw[7:4] */
153#define SW_RESERVED_START_OFFSET 0x14
154#define SW_RESERVED_START_BIT 28
155
156/* reserved_sw[3] */
157#define IGNORE_DEVSEL_START_OFFSET 0x14
158#define IGNORE_DEVSEL_START_BIT 27
159
160/* reserved_odm0 -> reserved_odm7 */
161#define ODM_RESERVED_DEVSEL_START_OFFSET 0x16
162#define ODM_RESERVED_START_BIT 4
163
164#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
165
166/* private_key4 */
167#define DEVKEY_START_OFFSET 0x16
168#define DEVKEY_START_BIT 22
169
170/* arm_debug_dis */
171#define JTAG_START_OFFSET 0x0
172#define JTAG_START_BIT 24
173
174/* security_mode */
175#define ODM_PROD_START_OFFSET 0x0
176#define ODM_PROD_START_BIT 23
177
178/* boot_device_info */
179#define SB_DEVCFG_START_OFFSET 0x18
180#define SB_DEVCFG_START_BIT 22
181
182/* reserved_sw[2:0] */
183#define SB_DEVSEL_START_OFFSET 0x1A
184#define SB_DEVSEL_START_BIT 6
185
186/* private_key0 -> private_key3 */
187#define SBK_START_OFFSET 0x0E
188#define SBK_START_BIT 22
189
190/* reserved_sw[7:4] */
191#define SW_RESERVED_START_OFFSET 0x1A
192#define SW_RESERVED_START_BIT 10
193
194/* reserved_sw[3] */
195#define IGNORE_DEVSEL_START_OFFSET 0x1A
196#define IGNORE_DEVSEL_START_BIT 9
197
198/* reserved_odm0 -> reserved_odm7 */
199#define ODM_RESERVED_DEVSEL_START_OFFSET 0x1A
200#define ODM_RESERVED_START_BIT 14
201
202#else
203
204#define DEVKEY_START_OFFSET 0x2C
205#define DEVKEY_START_BIT 0x07
206
207#define JTAG_START_OFFSET 0x0
208#define JTAG_START_BIT 0x3
209
210#define ODM_PROD_START_OFFSET 0x0
211#define ODM_PROD_START_BIT 0x4
212
213#define SB_DEVCFG_START_OFFSET 0x2E
214#define SB_DEVCFG_START_BIT 0x07
215
216#define SB_DEVSEL_START_OFFSET 0x2E
217#define SB_DEVSEL_START_BIT 0x23
218
219#define SBK_START_OFFSET 0x24
220#define SBK_START_BIT 0x07
221
222#define SW_RESERVED_START_OFFSET 0x2E
223#define SW_RESERVED_START_BIT 0x07
224
225#define IGNORE_DEVSEL_START_OFFSET 0x2E
226#define IGNORE_DEVSEL_START_BIT 0x26
227
228#define ODM_RESERVED_DEVSEL_START_OFFSET 0X30
229#define ODM_RESERVED_START_BIT 0X0
230
231#endif
232
233static struct param_info fuse_info_tbl[] = {
234 [DEVKEY] = {
235 .addr = &fuse_info.devkey,
236 .sz = sizeof(fuse_info.devkey),
237 .start_off = DEVKEY_START_OFFSET,
238 .start_bit = DEVKEY_START_BIT,
239 .nbits = 32,
240 .data_offset = 0,
241 .sysfs_name = "device_key",
242 },
243 [JTAG_DIS] = {
244 .addr = &fuse_info.jtag_dis,
245 .sz = sizeof(fuse_info.jtag_dis),
246 .start_off = JTAG_START_OFFSET,
247 .start_bit = JTAG_START_BIT,
248 .nbits = 1,
249 .data_offset = 1,
250 .sysfs_name = "jtag_disable",
251 },
252 [ODM_PROD_MODE] = {
253 .addr = &fuse_info.odm_prod_mode,
254 .sz = sizeof(fuse_info.odm_prod_mode),
255 .start_off = ODM_PROD_START_OFFSET,
256 .start_bit = ODM_PROD_START_BIT,
257 .nbits = 1,
258 .data_offset = 2,
259 .sysfs_name = "odm_production_mode",
260 },
261 [SEC_BOOT_DEV_CFG] = {
262 .addr = &fuse_info.bootdev_cfg,
263 .sz = sizeof(fuse_info.bootdev_cfg),
264 .start_off = SB_DEVCFG_START_OFFSET,
265 .start_bit = SB_DEVCFG_START_BIT,
266 .nbits = 16,
267 .data_offset = 3,
268 .sysfs_name = "sec_boot_dev_cfg",
269 },
270 [SEC_BOOT_DEV_SEL] = {
271 .addr = &fuse_info.bootdev_sel,
272 .sz = sizeof(fuse_info.bootdev_sel),
273 .start_off = SB_DEVSEL_START_OFFSET,
274 .start_bit = SB_DEVSEL_START_BIT,
275 .nbits = 3,
276 .data_offset = 4,
277 .sysfs_name = "sec_boot_dev_sel",
278 },
279 [SBK] = {
280 .addr = fuse_info.sbk,
281 .sz = sizeof(fuse_info.sbk),
282 .start_off = SBK_START_OFFSET,
283 .start_bit = SBK_START_BIT,
284 .nbits = 128,
285 .data_offset = 5,
286 .sysfs_name = "secure_boot_key",
287 },
288 [SW_RSVD] = {
289 .addr = &fuse_info.sw_rsvd,
290 .sz = sizeof(fuse_info.sw_rsvd),
291 .start_off = SW_RESERVED_START_OFFSET,
292 .start_bit = SW_RESERVED_START_BIT,
293 .nbits = 4,
294 .data_offset = 9,
295 .sysfs_name = "sw_reserved",
296 },
297 [IGNORE_DEV_SEL_STRAPS] = {
298 .addr = &fuse_info.ignore_devsel_straps,
299 .sz = sizeof(fuse_info.ignore_devsel_straps),
300 .start_off = IGNORE_DEVSEL_START_OFFSET,
301 .start_bit = IGNORE_DEVSEL_START_BIT,
302 .nbits = 1,
303 .data_offset = 10,
304 .sysfs_name = "ignore_dev_sel_straps",
305 },
306 [ODM_RSVD] = {
307 .addr = fuse_info.odm_rsvd,
308 .sz = sizeof(fuse_info.odm_rsvd),
309 .start_off = ODM_RESERVED_DEVSEL_START_OFFSET,
310 .start_bit = ODM_RESERVED_START_BIT,
311 .nbits = 256,
312 .data_offset = 11,
313 .sysfs_name = "odm_reserved",
314 },
315 [SBK_DEVKEY_STATUS] = {
316 .sz = SBK_DEVKEY_STATUS_SZ,
317 },
318};
319
320static void wait_for_idle(void)
321{
322 u32 reg;
323
324 do {
325 udelay(1);
326 reg = tegra_fuse_readl(FUSE_CTRL);
327 } while ((reg & (0xF << 16)) != STATE_IDLE);
328}
329
330#define FUSE_READ 0x1
331#define FUSE_WRITE 0x2
332#define FUSE_SENSE 0x3
333#define FUSE_CMD_MASK 0x3
334
335static u32 fuse_cmd_read(u32 addr)
336{
337 u32 reg;
338
339 wait_for_idle();
340 tegra_fuse_writel(addr, FUSE_REG_ADDR);
341 reg = tegra_fuse_readl(FUSE_CTRL);
342 reg &= ~FUSE_CMD_MASK;
343 reg |= FUSE_READ;
344 tegra_fuse_writel(reg, FUSE_CTRL);
345 wait_for_idle();
346
347 reg = tegra_fuse_readl(FUSE_REG_READ);
348 return reg;
349}
350
351static void fuse_cmd_write(u32 value, u32 addr)
352{
353 u32 reg;
354
355 wait_for_idle();
356 tegra_fuse_writel(addr, FUSE_REG_ADDR);
357 tegra_fuse_writel(value, FUSE_REG_WRITE);
358
359 reg = tegra_fuse_readl(FUSE_CTRL);
360 reg &= ~FUSE_CMD_MASK;
361 reg |= FUSE_WRITE;
362 tegra_fuse_writel(reg, FUSE_CTRL);
363 wait_for_idle();
364}
365
366static void fuse_cmd_sense(void)
367{
368 u32 reg;
369
370 wait_for_idle();
371 reg = tegra_fuse_readl(FUSE_CTRL);
372 reg &= ~FUSE_CMD_MASK;
373 reg |= FUSE_SENSE;
374 tegra_fuse_writel(reg, FUSE_CTRL);
375 wait_for_idle();
376}
377
378static void get_fuse(enum fuse_io_param io_param, u32 *out)
379{
380 int start_bit = fuse_info_tbl[io_param].start_bit;
381 int nbits = fuse_info_tbl[io_param].nbits;
382 int offset = fuse_info_tbl[io_param].start_off;
383 u32 *dst = fuse_info_tbl[io_param].addr;
384 int dst_bit = 0;
385 int i;
386 u32 val;
387 int loops;
388
389 if (out)
390 dst = out;
391
392 do {
393 val = fuse_cmd_read(offset);
394 loops = min(nbits, 32 - start_bit);
395 for (i = 0; i < loops; i++) {
396 if (val & (BIT(start_bit + i)))
397 *dst |= BIT(dst_bit);
398 else
399 *dst &= ~BIT(dst_bit);
400 dst_bit++;
401 if (dst_bit == 32) {
402 dst++;
403 dst_bit = 0;
404 }
405 }
406 nbits -= loops;
407 offset += 2;
408 start_bit = 0;
409 } while (nbits > 0);
410}
411
412int tegra_fuse_read(enum fuse_io_param io_param, u32 *data, int size)
413{
414 int nbits;
415 u32 sbk[4], devkey = 0;
416
417 if (IS_ERR_OR_NULL(clk_fuse)) {
418 pr_err("fuse read disabled");
419 return -ENODEV;
420 }
421
422 if (!data)
423 return -EINVAL;
424
425 if (size != fuse_info_tbl[io_param].sz) {
426 pr_err("%s: size mismatch(%d), %d vs %d\n", __func__,
427 (int)io_param, size, fuse_info_tbl[io_param].sz);
428 return -EINVAL;
429 }
430
431 mutex_lock(&fuse_lock);
432
433 clk_enable(clk_fuse);
434 fuse_cmd_sense();
435
436 if (io_param == SBK_DEVKEY_STATUS) {
437 *data = 0;
438
439 get_fuse(SBK, sbk);
440 get_fuse(DEVKEY, &devkey);
441 nbits = sizeof(sbk) * BITS_PER_BYTE;
442 if (find_first_bit((unsigned long *)sbk, nbits) != nbits)
443 *data = 1;
444 else if (devkey)
445 *data = 1;
446 } else {
447 get_fuse(io_param, data);
448 }
449
450 clk_disable(clk_fuse);
451 mutex_unlock(&fuse_lock);
452
453 return 0;
454}
455
456static bool fuse_odm_prod_mode(void)
457{
458 u32 odm_prod_mode = 0;
459
460 clk_enable(clk_fuse);
461 get_fuse(ODM_PROD_MODE, &odm_prod_mode);
462 clk_disable(clk_fuse);
463 return (odm_prod_mode ? true : false);
464}
465
466static void set_fuse(enum fuse_io_param io_param, u32 *data)
467{
468 int i, start_bit = fuse_info_tbl[io_param].start_bit;
469 int nbits = fuse_info_tbl[io_param].nbits, loops;
470 int offset = fuse_info_tbl[io_param].start_off >> 1;
471 int src_bit = 0;
472 u32 val;
473
474 do {
475 val = *data;
476 loops = min(nbits, 32 - start_bit);
477 for (i = 0; i < loops; i++) {
478 fuse_pgm_mask[offset] |= BIT(start_bit + i);
479 if (val & BIT(src_bit))
480 fuse_pgm_data[offset] |= BIT(start_bit + i);
481 else
482 fuse_pgm_data[offset] &= ~BIT(start_bit + i);
483 src_bit++;
484 if (src_bit == 32) {
485 data++;
486 val = *data;
487 src_bit = 0;
488 }
489 }
490 nbits -= loops;
491 offset++;
492 start_bit = 0;
493 } while (nbits > 0);
494}
495
496static void populate_fuse_arrs(struct fuse_data *info, u32 flags)
497{
498 u32 *src = (u32 *)info;
499 int i;
500
501 memset(fuse_pgm_data, 0, sizeof(fuse_pgm_data));
502 memset(fuse_pgm_mask, 0, sizeof(fuse_pgm_mask));
503
504 if ((flags & FLAGS_ODMRSVD)) {
505 set_fuse(ODM_RSVD, info->odm_rsvd);
506 flags &= ~FLAGS_ODMRSVD;
507 }
508
509 /* do not burn any more if secure mode is set */
510 if (fuse_odm_prod_mode())
511 goto out;
512
513 for_each_set_bit(i, (unsigned long *)&flags, MAX_PARAMS)
514 set_fuse(i, src + fuse_info_tbl[i].data_offset);
515
516out:
517 pr_debug("ready to program");
518}
519
520static void fuse_power_enable(void)
521{
522#if ENABLE_FUSE_BURNING
523 tegra_fuse_writel(0x1, FUSE_PWR_GOOD_SW);
524 udelay(1);
525#endif
526}
527
528static void fuse_power_disable(void)
529{
530#if ENABLE_FUSE_BURNING
531 tegra_fuse_writel(0, FUSE_PWR_GOOD_SW);
532 udelay(1);
533#endif
534}
535
536static void fuse_program_array(int pgm_cycles)
537{
538 u32 reg, fuse_val[2];
539 u32 *data = tmp_fuse_pgm_data, addr = 0, *mask = fuse_pgm_mask;
540 int i = 0;
541
542 fuse_cmd_sense();
543
544 /* get the first 2 fuse bytes */
545 fuse_val[0] = fuse_cmd_read(0);
546 fuse_val[1] = fuse_cmd_read(1);
547
548 fuse_power_enable();
549
550 /*
551 * The fuse macro is a high density macro. Fuses are
552 * burned using an addressing mechanism, so no need to prepare
553 * the full list, but more write to control registers are needed.
554 * The only bit that can be written at first is bit 0, a special write
555 * protection bit by assumptions all other bits are at 0
556 *
557 * The programming pulse must have a precise width of
558 * [9000, 11000] ns.
559 */
560 if (pgm_cycles > 0) {
561 reg = pgm_cycles;
562 tegra_fuse_writel(reg, FUSE_TIME_PGM);
563 }
564 fuse_val[0] = (0x1 & ~fuse_val[0]);
565 fuse_val[1] = (0x1 & ~fuse_val[1]);
566 fuse_cmd_write(fuse_val[0], 0);
567 fuse_cmd_write(fuse_val[1], 1);
568
569 fuse_power_disable();
570
571 /*
572 * this will allow programming of other fuses
573 * and the reading of the existing fuse values
574 */
575 fuse_cmd_sense();
576
577 /* Clear out all bits that have already been burned or masked out */
578 memcpy(data, fuse_pgm_data, sizeof(fuse_pgm_data));
579
580 for (addr = 0; addr < NFUSES; addr += 2, data++, mask++) {
581 reg = fuse_cmd_read(addr);
582 pr_debug("%d: 0x%x 0x%x 0x%x\n", addr, (u32)(*data),
583 ~reg, (u32)(*mask));
584 *data = (*data & ~reg) & *mask;
585 }
586
587 fuse_power_enable();
588
589 /*
590 * Finally loop on all fuses, program the non zero ones.
591 * Words 0 and 1 are written last and they contain control fuses. We
592 * need to invalidate after writing to a control word (with the exception
593 * of the master enable). This is also the reason we write them last.
594 */
595 for (i = ARRAY_SIZE(fuse_pgm_data) - 1; i >= 0; i--) {
596 if (tmp_fuse_pgm_data[i]) {
597 fuse_cmd_write(tmp_fuse_pgm_data[i], i * 2);
598 fuse_cmd_write(tmp_fuse_pgm_data[i], (i * 2) + 1);
599 }
600
601 if (i < 2) {
602 wait_for_idle();
603 fuse_power_disable();
604 fuse_cmd_sense();
605 fuse_power_enable();
606 }
607 }
608
609 fuse_power_disable();
610}
611
612static int fuse_set(enum fuse_io_param io_param, u32 *param, int size)
613{
614 int i, nwords = size / sizeof(u32);
615 u32 *data;
616
617 if (io_param > MAX_PARAMS)
618 return -EINVAL;
619
620 data = (u32*)kzalloc(size, GFP_KERNEL);
621 if (!data) {
622 pr_err("failed to alloc %d bytes\n", size);
623 return -ENOMEM;
624 }
625
626 get_fuse(io_param, data);
627
628 /* set only new fuse bits */
629 for (i = 0; i < nwords; i++) {
630 param[i] = (~data[i] & param[i]);
631 }
632
633 kfree(data);
634 return 0;
635}
636
637/*
638 * Function pointer to optional board specific function
639 */
640int (*tegra_fuse_regulator_en)(int);
641EXPORT_SYMBOL(tegra_fuse_regulator_en);
642
643#define CAR_OSC_CTRL 0x50
644#define PMC_PLLP_OVERRIDE 0xF8
645#define PMC_OSC_OVERRIDE BIT(0)
646#define PMC_OSC_FREQ_MASK (BIT(2) | BIT(3))
647#define PMC_OSC_FREQ_SHIFT 2
648#define CAR_OSC_FREQ_SHIFT 30
649
650#define FUSE_SENSE_DONE_BIT BIT(30)
651#define START_DATA BIT(0)
652#define SKIP_RAMREPAIR BIT(1)
653#define FUSE_PGM_TIMEOUT_MS 50
654
655#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
656/* cycles corresponding to 13MHz, 19.2MHz, 12MHz, 26MHz */
657static int fuse_pgm_cycles[] = {130, 192, 120, 260};
658#else
659/* cycles corresponding to 13MHz, 16.8MHz, 19.2MHz, 38.4MHz, 12MHz, 48MHz, 26MHz */
660static int fuse_pgm_cycles[] = {130, 168, 0, 0, 192, 384, 0, 0, 120, 480, 0, 0, 260};
661#endif
662
663int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags)
664{
665 u32 reg;
666 int i = 0;
667 int index;
668 int ret;
669 int delay = FUSE_PGM_TIMEOUT_MS;
670
671 if (!pgm_data || !flags) {
672 pr_err("invalid parameter");
673 return -EINVAL;
674 }
675
676 if (IS_ERR_OR_NULL(clk_fuse) ||
677 (!tegra_fuse_regulator_en && IS_ERR_OR_NULL(vdd_fuse))) {
678 pr_err("fuse write disabled");
679 return -ENODEV;
680 }
681
682 if (fuse_odm_prod_mode() && (flags != FLAGS_ODMRSVD)) {
683 pr_err("reserved odm fuses aren't allowed in secure mode");
684 return -EPERM;
685 }
686
687 if ((flags & FLAGS_ODM_PROD_MODE) &&
688 (flags & (FLAGS_SBK | FLAGS_DEVKEY))) {
689 pr_err("odm production mode and sbk/devkey not allowed");
690 return -EPERM;
691 }
692
693 clk_enable(clk_fuse);
694
695 /* check that fuse options write access hasn't been disabled */
696 mutex_lock(&fuse_lock);
697 reg = tegra_fuse_readl(FUSE_DIS_PGM);
698 mutex_unlock(&fuse_lock);
699 if (reg) {
700 pr_err("fuse programming disabled");
701 clk_disable(clk_fuse);
702 return -EACCES;
703 }
704
705 /* enable software writes to the fuse registers */
706 tegra_fuse_writel(0, FUSE_WRITE_ACCESS);
707
708 mutex_lock(&fuse_lock);
709 memcpy(&fuse_info, pgm_data, sizeof(fuse_info));
710 for_each_set_bit(i, (unsigned long *)&flags, MAX_PARAMS) {
711 fuse_set((u32)i, fuse_info_tbl[i].addr,
712 fuse_info_tbl[i].sz);
713 }
714
715#if ENABLE_FUSE_BURNING
716 if (tegra_fuse_regulator_en)
717 ret = tegra_fuse_regulator_en(1);
718 else
719 ret = regulator_enable(vdd_fuse);
720
721 if (ret)
722 BUG_ON("regulator enable fail\n");
723
724 populate_fuse_arrs(&fuse_info, flags);
725
726 /* calculate the number of program cycles from the oscillator freq */
727 reg = readl(IO_ADDRESS(TEGRA_PMC_BASE) + PMC_PLLP_OVERRIDE);
728 if (reg & PMC_OSC_OVERRIDE) {
729 index = (reg & PMC_OSC_FREQ_MASK) >> PMC_OSC_FREQ_SHIFT;
730 } else {
731 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE) + CAR_OSC_CTRL);
732 index = reg >> CAR_OSC_FREQ_SHIFT;
733 }
734
735 pr_debug("%s: use %d programming cycles\n", __func__, fuse_pgm_cycles[index]);
736 fuse_program_array(fuse_pgm_cycles[index]);
737
738 memset(&fuse_info, 0, sizeof(fuse_info));
739
740 if (tegra_fuse_regulator_en)
741 tegra_fuse_regulator_en(0);
742 else
743 regulator_disable(vdd_fuse);
744#endif
745
746 mutex_unlock(&fuse_lock);
747
748 /* disable software writes to the fuse registers */
749 tegra_fuse_writel(1, FUSE_WRITE_ACCESS);
750
751 /* apply the fuse values immediately instead of resetting the chip */
752 fuse_cmd_sense();
753
754 tegra_fuse_writel(START_DATA | SKIP_RAMREPAIR, FUSE_PRIV2INTFC);
755
756 /* check sense and shift done in addition to IDLE */
757 do {
758 mdelay(1);
759 reg = tegra_fuse_readl(FUSE_CTRL);
760 reg &= (FUSE_SENSE_DONE_BIT | STATE_IDLE);
761 } while ((reg != (FUSE_SENSE_DONE_BIT | STATE_IDLE)) && (--delay > 0));
762
763 clk_disable(clk_fuse);
764
765 return ((delay > 0) ? 0 : -ETIMEDOUT);
766}
767
768static int fuse_name_to_param(const char *str)
769{
770 int i;
771
772 for (i = DEVKEY; i < ARRAY_SIZE(fuse_info_tbl); i++) {
773 if (!strcmp(str, fuse_info_tbl[i].sysfs_name))
774 return i;
775 }
776
777 return -ENODATA;
778}
779
780static int char_to_xdigit(char c)
781{
782 return (c>='0' && c<='9') ? c - '0' :
783 (c>='a' && c<='f') ? c - 'a' + 10 :
784 (c>='A' && c<='F') ? c - 'A' + 10 : -1;
785}
786
787#define CHK_ERR(x) \
788{ \
789 if (x) \
790 { \
791 pr_err("%s: sysfs_create_file fail(%d)!", __func__, x); \
792 return x; \
793 } \
794}
795
796static ssize_t fuse_store(struct kobject *kobj, struct kobj_attribute *attr,
797 const char *buf, size_t count)
798{
799 enum fuse_io_param param = fuse_name_to_param(attr->attr.name);
800 int ret, i = 0;
801 int orig_count = count;
802 struct fuse_data data = {0};
803 u32 *raw_data = ((u32 *)&data) + fuse_info_tbl[param].data_offset;
804 u8 *raw_byte_data = (u8 *)raw_data;
805 struct wake_lock fuse_wk_lock;
806
807 if ((param == -1) || (param == -ENODATA)) {
808 pr_err("%s: invalid fuse\n", __func__);
809 return -EINVAL;
810 }
811
812 if (fuse_odm_prod_mode()) {
813 pr_err("%s: device locked. odm fuse already blown\n", __func__);
814 return -EPERM;
815 }
816
817 count--;
818 if (DIV_ROUND_UP(count, 2) > fuse_info_tbl[param].sz) {
819 pr_err("%s: fuse parameter too long, should be %d character(s)\n",
820 __func__, fuse_info_tbl[param].sz * 2);
821 return -EINVAL;
822 }
823
824 /* see if the string has 0x/x at the start */
825 if (*buf == 'x') {
826 count -= 1;
827 buf++;
828 } else if (*(buf + 1) == 'x') {
829 count -= 2;
830 buf += 2;
831 }
832
833 /* wakelock to avoid device powering down while programming */
834 wake_lock_init(&fuse_wk_lock, WAKE_LOCK_SUSPEND, "fuse_wk_lock");
835 wake_lock(&fuse_wk_lock);
836
837 /* we need to fit each character into a single nibble */
838 raw_byte_data += DIV_ROUND_UP(count, 2) - 1;
839
840 /* in case of odd number of writes, write the first one here */
841 if (count & BIT(0)) {
842 *raw_byte_data = char_to_xdigit(*buf);
843 buf++;
844 raw_byte_data--;
845 count--;
846 }
847
848 for (i = 1; i <= count; i++, buf++) {
849 if (i & BIT(0)) {
850 *raw_byte_data = char_to_xdigit(*buf);
851 } else {
852 *raw_byte_data <<= 4;
853 *raw_byte_data |= char_to_xdigit(*buf);
854 raw_byte_data--;
855 }
856 }
857
858 ret = tegra_fuse_program(&data, BIT(param));
859 if (ret) {
860 pr_err("%s: fuse program fail(%d)\n", __func__, ret);
861 orig_count = ret;
862 goto done;
863 }
864
865 /* if odm prodn mode fuse is burnt, change file permissions to 0440 */
866 if (param == ODM_PROD_MODE) {
867 CHK_ERR(sysfs_chmod_file(kobj, &attr->attr, 0440));
868 CHK_ERR(sysfs_chmod_file(kobj, &devkey_attr.attr, 0440));
869 CHK_ERR(sysfs_chmod_file(kobj, &jtagdis_attr.attr, 0440));
870 CHK_ERR(sysfs_chmod_file(kobj, &sec_boot_dev_cfg_attr.attr, 0440));
871 CHK_ERR(sysfs_chmod_file(kobj, &sec_boot_dev_sel_attr.attr, 0440));
872 CHK_ERR(sysfs_chmod_file(kobj, &sbk_attr.attr, 0440));
873 CHK_ERR(sysfs_chmod_file(kobj, &sw_rsvd_attr.attr, 0440));
874 CHK_ERR(sysfs_chmod_file(kobj, &ignore_dev_sel_straps_attr.attr, 0440));
875 CHK_ERR(sysfs_chmod_file(kobj, &odm_rsvd_attr.attr, 0440));
876 }
877
878done:
879 wake_unlock(&fuse_wk_lock);
880 wake_lock_destroy(&fuse_wk_lock);
881 return orig_count;
882}
883
884static ssize_t fuse_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
885{
886 enum fuse_io_param param = fuse_name_to_param(attr->attr.name);
887 u32 data[8];
888 char str[8];
889 int ret, i;
890
891 if ((param == -1) || (param == -ENODATA)) {
892 pr_err("%s: invalid fuse\n", __func__);
893 return -EINVAL;
894 }
895
896 if ((param == SBK) && fuse_odm_prod_mode()) {
897 pr_err("device locked. sbk read not allowed\n");
898 return 0;
899 }
900
901 memset(data, 0, sizeof(data));
902 ret = tegra_fuse_read(param, data, fuse_info_tbl[param].sz);
903 if (ret) {
904 pr_err("%s: read fail(%d)\n", __func__, ret);
905 return ret;
906 }
907
908 strcpy(buf, "0x");
909 for (i = (fuse_info_tbl[param].sz/sizeof(u32)) - 1; i >= 0 ; i--) {
910 sprintf(str, "%08x", data[i]);
911 strcat(buf, str);
912 }
913
914 strcat(buf, "\n");
915 return strlen(buf);
916}
917
918static int __init tegra_fuse_program_init(void)
919{
920 if (!tegra_fuse_regulator_en) {
921 /* get vdd_fuse regulator */
922 vdd_fuse = regulator_get(NULL, "vdd_fuse");
923 if (IS_ERR_OR_NULL(vdd_fuse))
924 pr_err("%s: no vdd_fuse. fuse write disabled\n", __func__);
925 }
926
927 clk_fuse = clk_get_sys("fuse-tegra", "fuse_burn");
928 if (IS_ERR_OR_NULL(clk_fuse)) {
929 pr_err("%s: no clk_fuse. fuse read/write disabled\n", __func__);
930 if (!IS_ERR_OR_NULL(vdd_fuse)) {
931 regulator_put(vdd_fuse);
932 vdd_fuse = NULL;
933 }
934 return -ENODEV;
935 }
936
937 fuse_kobj = kobject_create_and_add("fuse", firmware_kobj);
938 if (!fuse_kobj) {
939 pr_err("%s: fuse_kobj create fail\n", __func__);
940 regulator_put(vdd_fuse);
941 clk_put(clk_fuse);
942 return -ENODEV;
943 }
944
945 mutex_init(&fuse_lock);
946
947 /* change fuse file permissions, if ODM production fuse is not blown */
948 if (!fuse_odm_prod_mode())
949 {
950 devkey_attr.attr.mode = 0640;
951 jtagdis_attr.attr.mode = 0640;
952 sec_boot_dev_cfg_attr.attr.mode = 0640;
953 sec_boot_dev_sel_attr.attr.mode = 0640;
954 sbk_attr.attr.mode = 0640;
955 sw_rsvd_attr.attr.mode = 0640;
956 ignore_dev_sel_straps_attr.attr.mode = 0640;
957 odm_rsvd_attr.attr.mode = 0640;
958 odm_prod_mode_attr.attr.mode = 0644;
959 }
960
961 CHK_ERR(sysfs_create_file(fuse_kobj, &odm_prod_mode_attr.attr));
962 CHK_ERR(sysfs_create_file(fuse_kobj, &devkey_attr.attr));
963 CHK_ERR(sysfs_create_file(fuse_kobj, &jtagdis_attr.attr));
964 CHK_ERR(sysfs_create_file(fuse_kobj, &sec_boot_dev_cfg_attr.attr));
965 CHK_ERR(sysfs_create_file(fuse_kobj, &sec_boot_dev_sel_attr.attr));
966 CHK_ERR(sysfs_create_file(fuse_kobj, &sbk_attr.attr));
967 CHK_ERR(sysfs_create_file(fuse_kobj, &sw_rsvd_attr.attr));
968 CHK_ERR(sysfs_create_file(fuse_kobj, &ignore_dev_sel_straps_attr.attr));
969 CHK_ERR(sysfs_create_file(fuse_kobj, &odm_rsvd_attr.attr));
970
971 return 0;
972}
973
974static void __exit tegra_fuse_program_exit(void)
975{
976
977 fuse_power_disable();
978
979 if (!IS_ERR_OR_NULL(vdd_fuse))
980 regulator_put(vdd_fuse);
981
982 if (!IS_ERR_OR_NULL(clk_fuse))
983 clk_put(clk_fuse);
984
985 sysfs_remove_file(fuse_kobj, &odm_prod_mode_attr.attr);
986 sysfs_remove_file(fuse_kobj, &devkey_attr.attr);
987 sysfs_remove_file(fuse_kobj, &jtagdis_attr.attr);
988 sysfs_remove_file(fuse_kobj, &sec_boot_dev_cfg_attr.attr);
989 sysfs_remove_file(fuse_kobj, &sec_boot_dev_sel_attr.attr);
990 sysfs_remove_file(fuse_kobj, &sbk_attr.attr);
991 sysfs_remove_file(fuse_kobj, &sw_rsvd_attr.attr);
992 sysfs_remove_file(fuse_kobj, &ignore_dev_sel_straps_attr.attr);
993 sysfs_remove_file(fuse_kobj, &odm_rsvd_attr.attr);
994 kobject_del(fuse_kobj);
995}
996
997late_initcall(tegra_fuse_program_init);
998module_exit(tegra_fuse_program_exit);
diff --git a/arch/arm/mach-tegra/tegra_usb_modem_power.c b/arch/arm/mach-tegra/tegra_usb_modem_power.c
new file mode 100644
index 00000000000..db062ffac34
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra_usb_modem_power.c
@@ -0,0 +1,297 @@
1/*
2 * arch/arm/mach-tegra/tegra_usb_modem_power.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
25#include <linux/workqueue.h>
26#include <linux/gpio.h>
27#include <linux/usb.h>
28#include <linux/err.h>
29#include <linux/wakelock.h>
30#include <mach/tegra_usb_modem_power.h>
31
32struct tegra_usb_modem {
33 unsigned int wake_gpio; /* remote wakeup gpio */
34 unsigned int wake_cnt; /* remote wakeup counter */
35 int irq; /* remote wakeup irq */
36 struct mutex lock;
37 struct wake_lock wake_lock; /* modem wake lock */
38 unsigned int vid; /* modem vendor id */
39 unsigned int pid; /* modem product id */
40 struct usb_device *udev; /* modem usb device */
41 struct usb_interface *intf; /* first modem usb interface */
42 struct workqueue_struct *wq; /* modem workqueue */
43 struct delayed_work recovery_work; /* modem recovery work */
44 const struct tegra_modem_operations *ops; /* modem operations */
45 unsigned int capability; /* modem capability */
46};
47
48static struct tegra_usb_modem tegra_mdm;
49
50/* supported modems */
51static const struct usb_device_id modem_list[] = {
52 {USB_DEVICE(0x1983, 0x0310), /* Icera 450 rev1 */
53 .driver_info = TEGRA_MODEM_AUTOSUSPEND,
54 },
55 {USB_DEVICE(0x1983, 0x0321), /* Icera 450 rev2 */
56 .driver_info = TEGRA_MODEM_AUTOSUSPEND,
57 },
58 {}
59};
60
61static irqreturn_t tegra_usb_modem_wake_thread(int irq, void *data)
62{
63 struct tegra_usb_modem *modem = (struct tegra_usb_modem *)data;
64
65 wake_lock_timeout(&modem->wake_lock, HZ);
66 mutex_lock(&modem->lock);
67 if (modem->udev) {
68 usb_lock_device(modem->udev);
69 pr_info("modem wake (%u)\n", ++(modem->wake_cnt));
70 if (usb_autopm_get_interface(modem->intf) == 0)
71 usb_autopm_put_interface_async(modem->intf);
72 usb_unlock_device(modem->udev);
73 }
74 mutex_unlock(&modem->lock);
75
76 return IRQ_HANDLED;
77}
78
79static void tegra_usb_modem_recovery(struct work_struct *ws)
80{
81 struct tegra_usb_modem *modem = container_of(ws, struct tegra_usb_modem,
82 recovery_work.work);
83
84 mutex_lock(&modem->lock);
85 if (!modem->udev) { /* assume modem crashed */
86 if (modem->ops && modem->ops->reset)
87 modem->ops->reset();
88 }
89 mutex_unlock(&modem->lock);
90}
91
92static void device_add_handler(struct usb_device *udev)
93{
94 const struct usb_device_descriptor *desc = &udev->descriptor;
95 struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
96 const struct usb_device_id *id = usb_match_id(intf, modem_list);
97
98 if (id) {
99 /* hold wakelock to ensure ril has enough time to restart */
100 wake_lock_timeout(&tegra_mdm.wake_lock, HZ*10);
101
102 pr_info("Add device %d <%s %s>\n", udev->devnum,
103 udev->manufacturer, udev->product);
104
105 mutex_lock(&tegra_mdm.lock);
106 tegra_mdm.udev = udev;
107 tegra_mdm.intf = intf;
108 tegra_mdm.vid = desc->idVendor;
109 tegra_mdm.pid = desc->idProduct;
110 tegra_mdm.wake_cnt = 0;
111 tegra_mdm.capability = id->driver_info;
112 mutex_unlock(&tegra_mdm.lock);
113
114 pr_info("persist_enabled: %u\n", udev->persist_enabled);
115
116 if (tegra_mdm.capability & TEGRA_MODEM_AUTOSUSPEND) {
117 usb_enable_autosuspend(udev);
118 pr_info("enable autosuspend for %s %s\n",
119 udev->manufacturer, udev->product);
120 }
121 }
122}
123
124static void device_remove_handler(struct usb_device *udev)
125{
126 const struct usb_device_descriptor *desc = &udev->descriptor;
127
128 if (desc->idVendor == tegra_mdm.vid &&
129 desc->idProduct == tegra_mdm.pid) {
130 pr_info("Remove device %d <%s %s>\n", udev->devnum,
131 udev->manufacturer, udev->product);
132
133 mutex_lock(&tegra_mdm.lock);
134 tegra_mdm.udev = NULL;
135 tegra_mdm.intf = NULL;
136 tegra_mdm.vid = 0;
137 mutex_unlock(&tegra_mdm.lock);
138
139 if (tegra_mdm.capability & TEGRA_MODEM_RECOVERY)
140 queue_delayed_work(tegra_mdm.wq,
141 &tegra_mdm.recovery_work, HZ * 10);
142 }
143}
144
145static int usb_notify(struct notifier_block *self, unsigned long action,
146 void *blob)
147{
148 switch (action) {
149 case USB_DEVICE_ADD:
150 device_add_handler(blob);
151 break;
152 case USB_DEVICE_REMOVE:
153 device_remove_handler(blob);
154 break;
155 }
156
157 return NOTIFY_OK;
158}
159
160static struct notifier_block usb_nb = {
161 .notifier_call = usb_notify,
162};
163
164static int tegra_usb_modem_probe(struct platform_device *pdev)
165{
166 struct tegra_usb_modem_power_platform_data *pdata =
167 pdev->dev.platform_data;
168 int ret;
169
170 if (!pdata) {
171 dev_dbg(&pdev->dev, "platform_data not available\n");
172 return -EINVAL;
173 }
174
175 /* get modem operations from platform data */
176 tegra_mdm.ops = (const struct tegra_modem_operations *)pdata->ops;
177
178 if (tegra_mdm.ops) {
179 /* modem init */
180 if (tegra_mdm.ops->init) {
181 ret = tegra_mdm.ops->init();
182 if (ret)
183 return ret;
184 }
185
186 /* start modem */
187 if (tegra_mdm.ops->start)
188 tegra_mdm.ops->start();
189 }
190
191 mutex_init(&(tegra_mdm.lock));
192 wake_lock_init(&(tegra_mdm.wake_lock), WAKE_LOCK_SUSPEND,
193 "tegra_usb_mdm_lock");
194
195 /* create work queue */
196 tegra_mdm.wq = create_workqueue("tegra_usb_mdm_queue");
197 INIT_DELAYED_WORK(&(tegra_mdm.recovery_work), tegra_usb_modem_recovery);
198
199 /* create threaded irq for remote wakeup */
200 if (gpio_is_valid(pdata->wake_gpio)) {
201 /* get remote wakeup gpio from platform data */
202 tegra_mdm.wake_gpio = pdata->wake_gpio;
203
204 ret = gpio_request(tegra_mdm.wake_gpio, "usb_mdm_wake");
205 if (ret)
206 return ret;
207
208 tegra_gpio_enable(tegra_mdm.wake_gpio);
209
210 /* enable IRQ for remote wakeup */
211 tegra_mdm.irq = gpio_to_irq(tegra_mdm.wake_gpio);
212
213 ret =
214 request_threaded_irq(tegra_mdm.irq, NULL,
215 tegra_usb_modem_wake_thread,
216 pdata->flags, "tegra_usb_mdm_wake",
217 &tegra_mdm);
218 if (ret < 0) {
219 dev_err(&pdev->dev, "%s: request_threaded_irq error\n",
220 __func__);
221 return ret;
222 }
223
224 ret = enable_irq_wake(tegra_mdm.irq);
225 if (ret) {
226 dev_err(&pdev->dev, "%s: enable_irq_wake error\n",
227 __func__);
228 free_irq(tegra_mdm.irq, &tegra_mdm);
229 return ret;
230 }
231 }
232
233 usb_register_notify(&usb_nb);
234 dev_info(&pdev->dev, "Initialized tegra_usb_modem_power\n");
235
236 return 0;
237}
238
239static int __exit tegra_usb_modem_remove(struct platform_device *pdev)
240{
241 usb_unregister_notify(&usb_nb);
242
243 if (tegra_mdm.irq) {
244 disable_irq_wake(tegra_mdm.irq);
245 free_irq(tegra_mdm.irq, &tegra_mdm);
246 }
247 return 0;
248}
249
250#ifdef CONFIG_PM
251static int tegra_usb_modem_suspend(struct platform_device *pdev,
252 pm_message_t state)
253{
254 /* send L3 hint to modem */
255 if (tegra_mdm.ops && tegra_mdm.ops->suspend)
256 tegra_mdm.ops->suspend();
257 return 0;
258}
259
260static int tegra_usb_modem_resume(struct platform_device *pdev)
261{
262 /* send L3->L0 hint to modem */
263 if (tegra_mdm.ops && tegra_mdm.ops->resume)
264 tegra_mdm.ops->resume();
265 return 0;
266}
267#endif
268
269static struct platform_driver tegra_usb_modem_power_driver = {
270 .driver = {
271 .name = "tegra_usb_modem_power",
272 .owner = THIS_MODULE,
273 },
274 .probe = tegra_usb_modem_probe,
275 .remove = __exit_p(tegra_usb_modem_remove),
276#ifdef CONFIG_PM
277 .suspend = tegra_usb_modem_suspend,
278 .resume = tegra_usb_modem_resume,
279#endif
280};
281
282static int __init tegra_usb_modem_power_init(void)
283{
284 return platform_driver_register(&tegra_usb_modem_power_driver);
285}
286
287subsys_initcall(tegra_usb_modem_power_init);
288
289static void __exit tegra_usb_modem_power_exit(void)
290{
291 platform_driver_unregister(&tegra_usb_modem_power_driver);
292}
293
294module_exit(tegra_usb_modem_power_exit);
295
296MODULE_DESCRIPTION("Tegra usb modem power management driver");
297MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-tegra/timer-t2.c b/arch/arm/mach-tegra/timer-t2.c
new file mode 100644
index 00000000000..2d515abef16
--- /dev/null
+++ b/arch/arm/mach-tegra/timer-t2.c
@@ -0,0 +1,128 @@
1/*
2 * arch/arch/mach-tegra/timer.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
6 *
7 * Author:
8 * Colin Cross <ccross@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/init.h>
22#include <linux/err.h>
23#include <linux/sched.h>
24#include <linux/time.h>
25#include <linux/interrupt.h>
26#include <linux/irq.h>
27#include <linux/clockchips.h>
28#include <linux/clocksource.h>
29#include <linux/clk.h>
30#include <linux/io.h>
31#include <linux/syscore_ops.h>
32
33#include <asm/mach/time.h>
34#include <asm/localtimer.h>
35#include <asm/sched_clock.h>
36
37#include <mach/iomap.h>
38#include <mach/irqs.h>
39
40#include "board.h"
41#include "clock.h"
42#include "timer.h"
43
44/*
45 * Timers usage:
46 * TMR1 - Free.
47 * TMR2 - used by AVP.
48 * TMR3 - used as general CPU timer.
49 * TMR4 - used for LP2 wakeup.
50*/
51
52#define TIMER1_OFFSET (TEGRA_TMR1_BASE-TEGRA_TMR1_BASE)
53#define TIMER2_OFFSET (TEGRA_TMR2_BASE-TEGRA_TMR1_BASE)
54#define TIMER3_OFFSET (TEGRA_TMR3_BASE-TEGRA_TMR1_BASE)
55#define TIMER4_OFFSET (TEGRA_TMR4_BASE-TEGRA_TMR1_BASE)
56
57#define timer_writel(value, reg) \
58 __raw_writel(value, (u32)timer_reg_base + (reg))
59#define timer_readl(reg) \
60 __raw_readl((u32)timer_reg_base + (reg))
61
62
63static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
64
65#ifdef CONFIG_PM_SLEEP
66static irqreturn_t tegra_lp2wake_interrupt(int irq, void *dev_id)
67{
68 timer_writel(1<<30, TIMER4_OFFSET + TIMER_PCR);
69 return IRQ_HANDLED;
70}
71
72static struct irqaction tegra_lp2wake_irq = {
73 .name = "timer_lp2wake",
74 .flags = IRQF_DISABLED,
75 .handler = tegra_lp2wake_interrupt,
76 .dev_id = NULL,
77 .irq = INT_TMR4,
78};
79
80void tegra2_lp2_set_trigger(unsigned long cycles)
81{
82 timer_writel(0, TIMER4_OFFSET + TIMER_PTV);
83 if (cycles) {
84 u32 reg = 0x80000000ul | min(0x1ffffffful, cycles);
85 timer_writel(reg, TIMER4_OFFSET + TIMER_PTV);
86 }
87}
88EXPORT_SYMBOL(tegra2_lp2_set_trigger);
89
90unsigned long tegra2_lp2_timer_remain(void)
91{
92 return timer_readl(TIMER4_OFFSET + TIMER_PCR) & 0x1ffffffful;
93}
94#endif
95
96void __init tegra2_init_timer(u32 *offset, int *irq)
97{
98 unsigned long rate = tegra_clk_measure_input_freq();
99 int ret;
100
101 switch (rate) {
102 case 12000000:
103 timer_writel(0x000b, TIMERUS_USEC_CFG);
104 break;
105 case 13000000:
106 timer_writel(0x000c, TIMERUS_USEC_CFG);
107 break;
108 case 19200000:
109 timer_writel(0x045f, TIMERUS_USEC_CFG);
110 break;
111 case 26000000:
112 timer_writel(0x0019, TIMERUS_USEC_CFG);
113 break;
114 default:
115 WARN(1, "Unknown clock rate");
116 }
117
118#ifdef CONFIG_PM_SLEEP
119 ret = setup_irq(tegra_lp2wake_irq.irq, &tegra_lp2wake_irq);
120 if (ret) {
121 pr_err("Failed to register LP2 timer IRQ: %d\n", ret);
122 BUG();
123 }
124#endif
125
126 *offset = TIMER3_OFFSET;
127 *irq = INT_TMR3;
128}
diff --git a/arch/arm/mach-tegra/timer-t3.c b/arch/arm/mach-tegra/timer-t3.c
new file mode 100644
index 00000000000..df964fbce15
--- /dev/null
+++ b/arch/arm/mach-tegra/timer-t3.c
@@ -0,0 +1,338 @@
1/*
2 * arch/arch/mach-tegra/timer-t3.c
3 *
4 * Copyright (c) 2011-2012, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/err.h>
23#include <linux/sched.h>
24#include <linux/time.h>
25#include <linux/interrupt.h>
26#include <linux/irq.h>
27#include <linux/clockchips.h>
28#include <linux/clocksource.h>
29#include <linux/clk.h>
30#include <linux/io.h>
31#include <linux/smp.h>
32#include <linux/syscore_ops.h>
33#include <linux/cpu.h>
34
35#include <asm/mach/time.h>
36#include <asm/localtimer.h>
37#include <asm/sched_clock.h>
38
39#include <mach/hardware.h>
40#include <mach/iomap.h>
41#include <mach/irqs.h>
42
43#include "board.h"
44#include "clock.h"
45#include "cpuidle.h"
46#include "timer.h"
47
48#define TEST_LP2_WAKE_TIMERS 0
49
50/*
51 * Timers usage:
52 * TMR1 - used as general CPU timer.
53 * TMR2 - used by AVP.
54 * TMR3 - used by CPU0 for LP2 wakeup.
55 * TMR4 - used by CPU1 for LP2 wakeup.
56 * TMR5 - used by CPU2 for LP2 wakeup.
57 * TMR6 - used by CPU3 for LP2 wakeup.
58 * TMR7 - Free.
59 * TMR8 - Free.
60 * TMR9 - Free.
61 * TMR10 - used as source for watchdog controller 0.
62*/
63
64#define TIMER1_OFFSET (TEGRA_TMR1_BASE-TEGRA_TMR1_BASE)
65#define TIMER2_OFFSET (TEGRA_TMR2_BASE-TEGRA_TMR1_BASE)
66#define TIMER3_OFFSET (TEGRA_TMR3_BASE-TEGRA_TMR1_BASE)
67#define TIMER4_OFFSET (TEGRA_TMR4_BASE-TEGRA_TMR1_BASE)
68#define TIMER5_OFFSET (TEGRA_TMR5_BASE-TEGRA_TMR1_BASE)
69#define TIMER6_OFFSET (TEGRA_TMR6_BASE-TEGRA_TMR1_BASE)
70
71static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
72static cpumask_t wake_timer_ready;
73static cpumask_t wake_timer_canceled;
74
75#define timer_writel(value, reg) \
76 __raw_writel(value, (u32)timer_reg_base + (reg))
77#define timer_readl(reg) \
78 __raw_readl((u32)timer_reg_base + (reg))
79
80
81#ifdef CONFIG_PM_SLEEP
82static u32 lp2_wake_timers[] = {
83 TIMER3_OFFSET,
84#ifdef CONFIG_SMP
85 TIMER4_OFFSET,
86 TIMER5_OFFSET,
87 TIMER6_OFFSET,
88#endif
89};
90
91static irqreturn_t tegra_lp2wake_interrupt(int irq, void *dev_id)
92{
93 int cpu = (int)dev_id;
94 int base;
95
96 base = lp2_wake_timers[cpu];
97 timer_writel(1<<30, base + TIMER_PCR);
98 return IRQ_HANDLED;
99}
100
101#define LP2_TIMER_IRQ_ACTION(cpu, irqnum) { \
102 .name = "tmr_lp2wake_cpu" __stringify(cpu), \
103 .flags = IRQF_DISABLED, \
104 .handler = tegra_lp2wake_interrupt, \
105 .dev_id = (void*)cpu, \
106 .irq = irqnum }
107
108static struct irqaction tegra_lp2wake_irq[] = {
109 LP2_TIMER_IRQ_ACTION(0, INT_TMR3),
110#ifdef CONFIG_SMP
111 LP2_TIMER_IRQ_ACTION(1, INT_TMR4),
112 LP2_TIMER_IRQ_ACTION(2, INT_TMR5),
113 LP2_TIMER_IRQ_ACTION(3, INT_TMR6),
114#endif
115};
116
117#ifdef CONFIG_SMP
118#define hard_smp_processor_id() \
119 ({ \
120 unsigned int cpunum; \
121 __asm__("\n" \
122 "1: mrc p15, 0, %0, c0, c0, 5\n" \
123 " .pushsection \".alt.smp.init\", \"a\"\n"\
124 " .long 1b\n" \
125 " mov %0, #0\n" \
126 " .popsection" \
127 : "=r" (cpunum)); \
128 cpunum &= 0x0F; \
129 })
130#define cpu_number() hard_smp_processor_id()
131#else
132#define cpu_number() 0
133#endif
134
135/*
136 * To sanity test LP2 timer interrupts for CPU 0-3, enable this flag and check
137 * /proc/interrupts for timer interrupts. CPUs 0-3 should have one interrupt
138 * counted against them for tmr_lp2wake_cpu<n>, where <n> is the CPU number.
139 */
140#if TEST_LP2_WAKE_TIMERS
141static void test_lp2_wake_timer(unsigned int cpu)
142{
143 unsigned long cycles = 50000;
144 unsigned int base = lp2_wake_timers[cpu];
145 static bool tested[4] = {false, false, false, false};
146
147 /* Don't repeat the test process on hotplug restart. */
148 if (!tested[cpu]) {
149 timer_writel(0, base + TIMER_PTV);
150 if (cycles) {
151 u32 reg = 0x80000000ul | min(0x1ffffffful, cycles);
152 timer_writel(reg, base + TIMER_PTV);
153 tested[cpu] = true;
154 }
155 }
156}
157#else
158static inline void test_lp2_wake_timer(unsigned int cpu) {}
159#endif
160
161static int tegra3_resume_wake_timer(unsigned int cpu)
162{
163#ifdef CONFIG_SMP
164 int ret = irq_set_affinity(tegra_lp2wake_irq[cpu].irq, cpumask_of(cpu));
165 if (ret) {
166 pr_err("Failed to set affinity for LP2 timer IRQ to "
167 "CPU %d: irq=%d, ret=%d\n", cpu,
168 tegra_lp2wake_irq[cpu].irq, ret);
169 return ret;
170 }
171#endif
172 cpumask_set_cpu(cpu, &wake_timer_ready);
173 return 0;
174}
175
176static void tegra3_register_wake_timer(unsigned int cpu)
177{
178 int ret;
179
180 ret = setup_irq(tegra_lp2wake_irq[cpu].irq, &tegra_lp2wake_irq[cpu]);
181 if (ret) {
182 pr_err("Failed to register LP2 timer IRQ for CPU %d: "
183 "irq=%d, ret=%d\n", cpu,
184 tegra_lp2wake_irq[cpu].irq, ret);
185 goto fail;
186 }
187
188 ret = tegra3_resume_wake_timer(cpu);
189 if (ret)
190 goto fail;
191
192 test_lp2_wake_timer(cpu);
193 return;
194fail:
195 tegra_lp2_in_idle(false);
196}
197
198#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_HOTPLUG_CPU)
199static void tegra3_suspend_wake_timer(unsigned int cpu)
200{
201 cpumask_clear_cpu(cpu, &wake_timer_ready);
202#ifdef CONFIG_SMP
203 /* Reassign the affinity of the wake IRQ to CPU 0. */
204 (void)irq_set_affinity(tegra_lp2wake_irq[cpu].irq, cpumask_of(0));
205#endif
206}
207
208static void tegra3_unregister_wake_timer(unsigned int cpu)
209{
210 tegra3_suspend_wake_timer(cpu);
211
212 /* Dispose of this IRQ. */
213 remove_irq(tegra_lp2wake_irq[cpu].irq, &tegra_lp2wake_irq[cpu]);
214}
215#endif
216
217void tegra3_lp2_set_trigger(unsigned long cycles)
218{
219 int cpu = cpu_number();
220 int base;
221
222 base = lp2_wake_timers[cpu];
223 timer_writel(0, base + TIMER_PTV);
224 if (cycles) {
225 u32 reg = 0x80000000ul | min(0x1ffffffful, cycles);
226 timer_writel(reg, base + TIMER_PTV);
227 }
228}
229EXPORT_SYMBOL(tegra3_lp2_set_trigger);
230
231unsigned long tegra3_lp2_timer_remain(void)
232{
233 int cpu = cpu_number();
234
235 if (cpumask_test_and_clear_cpu(cpu, &wake_timer_canceled))
236 return -ETIME;
237
238 return timer_readl(lp2_wake_timers[cpu] + TIMER_PCR) & 0x1ffffffful;
239}
240
241int tegra3_is_lp2_timer_ready(unsigned int cpu)
242{
243 return cpumask_test_cpu(cpu, &wake_timer_ready);
244}
245
246void tegra3_lp2_timer_cancel_secondary(void)
247{
248 int cpu;
249 int base;
250
251 for (cpu = 1; cpu < ARRAY_SIZE(lp2_wake_timers); cpu++) {
252 base = lp2_wake_timers[cpu];
253 cpumask_set_cpu(cpu, &wake_timer_canceled);
254 timer_writel(0, base + TIMER_PTV);
255 timer_writel(1<<30, base + TIMER_PCR);
256 }
257}
258#endif
259
260void __init tegra3_init_timer(u32 *offset, int *irq)
261{
262 unsigned long rate = tegra_clk_measure_input_freq();
263
264 switch (rate) {
265 case 12000000:
266 timer_writel(0x000b, TIMERUS_USEC_CFG);
267 break;
268 case 13000000:
269 timer_writel(0x000c, TIMERUS_USEC_CFG);
270 break;
271 case 19200000:
272 timer_writel(0x045f, TIMERUS_USEC_CFG);
273 break;
274 case 26000000:
275 timer_writel(0x0019, TIMERUS_USEC_CFG);
276 break;
277 case 16800000:
278 timer_writel(0x0453, TIMERUS_USEC_CFG);
279 break;
280 case 38400000:
281 timer_writel(0x04BF, TIMERUS_USEC_CFG);
282 break;
283 case 48000000:
284 timer_writel(0x002F, TIMERUS_USEC_CFG);
285 break;
286 default:
287 WARN(1, "Unknown clock rate");
288 }
289
290#ifdef CONFIG_PM_SLEEP
291#ifdef CONFIG_SMP
292 /* For T30.A01 use INT_TMR_SHARED instead of INT_TMR6 for CPU3. */
293 if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) &&
294 (tegra_get_revision() == TEGRA_REVISION_A01))
295 tegra_lp2wake_irq[3].irq = INT_TMR_SHARED;
296#endif
297
298 tegra3_register_wake_timer(0);
299#endif
300
301 *offset = TIMER1_OFFSET;
302 *irq = INT_TMR1;
303}
304
305#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_HOTPLUG_CPU)
306static int hotplug_notify(struct notifier_block *self,
307 unsigned long action, void *cpu)
308{
309 switch (action) {
310 case CPU_ONLINE:
311 tegra3_register_wake_timer((unsigned int)cpu);
312 break;
313 case CPU_ONLINE_FROZEN:
314 tegra3_resume_wake_timer((unsigned int)cpu);
315 break;
316 case CPU_DOWN_PREPARE:
317 tegra3_unregister_wake_timer((unsigned int)cpu);
318 break;
319 case CPU_DOWN_PREPARE_FROZEN:
320 tegra3_suspend_wake_timer((unsigned int)cpu);
321 break;
322 default:
323 break;
324 }
325
326 return NOTIFY_OK;
327}
328
329static struct notifier_block __cpuinitdata hotplug_notifier_block = {
330 .notifier_call = hotplug_notify,
331};
332
333static int __init hotplug_cpu_register(void)
334{
335 return register_cpu_notifier(&hotplug_notifier_block);
336}
337early_initcall(hotplug_cpu_register);
338#endif
diff --git a/arch/arm/mach-tegra/timer.h b/arch/arm/mach-tegra/timer.h
new file mode 100644
index 00000000000..4a91792f5d9
--- /dev/null
+++ b/arch/arm/mach-tegra/timer.h
@@ -0,0 +1,55 @@
1/*
2 * arch/arm/mach-tegra/timer.h
3 *
4 * Copyright (C) 2010-2011 NVIDIA Corporation
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_TIMER_H_
18#define _MACH_TEGRA_TIMER_H_
19
20#define RTC_SECONDS 0x08
21#define RTC_SHADOW_SECONDS 0x0c
22#define RTC_MILLISECONDS 0x10
23
24#define TIMER_PTV 0x0
25#define TIMER_PCR 0x4
26
27#define TIMERUS_CNTR_1US 0x10
28#define TIMERUS_USEC_CFG 0x14
29#define TIMERUS_CNTR_FREEZE 0x4c
30
31
32#ifdef CONFIG_ARCH_TEGRA_2x_SOC
33void __init tegra2_init_timer(u32 *offset, int *irq);
34#else
35void __init tegra3_init_timer(u32 *offset, int *irq);
36#endif
37
38struct tegra_twd_context {
39 u32 twd_ctrl;
40 u32 twd_load;
41 u32 twd_cnt;
42};
43
44#ifdef CONFIG_HAVE_ARM_TWD
45int tegra_twd_get_state(struct tegra_twd_context *context);
46void tegra_twd_suspend(struct tegra_twd_context *context);
47void tegra_twd_resume(struct tegra_twd_context *context);
48#else
49static inline int tegra_twd_get_state(struct tegra_twd_context *context)
50{ return -ENODEV; }
51static inline void tegra_twd_suspend(struct tegra_twd_context *context) {}
52static inline void tegra_twd_resume(struct tegra_twd_context *context) {}
53#endif
54
55#endif /* _MACH_TEGRA_TIMER_H_ */
diff --git a/arch/arm/mach-tegra/timerinfo.c b/arch/arm/mach-tegra/timerinfo.c
new file mode 100644
index 00000000000..b64ea821f4a
--- /dev/null
+++ b/arch/arm/mach-tegra/timerinfo.c
@@ -0,0 +1,74 @@
1/*
2 * arch/arch/mach-tegra/timerinfo.c
3 *
4 * Copyright (C) 2012 NVIDIA Corporation.
5 *
6 * Author:
7 * Jon Mayo <jmayo@nvidia.com>
8 *
9 * Copyright (C) 2012 NVIDIA Corporation.
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#include <linux/init.h>
23#include <linux/fs.h>
24#include <linux/mm.h>
25#include <linux/platform_device.h>
26#include <linux/miscdevice.h>
27#include <mach/iomap.h>
28
29#include "timer.h"
30
31static int timerinfo_dev_mmap(struct file *file, struct vm_area_struct *vma);
32
33static const struct file_operations timerinfo_dev_fops = {
34 .owner = THIS_MODULE,
35 .open = nonseekable_open,
36 .mmap = timerinfo_dev_mmap,
37 .llseek = noop_llseek,
38};
39
40static struct miscdevice timerinfo_dev = {
41 .minor = MISC_DYNAMIC_MINOR,
42 .name = "timerinfo",
43 .fops = &timerinfo_dev_fops,
44};
45
46static int timerinfo_dev_mmap(struct file *file, struct vm_area_struct *vma)
47{
48 /* start at first page containing TIMERUS_CNTR_1US */
49 phys_addr_t addr = TEGRA_TMR1_BASE;
50
51 if (vma->vm_end - vma->vm_start != PAGE_SIZE)
52 return -EINVAL;
53
54 if (vma->vm_flags & VM_WRITE)
55 return -EPERM;
56
57 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
58
59 if (remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, PAGE_SIZE,
60 vma->vm_page_prot)) {
61 pr_err("%s:remap_pfn_range failed\n", timerinfo_dev.name);
62 return -EAGAIN;
63 }
64
65 return 0;
66}
67
68static int __init timerinfo_dev_init(void)
69{
70 return misc_register(&timerinfo_dev);
71}
72
73module_init(timerinfo_dev_init);
74MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
new file mode 100644
index 00000000000..d154b0649d1
--- /dev/null
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -0,0 +1,3019 @@
1/*
2 * arch/arm/mach-tegra/usb_phy.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2010 - 2011 NVIDIA Corporation
6 *
7 * Author:
8 * Erik Gilling <konkers@google.com>
9 * Benoit Goby <benoit@android.com>
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#include <linux/resource.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/slab.h>
26#include <linux/err.h>
27#include <linux/platform_device.h>
28#include <linux/io.h>
29#include <linux/gpio.h>
30#include <linux/usb/otg.h>
31#include <linux/usb/ulpi.h>
32#include <asm/mach-types.h>
33#include <mach/usb_phy.h>
34#include <mach/iomap.h>
35#include <mach/pinmux.h>
36#include "fuse.h"
37
38
39#ifdef CONFIG_ARCH_TEGRA_2x_SOC
40#define USB_USBCMD 0x140
41#define USB_USBCMD_RS (1 << 0)
42
43#define USB_USBSTS 0x144
44#define USB_USBSTS_PCI (1 << 2)
45#define USB_USBSTS_HCH (1 << 12)
46
47#define USB_TXFILLTUNING 0x164
48#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16)
49#define USB_FIFO_TXFILL_MASK 0x1f0000
50
51#define ULPI_VIEWPORT 0x170
52#define ULPI_WAKEUP (1 << 31)
53#define ULPI_RUN (1 << 30)
54#define ULPI_RD_WR (1 << 29)
55
56#define USB_PORTSC1 0x184
57#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
58#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26)
59#define USB_PORTSC1_PHCD (1 << 23)
60#define USB_PORTSC1_WKOC (1 << 22)
61#define USB_PORTSC1_WKDS (1 << 21)
62#define USB_PORTSC1_WKCN (1 << 20)
63#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
64#define USB_PORTSC1_PP (1 << 12)
65#define USB_PORTSC1_LS(x) (((x) & 0x3) << 10)
66#define USB_PORTSC1_SUSP (1 << 7)
67#define USB_PORTSC1_PE (1 << 2)
68#define USB_PORTSC1_CCS (1 << 0)
69
70#define USB_SUSP_CTRL 0x400
71#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
72#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
73#define USB_SUSP_CLR (1 << 5)
74#define USB_CLKEN (1 << 6)
75#define USB_PHY_CLK_VALID (1 << 7)
76#define USB_PHY_CLK_VALID_INT_ENB (1 << 9)
77#define UTMIP_RESET (1 << 11)
78#define UHSIC_RESET (1 << 11)
79#define UTMIP_PHY_ENABLE (1 << 12)
80#define UHSIC_PHY_ENABLE (1 << 12)
81#define ULPI_PHY_ENABLE (1 << 13)
82#define USB_SUSP_SET (1 << 14)
83#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
84
85#define USB_PHY_VBUS_WAKEUP_ID 0x408
86#define VDAT_DET_INT_EN (1 << 16)
87#define VDAT_DET_CHG_DET (1 << 17)
88#define VDAT_DET_STS (1 << 18)
89
90#define USB1_LEGACY_CTRL 0x410
91#define USB1_NO_LEGACY_MODE (1 << 0)
92#define USB1_VBUS_SENSE_CTL_MASK (3 << 1)
93#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1)
94#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \
95 (1 << 1)
96#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1)
97#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1)
98
99
100#define UTMIP_PLL_CFG1 0x804
101#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
102#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
103
104#define UTMIP_XCVR_CFG0 0x808
105#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0)
106#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8)
107#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10)
108#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
109#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
110#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
111#define UTMIP_XCVR_LSBIAS_SEL (1 << 21)
112#define UTMIP_XCVR_SETUP_MSB(x) (((x) & 0x7) << 22)
113#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25)
114
115#define UTMIP_XCVR_MAX_OFFSET 2
116#define UTMIP_XCVR_SETUP_MAX_VALUE 0x7f
117#define UTMIP_XCVR_SETUP_MIN_VALUE 0
118#define XCVR_SETUP_MSB_CALIB(x) ((x) >> 4)
119
120#define UTMIP_BIAS_CFG0 0x80c
121#define UTMIP_OTGPD (1 << 11)
122#define UTMIP_BIASPD (1 << 10)
123
124#define UTMIP_HSRX_CFG0 0x810
125#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10)
126#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15)
127
128#define UTMIP_HSRX_CFG1 0x814
129#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
130
131#define UTMIP_TX_CFG0 0x820
132#define UTMIP_FS_PREABMLE_J (1 << 19)
133#define UTMIP_HS_DISCON_DISABLE (1 << 8)
134
135#define UTMIP_MISC_CFG1 0x828
136#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18)
137#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6)
138
139#define UTMIP_DEBOUNCE_CFG0 0x82c
140#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0)
141
142#define UTMIP_BAT_CHRG_CFG0 0x830
143#define UTMIP_PD_CHRG (1 << 0)
144#define UTMIP_ON_SINK_EN (1 << 2)
145#define UTMIP_OP_SRC_EN (1 << 3)
146
147#define UTMIP_XCVR_CFG1 0x838
148#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
149#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
150#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
151#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18)
152
153#define UTMIP_BIAS_CFG1 0x83c
154#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
155
156#define UHSIC_PLL_CFG1 0x804
157#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
158#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14)
159
160#define UHSIC_HSRX_CFG0 0x808
161#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2)
162#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8)
163#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13)
164
165#define UHSIC_HSRX_CFG1 0x80c
166#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
167
168#define UHSIC_TX_CFG0 0x810
169#define UHSIC_HS_POSTAMBLE_OUTPUT_ENABLE (1 << 6)
170
171#define UHSIC_MISC_CFG0 0x814
172#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7)
173#define UHSIC_DETECT_SHORT_CONNECT (1 << 8)
174#define UHSIC_FORCE_XCVR_MODE (1 << 15)
175
176#define UHSIC_MISC_CFG1 0X818
177#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2)
178
179#define UHSIC_PADS_CFG0 0x81c
180#define UHSIC_TX_RTUNEN 0xf000
181#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12)
182
183#define UHSIC_PADS_CFG1 0x820
184#define UHSIC_PD_BG (1 << 2)
185#define UHSIC_PD_TX (1 << 3)
186#define UHSIC_PD_TRK (1 << 4)
187#define UHSIC_PD_RX (1 << 5)
188#define UHSIC_PD_ZI (1 << 6)
189#define UHSIC_RX_SEL (1 << 7)
190#define UHSIC_RPD_DATA (1 << 9)
191#define UHSIC_RPD_STROBE (1 << 10)
192#define UHSIC_RPU_DATA (1 << 11)
193#define UHSIC_RPU_STROBE (1 << 12)
194
195#define UHSIC_STAT_CFG0 0x828
196#define UHSIC_CONNECT_DETECT (1 << 0)
197
198
199#else
200
201#define USB_USBCMD 0x130
202#define USB_USBCMD_RS (1 << 0)
203
204#define USB_USBSTS 0x134
205#define USB_USBSTS_PCI (1 << 2)
206#define USB_USBSTS_SRI (1 << 7)
207#define USB_USBSTS_HCH (1 << 12)
208
209#define USB_TXFILLTUNING 0x154
210#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16)
211#define USB_FIFO_TXFILL_MASK 0x1f0000
212
213#define ULPI_VIEWPORT 0x160
214
215#define USB_PORTSC1 0x174
216#define USB_PORTSC1_WKOC (1 << 22)
217#define USB_PORTSC1_WKDS (1 << 21)
218#define USB_PORTSC1_WKCN (1 << 20)
219#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
220#define USB_PORTSC1_PP (1 << 12)
221#define USB_PORTSC1_LS(x) (((x) & 0x3) << 10)
222#define USB_PORTSC1_SUSP (1 << 7)
223#define USB_PORTSC1_RESUME (1 << 6)
224#define USB_PORTSC1_PE (1 << 2)
225#define USB_PORTSC1_CCS (1 << 0)
226
227#define USB_SUSP_CTRL 0x400
228#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
229#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
230#define USB_SUSP_CLR (1 << 5)
231#define USB_PHY_CLK_VALID (1 << 7)
232#define USB_PHY_CLK_VALID_INT_ENB (1 << 9)
233
234
235#define UTMIP_RESET (1 << 11)
236#define UTMIP_PHY_ENABLE (1 << 12)
237#define ULPI_PHY_ENABLE (1 << 13)
238#define UHSIC_RESET (1 << 14)
239
240#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
241#define UHSIC_PHY_ENABLE (1 << 19)
242#define ULPIS2S_SLV0_RESET (1 << 20)
243#define ULPIS2S_SLV1_RESET (1 << 21)
244#define ULPIS2S_LINE_RESET (1 << 22)
245#define ULPI_PADS_RESET (1 << 23)
246#define ULPI_PADS_CLKEN_RESET (1 << 24)
247
248#define USB_PHY_VBUS_WAKEUP_ID 0x408
249#define VDAT_DET_INT_EN (1 << 16)
250#define VDAT_DET_CHG_DET (1 << 17)
251#define VDAT_DET_STS (1 << 18)
252
253#define USB1_LEGACY_CTRL 0x410
254#define USB1_NO_LEGACY_MODE (1 << 0)
255#define USB1_VBUS_SENSE_CTL_MASK (3 << 1)
256#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1)
257#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \
258 (1 << 1)
259#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1)
260#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1)
261
262#define UTMIP_PLL_CFG1 0x804
263#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
264#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
265
266#define UTMIP_XCVR_CFG0 0x808
267#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0)
268#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8)
269#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10)
270#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
271#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
272#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
273#define UTMIP_XCVR_LSBIAS_SEL (1 << 21)
274#define UTMIP_XCVR_SETUP_MSB(x) (((x) & 0x7) << 22)
275#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25)
276
277#define UTMIP_XCVR_MAX_OFFSET 2
278#define UTMIP_XCVR_SETUP_MAX_VALUE 0x7f
279#define UTMIP_XCVR_SETUP_MIN_VALUE 0
280#define XCVR_SETUP_MSB_CALIB(x) ((x) >> 4)
281
282#define UTMIP_BIAS_CFG0 0x80c
283#define UTMIP_OTGPD (1 << 11)
284#define UTMIP_BIASPD (1 << 10)
285#define UTMIP_HSSQUELCH_LEVEL(x) (((x) & 0x3) << 0)
286#define UTMIP_HSDISCON_LEVEL(x) (((x) & 0x3) << 2)
287#define UTMIP_HSDISCON_LEVEL_MSB (1 << 24)
288
289#define UTMIP_HSRX_CFG0 0x810
290#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10)
291#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15)
292
293#define UTMIP_HSRX_CFG1 0x814
294#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
295
296#define UTMIP_TX_CFG0 0x820
297#define UTMIP_FS_PREABMLE_J (1 << 19)
298#define UTMIP_HS_DISCON_DISABLE (1 << 8)
299
300#define UTMIP_MISC_CFG1 0x828
301#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18)
302#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6)
303
304#define UTMIP_DEBOUNCE_CFG0 0x82c
305#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0)
306
307#define UTMIP_BAT_CHRG_CFG0 0x830
308#define UTMIP_PD_CHRG (1 << 0)
309#define UTMIP_ON_SINK_EN (1 << 2)
310#define UTMIP_OP_SRC_EN (1 << 3)
311
312#define UTMIP_XCVR_CFG1 0x838
313#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
314#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
315#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
316#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18)
317
318#define UTMIP_BIAS_CFG1 0x83c
319#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
320#define UTMIP_BIAS_PDTRK_POWERDOWN (1 << 0)
321#define UTMIP_BIAS_PDTRK_POWERUP (1 << 1)
322
323#define HOSTPC1_DEVLC 0x1b4
324#define HOSTPC1_DEVLC_PHCD (1 << 22)
325#define HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29)
326#define HOSTPC1_DEVLC_PTS_MASK 7
327#define HOSTPC1_DEVLC_PTS_HSIC 4
328#define HOSTPC1_DEVLC_STS (1 << 28)
329#define HOSTPC1_DEVLC_PSPD(x) (((x) & 0x3) << 25)
330#define HOSTPC1_DEVLC_PSPD_MASK 3
331#define HOSTPC1_DEVLC_PSPD_HIGH_SPEED 2
332
333#define TEGRA_USB_USBMODE_REG_OFFSET 0x1f8
334#define TEGRA_USB_USBMODE_HOST (3 << 0)
335
336#define TEGRA_PMC_USB_AO 0xf0
337#define TEGRA_PMC_USB_AO_VBUS_WAKEUP_PD_P0 (1 << 2)
338#define TEGRA_PMC_USB_AO_ID_PD_P0 (1 << 3)
339#define TEGRA_PMC_USB_AO_PD_P2 (0xf << 8)
340
341#define ICUSB_CTRL 0x15c
342
343#define UHSIC_PLL_CFG1 0xc04
344#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
345#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14)
346
347#define UHSIC_HSRX_CFG0 0xc08
348#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2)
349#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8)
350#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13)
351
352#define UHSIC_HSRX_CFG1 0xc0c
353#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
354
355#define UHSIC_TX_CFG0 0xc10
356#define UHSIC_HS_READY_WAIT_FOR_VALID (1 << 9)
357
358#define UHSIC_MISC_CFG0 0xc14
359#define UHSIC_SUSPEND_EXIT_ON_EDGE (1 << 7)
360#define UHSIC_DETECT_SHORT_CONNECT (1 << 8)
361#define UHSIC_FORCE_XCVR_MODE (1 << 15)
362#define UHSIC_DISABLE_BUSRESET (1 << 20)
363
364#define UHSIC_MISC_CFG1 0xc18
365#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2)
366
367#define UHSIC_PADS_CFG0 0xc1c
368#define UHSIC_TX_RTUNEN 0xf000
369#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12)
370
371#define UHSIC_PADS_CFG1 0xc20
372#define UHSIC_PD_BG (1 << 2)
373#define UHSIC_PD_TX (1 << 3)
374#define UHSIC_PD_TRK (1 << 4)
375#define UHSIC_PD_RX (1 << 5)
376#define UHSIC_PD_ZI (1 << 6)
377#define UHSIC_RX_SEL (1 << 7)
378#define UHSIC_RPD_DATA (1 << 9)
379#define UHSIC_RPD_STROBE (1 << 10)
380#define UHSIC_RPU_DATA (1 << 11)
381#define UHSIC_RPU_STROBE (1 << 12)
382
383#define UHSIC_STAT_CFG0 0xc28
384#define UHSIC_CONNECT_DETECT (1 << 0)
385
386#define PMC_UTMIP_MASTER_CONFIG 0x310
387#define UTMIP_PWR(inst) (1 << (inst))
388
389#define PMC_USB_DEBOUNCE 0xec
390#define UTMIP_LINE_DEB_CNT(x) (((x) & 0xf) << 16)
391
392#define PMC_UTMIP_UHSIC_FAKE 0x218
393#define USBON_VAL(inst) (1 << ((4*(inst))+1))
394#define USBON_VAL_P2 (1 << 9)
395#define USBON_VAL_P1 (1 << 5)
396#define USBON_VAL_P0 (1 << 1)
397#define USBOP_VAL(inst) (1 << (4*(inst)))
398#define USBOP_VAL_P2 (1 << 8)
399#define USBOP_VAL_P1 (1 << 4)
400#define USBOP_VAL_P0 (1 << 0)
401
402#define PMC_SLEEPWALK_CFG 0x200
403#define UTMIP_LINEVAL_WALK_EN(inst) (1 << ((8*(inst))+7))
404#define UTMIP_LINEVAL_WALK_EN_P2 (1 << 23)
405#define UTMIP_LINEVAL_WALK_EN_P1 (1 << 15)
406#define UTMIP_LINEVAL_WALK_EN_P0 (1 << 7)
407#define UTMIP_WAKE_VAL(inst, x) (((x) & 0xf) << ((8*(inst))+4))
408#define UTMIP_WAKE_VAL_P2(x) (((x) & 0xf) << 20)
409#define UTMIP_WAKE_VAL_P1(x) (((x) & 0xf) << 12)
410#define UTMIP_WAKE_VAL_P0(x) (((x) & 0xf) << 4)
411#define WAKE_VAL_NONE 0xc
412#define WAKE_VAL_FSJ 0x2
413#define WAKE_VAL_FSK 0x1
414#define WAKE_VAL_SE0 0x0
415#define WAKE_VAL_ANY 0xf
416
417#define PMC_SLEEP_CFG 0x1fc
418#define UTMIP_TCTRL_USE_PMC(inst) (1 << ((8*(inst))+3))
419#define UTMIP_TCTRL_USE_PMC_P2 (1 << 19)
420#define UTMIP_TCTRL_USE_PMC_P1 (1 << 11)
421#define UTMIP_TCTRL_USE_PMC_P0 (1 << 3)
422#define UTMIP_RCTRL_USE_PMC(inst) (1 << ((8*(inst))+2))
423#define UTMIP_RCTRL_USE_PMC_P2 (1 << 18)
424#define UTMIP_RCTRL_USE_PMC_P1 (1 << 10)
425#define UTMIP_RCTRL_USE_PMC_P0 (1 << 2)
426#define UTMIP_FSLS_USE_PMC(inst) (1 << ((8*(inst))+1))
427#define UTMIP_FSLS_USE_PMC_P2 (1 << 17)
428#define UTMIP_FSLS_USE_PMC_P1 (1 << 9)
429#define UTMIP_FSLS_USE_PMC_P0 (1 << 1)
430#define UTMIP_MASTER_ENABLE(inst) (1 << (8*(inst)))
431#define UTMIP_MASTER_ENABLE_P2 (1 << 16)
432#define UTMIP_MASTER_ENABLE_P1 (1 << 8)
433#define UTMIP_MASTER_ENABLE_P0 (1 << 0)
434
435#define PMC_USB_AO 0xf0
436#define USBON_VAL_PD(inst) (1 << ((4*(inst))+1))
437#define USBON_VAL_PD_P2 (1 << 9)
438#define USBON_VAL_PD_P1 (1 << 5)
439#define USBON_VAL_PD_P0 (1 << 1)
440#define USBOP_VAL_PD(inst) (1 << (4*(inst)))
441#define USBOP_VAL_PD_P2 (1 << 8)
442#define USBOP_VAL_PD_P1 (1 << 4)
443#define USBOP_VAL_PD_P0 (1 << 0)
444
445#define PMC_TRIGGERS 0x1ec
446#define UTMIP_CLR_WALK_PTR(inst) (1 << (inst))
447#define UTMIP_CLR_WALK_PTR_P2 (1 << 2)
448#define UTMIP_CLR_WALK_PTR_P1 (1 << 1)
449#define UTMIP_CLR_WALK_PTR_P0 (1 << 0)
450#define UTMIP_CAP_CFG(inst) (1 << ((inst)+4))
451#define UTMIP_CAP_CFG_P2 (1 << 6)
452#define UTMIP_CAP_CFG_P1 (1 << 5)
453#define UTMIP_CAP_CFG_P0 (1 << 4)
454#define UTMIP_CLR_WAKE_ALARM(inst) (1 << ((inst)+12))
455#define UTMIP_CLR_WAKE_ALARM_P2 (1 << 14)
456
457#define PMC_PAD_CFG (0x1f4)
458
459#define PMC_UTMIP_BIAS_MASTER_CNTRL 0x30c
460#define BIAS_MASTER_PROG_VAL (1 << 1)
461
462#define PMC_SLEEPWALK_REG(inst) (0x204 + (4*(inst)))
463#define PMC_SLEEPWALK_P0 0x204
464#define PMC_SLEEPWALK_P1 0x208
465#define PMC_SLEEPWALK_P2 0x20c
466#define UTMIP_USBOP_RPD_A (1 << 0)
467#define UTMIP_USBON_RPD_A (1 << 1)
468#define UTMIP_AP_A (1 << 4)
469#define UTMIP_AN_A (1 << 5)
470#define UTMIP_HIGHZ_A (1 << 6)
471#define UTMIP_USBOP_RPD_B (1 << 8)
472#define UTMIP_USBON_RPD_B (1 << 9)
473#define UTMIP_AP_B (1 << 12)
474#define UTMIP_AN_B (1 << 13)
475#define UTMIP_HIGHZ_B (1 << 14)
476#define UTMIP_USBOP_RPD_C (1 << 16)
477#define UTMIP_USBON_RPD_C (1 << 17)
478#define UTMIP_AP_C (1 << 20)
479#define UTMIP_AN_C (1 << 21)
480#define UTMIP_HIGHZ_C (1 << 22)
481#define UTMIP_USBOP_RPD_D (1 << 24)
482#define UTMIP_USBON_RPD_D (1 << 25)
483#define UTMIP_AP_D (1 << 28)
484#define UTMIP_AN_D (1 << 29)
485#define UTMIP_HIGHZ_D (1 << 30)
486
487#define UTMIP_PMC_WAKEUP0 0x84c
488#define EVENT_INT_ENB (1 << 0)
489
490#define UTMIP_UHSIC_STATUS 0x214
491#define UTMIP_WALK_PTR_VAL(inst) (0x3 << ((inst)*2))
492#define UTMIP_USBOP_VAL(inst) (1 << ((2*(inst)) + 8))
493#define UTMIP_USBOP_VAL_P2 (1 << 12)
494#define UTMIP_USBOP_VAL_P1 (1 << 10)
495#define UTMIP_USBOP_VAL_P0 (1 << 8)
496#define UTMIP_USBON_VAL(inst) (1 << ((2*(inst)) + 9))
497#define UTMIP_USBON_VAL_P2 (1 << 13)
498#define UTMIP_USBON_VAL_P1 (1 << 11)
499#define UTMIP_USBON_VAL_P0 (1 << 9)
500#define UTMIP_WAKE_ALARM(inst) (1 << ((inst) + 16))
501#define UTMIP_WAKE_ALARM_P2 (1 << 18)
502#define UTMIP_WAKE_ALARM_P1 (1 << 17)
503#define UTMIP_WAKE_ALARM_P0 (1 << 16)
504#define UTMIP_WALK_PTR(inst) (1 << ((inst)*2))
505#define UTMIP_WALK_PTR_P2 (1 << 4)
506#define UTMIP_WALK_PTR_P1 (1 << 2)
507#define UTMIP_WALK_PTR_P0 (1 << 0)
508
509#define UTMIP_BIAS_STS0 0x840
510#define UTMIP_RCTRL_VAL(x) (((x) & 0xffff) << 0)
511#define UTMIP_TCTRL_VAL(x) (((x) & (0xffff << 16)) >> 16)
512
513#define PMC_UTMIP_TERM_PAD_CFG 0x1f8
514#define PMC_TCTRL_VAL(x) (((x) & 0x1f) << 5)
515#define PMC_RCTRL_VAL(x) (((x) & 0x1f) << 0)
516
517static u32 utmip_rctrl_val, utmip_tctrl_val;
518
519#endif
520
521/* Common registers */
522#define UTMIP_MISC_CFG0 0x824
523#define UTMIP_DPDM_OBSERVE (1 << 26)
524#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27)
525#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf)
526#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe)
527#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd)
528#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc)
529#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22)
530#define FORCE_PULLDN_DM (1 << 8)
531#define FORCE_PULLDN_DP (1 << 9)
532#define COMB_TERMS (1 << 0)
533#define ALWAYS_FREE_RUNNING_TERMS (1 << 1)
534
535#define ULPIS2S_CTRL 0x418
536#define ULPIS2S_ENA (1 << 0)
537#define ULPIS2S_SUPPORT_DISCONNECT (1 << 2)
538#define ULPIS2S_PLLU_MASTER_BLASTER60 (1 << 3)
539#define ULPIS2S_SPARE(x) (((x) & 0xF) << 8)
540#define ULPIS2S_FORCE_ULPI_CLK_OUT (1 << 12)
541#define ULPIS2S_DISCON_DONT_CHECK_SE0 (1 << 13)
542#define ULPIS2S_SUPPORT_HS_KEEP_ALIVE (1 << 14)
543#define ULPIS2S_DISABLE_STP_PU (1 << 15)
544#define ULPIS2S_SLV0_CLAMP_XMIT (1 << 16)
545
546
547#define ULPI_TIMING_CTRL_0 0x424
548#define ULPI_CLOCK_OUT_DELAY(x) ((x) & 0x1F)
549#define ULPI_OUTPUT_PINMUX_BYP (1 << 10)
550#define ULPI_CLKOUT_PINMUX_BYP (1 << 11)
551#define ULPI_SHADOW_CLK_LOOPBACK_EN (1 << 12)
552#define ULPI_SHADOW_CLK_SEL (1 << 13)
553#define ULPI_CORE_CLK_SEL (1 << 14)
554#define ULPI_SHADOW_CLK_DELAY(x) (((x) & 0x1F) << 16)
555#define ULPI_LBK_PAD_EN (1 << 26)
556#define ULPI_LBK_PAD_E_INPUT_OR (1 << 27)
557#define ULPI_CLK_OUT_ENA (1 << 28)
558#define ULPI_CLK_PADOUT_ENA (1 << 29)
559
560#define ULPI_TIMING_CTRL_1 0x428
561#define ULPI_DATA_TRIMMER_LOAD (1 << 0)
562#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1)
563#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16)
564#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17)
565#define ULPI_DIR_TRIMMER_LOAD (1 << 24)
566#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25)
567
568#define UTMIP_SPARE_CFG0 0x834
569#define FUSE_SETUP_SEL (1 << 3)
570#define FUSE_ATERM_SEL (1 << 4)
571
572#define FUSE_USB_CALIB_0 0x1F0
573#define FUSE_USB_CALIB_XCVR_SETUP(x) (((x) & 0x7F) << 0)
574
575#define UHSIC_PLL_CFG0 0x800
576
577#define UHSIC_CMD_CFG0 0x824
578#define UHSIC_PRETEND_CONNECT_DETECT (1 << 5)
579
580#define UHSIC_SPARE_CFG0 0x82c
581
582/* These values (in milli second) are taken from the battery charging spec */
583#define TDP_SRC_ON_MS 100
584#define TDPSRC_CON_MS 40
585
586#define CONNECT_DETECT_TIMEOUT 25000
587
588static DEFINE_SPINLOCK(utmip_pad_lock);
589static int utmip_pad_count;
590
591struct tegra_xtal_freq {
592 int freq;
593 u8 enable_delay;
594 u8 stable_count;
595 u8 active_delay;
596 u16 xtal_freq_count;
597 u16 debounce;
598 u8 pdtrk_count;
599};
600
601static const struct tegra_xtal_freq tegra_freq_table[] = {
602 {
603 .freq = 12000000,
604 .enable_delay = 0x02,
605 .stable_count = 0x2F,
606 .active_delay = 0x04,
607 .xtal_freq_count = 0x76,
608 .debounce = 0x7530,
609 .pdtrk_count = 5,
610 },
611 {
612 .freq = 13000000,
613 .enable_delay = 0x02,
614 .stable_count = 0x33,
615 .active_delay = 0x05,
616 .xtal_freq_count = 0x7F,
617 .debounce = 0x7EF4,
618 .pdtrk_count = 5,
619 },
620 {
621 .freq = 19200000,
622 .enable_delay = 0x03,
623 .stable_count = 0x4B,
624 .active_delay = 0x06,
625 .xtal_freq_count = 0xBB,
626 .debounce = 0xBB80,
627 .pdtrk_count = 7,
628 },
629 {
630 .freq = 26000000,
631 .enable_delay = 0x04,
632 .stable_count = 0x66,
633 .active_delay = 0x09,
634 .xtal_freq_count = 0xFE,
635 .debounce = 0xFDE8,
636 .pdtrk_count = 9,
637 },
638};
639
640static const struct tegra_xtal_freq tegra_uhsic_freq_table[] = {
641 {
642 .freq = 12000000,
643 .enable_delay = 0x02,
644 .stable_count = 0x2F,
645 .active_delay = 0x0,
646 .xtal_freq_count = 0x1CA,
647 },
648 {
649 .freq = 13000000,
650 .enable_delay = 0x02,
651 .stable_count = 0x33,
652 .active_delay = 0x0,
653 .xtal_freq_count = 0x1F0,
654 },
655 {
656 .freq = 19200000,
657 .enable_delay = 0x03,
658 .stable_count = 0x4B,
659 .active_delay = 0x0,
660 .xtal_freq_count = 0x2DD,
661 },
662 {
663 .freq = 26000000,
664 .enable_delay = 0x04,
665 .stable_count = 0x66,
666 .active_delay = 0x0,
667 .xtal_freq_count = 0x3E0,
668 },
669};
670
671static struct tegra_utmip_config utmip_default[] = {
672 [0] = {
673 .hssync_start_delay = 9,
674 .idle_wait_delay = 17,
675 .elastic_limit = 16,
676 .term_range_adj = 6,
677 .xcvr_setup = 9,
678 .xcvr_setup_offset = 0,
679 .xcvr_use_fuses = 1,
680 .xcvr_lsfslew = 2,
681 .xcvr_lsrslew = 2,
682 },
683 [2] = {
684 .hssync_start_delay = 9,
685 .idle_wait_delay = 17,
686 .elastic_limit = 16,
687 .term_range_adj = 6,
688 .xcvr_setup_offset = 0,
689 .xcvr_use_fuses = 1,
690 .xcvr_setup = 9,
691 .xcvr_lsfslew = 2,
692 .xcvr_lsrslew = 2,
693 },
694};
695
696struct usb_phy_plat_data usb_phy_data[] = {
697 { 0, 0, -1, NULL},
698 { 0, 0, -1, NULL},
699 { 0, 0, -1, NULL},
700};
701
702static int utmip_pad_open(struct tegra_usb_phy *phy)
703{
704 phy->pad_clk = clk_get_sys("utmip-pad", NULL);
705 if (IS_ERR(phy->pad_clk)) {
706 pr_err("%s: can't get utmip pad clock\n", __func__);
707 return PTR_ERR(phy->pad_clk);
708 }
709
710 if (phy->instance == 0) {
711 phy->pad_regs = phy->regs;
712 } else {
713 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
714 if (!phy->pad_regs) {
715 pr_err("%s: can't remap usb registers\n", __func__);
716 clk_put(phy->pad_clk);
717 return -ENOMEM;
718 }
719 }
720 return 0;
721}
722
723static void utmip_pad_close(struct tegra_usb_phy *phy)
724{
725 if (phy->instance != 0)
726 iounmap(phy->pad_regs);
727 clk_put(phy->pad_clk);
728}
729
730static int utmip_pad_power_on(struct tegra_usb_phy *phy)
731{
732 unsigned long val, flags;
733 void __iomem *base = phy->pad_regs;
734
735 clk_enable(phy->pad_clk);
736
737 spin_lock_irqsave(&utmip_pad_lock, flags);
738
739 utmip_pad_count++;
740 val = readl(base + UTMIP_BIAS_CFG0);
741 val &= ~(UTMIP_OTGPD | UTMIP_BIASPD);
742#ifndef CONFIG_ARCH_TEGRA_2x_SOC
743 val |= UTMIP_HSSQUELCH_LEVEL(0x2) | UTMIP_HSDISCON_LEVEL(0x1) |
744 UTMIP_HSDISCON_LEVEL_MSB;
745#endif
746 writel(val, base + UTMIP_BIAS_CFG0);
747
748 spin_unlock_irqrestore(&utmip_pad_lock, flags);
749
750 clk_disable(phy->pad_clk);
751
752 return 0;
753}
754
755static int utmip_pad_power_off(struct tegra_usb_phy *phy, bool is_dpd)
756{
757 unsigned long val, flags;
758 void __iomem *base = phy->pad_regs;
759
760 if (!utmip_pad_count) {
761 pr_err("%s: utmip pad already powered off\n", __func__);
762 return -EINVAL;
763 }
764
765 clk_enable(phy->pad_clk);
766
767 spin_lock_irqsave(&utmip_pad_lock, flags);
768
769 if (--utmip_pad_count == 0 && is_dpd) {
770 val = readl(base + UTMIP_BIAS_CFG0);
771 val |= UTMIP_OTGPD | UTMIP_BIASPD;
772#ifndef CONFIG_ARCH_TEGRA_2x_SOC
773 val &= ~(UTMIP_HSSQUELCH_LEVEL(~0) | UTMIP_HSDISCON_LEVEL(~0) |
774 UTMIP_HSDISCON_LEVEL_MSB);
775#endif
776 writel(val, base + UTMIP_BIAS_CFG0);
777 }
778
779 spin_unlock_irqrestore(&utmip_pad_lock, flags);
780
781 clk_disable(phy->pad_clk);
782
783 return 0;
784}
785
786static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result)
787{
788 unsigned long timeout = 2500;
789 do {
790 if ((readl(reg) & mask) == result)
791 return 0;
792 udelay(1);
793 timeout--;
794 } while (timeout);
795 return -1;
796}
797
798static int utmi_wait_register_timeout(void __iomem *reg, u32 mask, u32 result,
799 unsigned long timeout)
800{
801 do {
802 if ((readl(reg) & mask) == result)
803 return 0;
804 udelay(1);
805 timeout--;
806 } while (timeout);
807 return -1;
808}
809
810static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
811{
812 unsigned long val;
813 void __iomem *base = phy->regs;
814
815#ifdef CONFIG_ARCH_TEGRA_2x_SOC
816 if (phy->instance == 0) {
817 val = readl(base + USB_SUSP_CTRL);
818 val |= USB_SUSP_SET;
819 writel(val, base + USB_SUSP_CTRL);
820
821 udelay(10);
822
823 val = readl(base + USB_SUSP_CTRL);
824 val &= ~USB_SUSP_SET;
825 writel(val, base + USB_SUSP_CTRL);
826 }
827
828 if (phy->instance == 2) {
829 val = readl(base + USB_PORTSC1);
830 val |= USB_PORTSC1_PHCD;
831 writel(val, base + USB_PORTSC1);
832 }
833#else
834 val = readl(base + HOSTPC1_DEVLC);
835 val |= HOSTPC1_DEVLC_PHCD;
836 writel(val, base + HOSTPC1_DEVLC);
837#endif
838 if (phy->instance == 2) {
839 val = readl(base + USB_SUSP_CTRL);
840 val |= USB_PHY_CLK_VALID_INT_ENB;
841 writel(val, base + USB_SUSP_CTRL);
842 } else {
843 val = readl(base + USB_SUSP_CTRL);
844 val |= UTMIP_RESET;
845 writel(val, base + USB_SUSP_CTRL);
846 }
847
848 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
849 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
850}
851
852static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
853{
854 unsigned long val;
855 void __iomem *base = phy->regs;
856
857 if (phy->instance == 0) {
858 val = readl(base + USB_SUSP_CTRL);
859 val |= USB_SUSP_CLR;
860 writel(val, base + USB_SUSP_CTRL);
861
862 udelay(10);
863
864 val = readl(base + USB_SUSP_CTRL);
865 val &= ~USB_SUSP_CLR;
866 writel(val, base + USB_SUSP_CTRL);
867 }
868
869#ifdef CONFIG_ARCH_TEGRA_2x_SOC
870 if (phy->instance == 2) {
871 val = readl(base + USB_PORTSC1);
872 val &= ~USB_PORTSC1_PHCD;
873 writel(val, base + USB_PORTSC1);
874 }
875#endif
876
877 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
878 USB_PHY_CLK_VALID) < 0)
879 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
880}
881
882static void vbus_enable(struct tegra_usb_phy *phy)
883{
884#ifdef CONFIG_ARCH_TEGRA_2x_SOC
885 int gpio_status;
886 int gpio = usb_phy_data[phy->instance].vbus_gpio;
887
888 if (gpio == -1)
889 return;
890
891 gpio_status = gpio_request(gpio,"VBUS_USB");
892 if (gpio_status < 0) {
893 printk("VBUS_USB request GPIO FAILED\n");
894 WARN_ON(1);
895 return;
896 }
897 if (gpio < TEGRA_NR_GPIOS) tegra_gpio_enable(gpio);
898 gpio_status = gpio_direction_output(gpio, 1);
899 if (gpio_status < 0) {
900 printk("VBUS_USB request GPIO DIRECTION FAILED \n");
901 WARN_ON(1);
902 return;
903 }
904 gpio_set_value_cansleep(gpio, 1);
905#else
906 if (phy->reg_vbus)
907 regulator_enable(phy->reg_vbus);
908#endif
909}
910
911static void vbus_disable(struct tegra_usb_phy *phy)
912{
913#ifdef CONFIG_ARCH_TEGRA_2x_SOC
914 int gpio = usb_phy_data[phy->instance].vbus_gpio;
915
916 if (gpio == -1)
917 return;
918
919 gpio_set_value_cansleep(gpio, 0);
920 gpio_free(gpio);
921#else
922 if (phy->reg_vbus)
923 regulator_disable(phy->reg_vbus);
924#endif
925}
926
927#ifndef CONFIG_ARCH_TEGRA_2x_SOC
928static void utmip_phy_enable_trking_data(struct tegra_usb_phy *phy)
929{
930 void __iomem *base = phy->pad_regs;
931 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
932 static bool init_done = false;
933 u32 val;
934
935 /* Should be done only once after system boot */
936 if (init_done)
937 return;
938
939 clk_enable(phy->pad_clk);
940 /* Bias pad MASTER_ENABLE=1 */
941 val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
942 val |= BIAS_MASTER_PROG_VAL;
943 writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
944
945 /* Setting the tracking length time */
946 val = readl(base + UTMIP_BIAS_CFG1);
947 val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
948 val |= UTMIP_BIAS_PDTRK_COUNT(5);
949 writel(val, base + UTMIP_BIAS_CFG1);
950
951 /* Bias PDTRK is Shared and MUST be done from USB1 ONLY, PD_TRK=0 */
952 val = readl(base + UTMIP_BIAS_CFG1);
953 val &= ~ UTMIP_BIAS_PDTRK_POWERDOWN;
954 writel(val, base + UTMIP_BIAS_CFG1);
955
956 val = readl(base + UTMIP_BIAS_CFG1);
957 val |= UTMIP_BIAS_PDTRK_POWERUP;
958 writel(val, base + UTMIP_BIAS_CFG1);
959
960 /* Wait for 25usec */
961 udelay(25);
962
963 /* Bias pad MASTER_ENABLE=0 */
964 val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
965 val &= ~BIAS_MASTER_PROG_VAL;
966 writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
967
968 /* Wait for 1usec */
969 udelay(1);
970
971 /* Bias pad MASTER_ENABLE=1 */
972 val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
973 val |= BIAS_MASTER_PROG_VAL;
974 writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
975
976 /* Read RCTRL and TCTRL from UTMIP space */
977 val = readl(base + UTMIP_BIAS_STS0);
978 utmip_rctrl_val = ffz(UTMIP_RCTRL_VAL(val));
979 utmip_tctrl_val = ffz(UTMIP_TCTRL_VAL(val));
980
981 /* PD_TRK=1 */
982 val = readl(base + UTMIP_BIAS_CFG1);
983 val |= UTMIP_BIAS_PDTRK_POWERDOWN;
984 writel(val, base + UTMIP_BIAS_CFG1);
985
986 /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */
987 val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG);
988 val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val);
989 writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG);
990 clk_disable(phy->pad_clk);
991 init_done = true;
992}
993#endif
994
995static unsigned int tegra_phy_xcvr_setup_value(struct tegra_utmip_config *cfg)
996{
997 signed long val;
998
999 if (cfg->xcvr_use_fuses) {
1000 val = FUSE_USB_CALIB_XCVR_SETUP(
1001 tegra_fuse_readl(FUSE_USB_CALIB_0));
1002 if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET)
1003 val = val + cfg->xcvr_setup_offset;
1004
1005 if (val > UTMIP_XCVR_SETUP_MAX_VALUE) {
1006 val = UTMIP_XCVR_SETUP_MAX_VALUE;
1007 pr_info("%s: reset XCVR_SETUP to max value\n",
1008 __func__);
1009 } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) {
1010 val = UTMIP_XCVR_SETUP_MIN_VALUE;
1011 pr_info("%s: reset XCVR_SETUP to min value\n",
1012 __func__);
1013 }
1014 } else {
1015 val = cfg->xcvr_setup;
1016 }
1017
1018 return (unsigned int)val;
1019}
1020
1021static int utmi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
1022{
1023 unsigned long val;
1024 void __iomem *base = phy->regs;
1025 unsigned int xcvr_setup_value;
1026 struct tegra_utmip_config *config = phy->config;
1027
1028 val = readl(base + USB_SUSP_CTRL);
1029 val |= UTMIP_RESET;
1030 writel(val, base + USB_SUSP_CTRL);
1031
1032#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1033 if (phy->instance == 0) {
1034 val = readl(base + USB1_LEGACY_CTRL);
1035 val |= USB1_NO_LEGACY_MODE;
1036 writel(val, base + USB1_LEGACY_CTRL);
1037 }
1038#endif
1039
1040 val = readl(base + UTMIP_TX_CFG0);
1041 val |= UTMIP_FS_PREABMLE_J;
1042 writel(val, base + UTMIP_TX_CFG0);
1043
1044 val = readl(base + UTMIP_HSRX_CFG0);
1045 val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0));
1046 val |= UTMIP_IDLE_WAIT(config->idle_wait_delay);
1047 val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit);
1048 writel(val, base + UTMIP_HSRX_CFG0);
1049
1050 val = readl(base + UTMIP_HSRX_CFG1);
1051 val &= ~UTMIP_HS_SYNC_START_DLY(~0);
1052 val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay);
1053 writel(val, base + UTMIP_HSRX_CFG1);
1054
1055 val = readl(base + UTMIP_DEBOUNCE_CFG0);
1056 val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
1057 val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce);
1058 writel(val, base + UTMIP_DEBOUNCE_CFG0);
1059
1060 val = readl(base + UTMIP_MISC_CFG0);
1061 val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
1062 writel(val, base + UTMIP_MISC_CFG0);
1063
1064#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1065 val = readl(base + UTMIP_MISC_CFG1);
1066 val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0));
1067 val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) |
1068 UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count);
1069 writel(val, base + UTMIP_MISC_CFG1);
1070
1071 val = readl(base + UTMIP_PLL_CFG1);
1072 val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0));
1073 val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) |
1074 UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
1075 writel(val, base + UTMIP_PLL_CFG1);
1076#endif
1077
1078 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
1079 val = readl(base + USB_SUSP_CTRL);
1080 val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV);
1081 writel(val, base + USB_SUSP_CTRL);
1082 }
1083
1084 utmip_pad_power_on(phy);
1085
1086 xcvr_setup_value = phy->xcvr_setup_value;
1087
1088 val = readl(base + UTMIP_XCVR_CFG0);
1089 val &= ~(UTMIP_XCVR_LSBIAS_SEL | UTMIP_FORCE_PD_POWERDOWN |
1090 UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN |
1091 UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_LSFSLEW(~0) |
1092 UTMIP_XCVR_LSRSLEW(~0) | UTMIP_XCVR_HSSLEW_MSB(~0));
1093 val |= UTMIP_XCVR_SETUP(xcvr_setup_value);
1094 val |= UTMIP_XCVR_SETUP_MSB(XCVR_SETUP_MSB_CALIB(xcvr_setup_value));
1095 val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew);
1096 val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew);
1097#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1098 val |= UTMIP_XCVR_HSSLEW_MSB(0x8);
1099#endif
1100 writel(val, base + UTMIP_XCVR_CFG0);
1101
1102 val = readl(base + UTMIP_XCVR_CFG1);
1103 val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
1104 UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0));
1105 val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj);
1106 writel(val, base + UTMIP_XCVR_CFG1);
1107
1108 val = readl(base + UTMIP_BAT_CHRG_CFG0);
1109 if (phy->mode == TEGRA_USB_PHY_MODE_HOST)
1110 val |= UTMIP_PD_CHRG;
1111 else
1112 val &= ~UTMIP_PD_CHRG;
1113 writel(val, base + UTMIP_BAT_CHRG_CFG0);
1114
1115 val = readl(base + UTMIP_BIAS_CFG1);
1116 val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
1117 val |= UTMIP_BIAS_PDTRK_COUNT(phy->freq->pdtrk_count);
1118 writel(val, base + UTMIP_BIAS_CFG1);
1119
1120#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1121 val = readl(base + UTMIP_SPARE_CFG0);
1122 val &= ~FUSE_SETUP_SEL;
1123 writel(val, base + UTMIP_SPARE_CFG0);
1124
1125 if (phy->instance == 2) {
1126 val = readl(base + UTMIP_SPARE_CFG0);
1127 val |= FUSE_SETUP_SEL;
1128 writel(val, base + UTMIP_SPARE_CFG0);
1129
1130 val = readl(base + USB_SUSP_CTRL);
1131 val |= UTMIP_PHY_ENABLE;
1132 writel(val, base + USB_SUSP_CTRL);
1133 }
1134#else
1135 val = readl(base + UTMIP_SPARE_CFG0);
1136 val &= ~FUSE_SETUP_SEL;
1137 val |= FUSE_ATERM_SEL;
1138 writel(val, base + UTMIP_SPARE_CFG0);
1139
1140 val = readl(base + USB_SUSP_CTRL);
1141 val |= UTMIP_PHY_ENABLE;
1142 writel(val, base + USB_SUSP_CTRL);
1143#endif
1144
1145 val = readl(base + USB_SUSP_CTRL);
1146 val &= ~UTMIP_RESET;
1147 writel(val, base + USB_SUSP_CTRL);
1148
1149 if (phy->instance == 0) {
1150 val = readl(base + USB1_LEGACY_CTRL);
1151 val &= ~USB1_VBUS_SENSE_CTL_MASK;
1152 val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD;
1153 writel(val, base + USB1_LEGACY_CTRL);
1154
1155#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1156 val = readl(base + USB_SUSP_CTRL);
1157 val &= ~USB_SUSP_SET;
1158 writel(val, base + USB_SUSP_CTRL);
1159#endif
1160 }
1161
1162 utmi_phy_clk_enable(phy);
1163#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1164 if (phy->instance == 2) {
1165 val = readl(base + USB_PORTSC1);
1166 val &= ~USB_PORTSC1_PTS(~0);
1167 writel(val, base + USB_PORTSC1);
1168 }
1169#else
1170 if (phy->instance == 0)
1171 utmip_phy_enable_trking_data(phy);
1172
1173 if(phy->instance == 2) {
1174 writel(0, base + ICUSB_CTRL);
1175 }
1176
1177 if (phy->mode == TEGRA_USB_PHY_MODE_HOST) {
1178 val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET);
1179 writel((val | TEGRA_USB_USBMODE_HOST),
1180 (base + TEGRA_USB_USBMODE_REG_OFFSET));
1181 }
1182 val = readl(base + HOSTPC1_DEVLC);
1183 val &= ~HOSTPC1_DEVLC_PTS(~0);
1184 val |= HOSTPC1_DEVLC_STS;
1185 writel(val, base + HOSTPC1_DEVLC);
1186#endif
1187
1188 return 0;
1189}
1190
1191#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1192static void utmip_setup_pmc_wake_detect(struct tegra_usb_phy *phy)
1193{
1194 unsigned long val, pmc_pad_cfg_val;
1195 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
1196 unsigned int inst = phy->instance;
1197 void __iomem *base = phy->regs;
1198 bool port_connected;
1199 enum tegra_usb_phy_port_speed port_speed;
1200
1201 /* check for port connect status */
1202 val = readl(base + USB_PORTSC1);
1203 port_connected = val & USB_PORTSC1_CCS;
1204
1205 if (!port_connected)
1206 return;
1207
1208 port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) &
1209 HOSTPC1_DEVLC_PSPD_MASK;
1210 /*Set PMC MASTER bits to do the following
1211 * a. Take over the UTMI drivers
1212 * b. set up such that it will take over resume
1213 * if remote wakeup is detected
1214 * Prepare PMC to take over suspend-wake detect-drive resume until USB
1215 * controller ready
1216 */
1217
1218 /* disable master enable in PMC */
1219 val = readl(pmc_base + PMC_SLEEP_CFG);
1220 val &= ~UTMIP_MASTER_ENABLE(inst);
1221 writel(val, pmc_base + PMC_SLEEP_CFG);
1222
1223 /* UTMIP_PWR_PX=1 for power savings mode */
1224 val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG);
1225 val |= UTMIP_PWR(inst);
1226 writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG);
1227
1228 /* config debouncer */
1229 val = readl(pmc_base + PMC_USB_DEBOUNCE);
1230 val &= ~UTMIP_LINE_DEB_CNT(~0);
1231 val |= UTMIP_LINE_DEB_CNT(1);
1232 writel(val, pmc_base + PMC_USB_DEBOUNCE);
1233
1234 /* Make sure nothing is happening on the line with respect to PMC */
1235 val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE);
1236 val &= ~USBOP_VAL(inst);
1237 val &= ~USBON_VAL(inst);
1238 writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE);
1239
1240 /* Make sure wake value for line is none */
1241 val = readl(pmc_base + PMC_SLEEPWALK_CFG);
1242 val &= ~UTMIP_LINEVAL_WALK_EN(inst);
1243 writel(val, pmc_base + PMC_SLEEPWALK_CFG);
1244 val = readl(pmc_base + PMC_SLEEP_CFG);
1245 val &= ~UTMIP_WAKE_VAL(inst, ~0);
1246 val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE);
1247 writel(val, pmc_base + PMC_SLEEP_CFG);
1248
1249 /* turn off pad detectors */
1250 val = readl(pmc_base + PMC_USB_AO);
1251 val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst));
1252 writel(val, pmc_base + PMC_USB_AO);
1253
1254 /* Remove fake values and make synchronizers work a bit */
1255 val = readl(pmc_base + PMC_UTMIP_UHSIC_FAKE);
1256 val &= ~USBOP_VAL(inst);
1257 val &= ~USBON_VAL(inst);
1258 writel(val, pmc_base + PMC_UTMIP_UHSIC_FAKE);
1259
1260 /* Enable which type of event can trigger a walk,
1261 in this case usb_line_wake */
1262 val = readl(pmc_base + PMC_SLEEPWALK_CFG);
1263 val |= UTMIP_LINEVAL_WALK_EN(inst);
1264 writel(val, pmc_base + PMC_SLEEPWALK_CFG);
1265
1266 /* Enable which type of event can trigger a walk,
1267 * in this case usb_line_wake */
1268 val = readl(pmc_base + PMC_SLEEPWALK_CFG);
1269 val |= UTMIP_LINEVAL_WALK_EN(inst);
1270 writel(val, pmc_base + PMC_SLEEPWALK_CFG);
1271
1272 /* Clear the walk pointers and wake alarm */
1273 val = readl(pmc_base + PMC_TRIGGERS);
1274 val |= UTMIP_CLR_WAKE_ALARM(inst) | UTMIP_CLR_WALK_PTR(inst);
1275 writel(val, pmc_base + PMC_TRIGGERS);
1276
1277
1278 /* Capture FS/LS pad configurations */
1279 pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG);
1280 val = readl(pmc_base + PMC_TRIGGERS);
1281 val |= UTMIP_CAP_CFG(inst);
1282 writel(val, pmc_base + PMC_TRIGGERS);
1283 udelay(1);
1284 pmc_pad_cfg_val = readl(pmc_base + PMC_PAD_CFG);
1285
1286 /* BIAS MASTER_ENABLE=0 */
1287 val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
1288 val &= ~BIAS_MASTER_PROG_VAL;
1289 writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
1290
1291 /* program walk sequence, maintain a J, followed by a driven K
1292 * to signal a resume once an wake event is detected */
1293 val = readl(pmc_base + PMC_SLEEPWALK_REG(inst));
1294 val &= ~UTMIP_AP_A;
1295 val |= UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A| UTMIP_AN_A | UTMIP_HIGHZ_A |
1296 UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_AP_B |
1297 UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_AP_C |
1298 UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_AP_D;
1299 writel(val, pmc_base + PMC_SLEEPWALK_REG(inst));
1300
1301 if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) {
1302 val = readl(pmc_base + PMC_SLEEPWALK_REG(inst));
1303 val &= ~(UTMIP_AN_B | UTMIP_HIGHZ_B | UTMIP_AN_C |
1304 UTMIP_HIGHZ_C | UTMIP_AN_D | UTMIP_HIGHZ_D);
1305 writel(val, pmc_base + PMC_SLEEPWALK_REG(inst));
1306 } else {
1307 val = readl(pmc_base + PMC_SLEEPWALK_REG(inst));
1308 val &= ~(UTMIP_AP_B | UTMIP_HIGHZ_B | UTMIP_AP_C |
1309 UTMIP_HIGHZ_C | UTMIP_AP_D | UTMIP_HIGHZ_D);
1310 writel(val, pmc_base + PMC_SLEEPWALK_REG(inst));
1311 }
1312
1313 /* turn on pad detectors */
1314 val = readl(pmc_base + PMC_USB_AO);
1315 val &= ~(USBOP_VAL_PD(inst) | USBON_VAL_PD(inst));
1316 writel(val, pmc_base + PMC_USB_AO);
1317
1318 /* Add small delay before usb detectors provide stable line values */
1319 mdelay(1);
1320
1321 /* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */
1322 val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG);
1323 val = PMC_TCTRL_VAL(utmip_tctrl_val) | PMC_RCTRL_VAL(utmip_rctrl_val);
1324 writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG);
1325
1326 phy->remote_wakeup = false;
1327
1328 /* Turn over pad configuration to PMC for line wake events*/
1329 val = readl(pmc_base + PMC_SLEEP_CFG);
1330 val &= ~UTMIP_WAKE_VAL(inst, ~0);
1331 val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_ANY);
1332 val |= UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst);
1333 val |= UTMIP_MASTER_ENABLE(inst) | UTMIP_FSLS_USE_PMC(inst);
1334 writel(val, pmc_base + PMC_SLEEP_CFG);
1335
1336 val = readl(base + UTMIP_PMC_WAKEUP0);
1337 val |= EVENT_INT_ENB;
1338 writel(val, base + UTMIP_PMC_WAKEUP0);
1339}
1340#endif
1341
1342static int utmi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
1343{
1344 unsigned long val;
1345 void __iomem *base = phy->regs;
1346
1347#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1348 if (phy->mode == TEGRA_USB_PHY_MODE_HOST)
1349 utmip_setup_pmc_wake_detect(phy);
1350#endif
1351 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
1352 val = readl(base + USB_SUSP_CTRL);
1353 val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
1354 val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5);
1355 writel(val, base + USB_SUSP_CTRL);
1356 }
1357
1358 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
1359 val = readl(base + UTMIP_BAT_CHRG_CFG0);
1360 val |= UTMIP_PD_CHRG;
1361 writel(val, base + UTMIP_BAT_CHRG_CFG0);
1362 }
1363
1364 if (phy->instance != 2) {
1365 val = readl(base + UTMIP_XCVR_CFG0);
1366 val |= (UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
1367 UTMIP_FORCE_PDZI_POWERDOWN);
1368 writel(val, base + UTMIP_XCVR_CFG0);
1369 }
1370 val = readl(base + UTMIP_XCVR_CFG1);
1371 val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
1372 UTMIP_FORCE_PDDR_POWERDOWN;
1373 writel(val, base + UTMIP_XCVR_CFG1);
1374
1375#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1376 val = readl(base + UTMIP_BIAS_CFG1);
1377 val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
1378 writel(val, base + UTMIP_BIAS_CFG1);
1379#endif
1380
1381 if (phy->hotplug) {
1382 val = readl(base + USB_PORTSC1);
1383 val |= USB_PORTSC1_WKCN;
1384 writel(val, base + USB_PORTSC1);
1385 }
1386 if (phy->instance != 0) {
1387 val = readl(base + UTMIP_BIAS_CFG0);
1388 val |= UTMIP_OTGPD;
1389 writel(val, base + UTMIP_BIAS_CFG0);
1390 }
1391
1392 utmi_phy_clk_disable(phy);
1393
1394 utmip_pad_power_off(phy, true);
1395 return 0;
1396}
1397
1398static void utmip_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy)
1399{
1400#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1401 unsigned long val;
1402 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
1403 unsigned int inst = phy->instance;
1404 void __iomem *base = phy->regs;
1405
1406 val = readl(pmc_base + PMC_SLEEP_CFG);
1407 val &= ~UTMIP_WAKE_VAL(inst, 0x0);
1408 val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE);
1409 writel(val, pmc_base + PMC_SLEEP_CFG);
1410
1411 val = readl(pmc_base + PMC_TRIGGERS);
1412 val |= UTMIP_CLR_WAKE_ALARM(inst) | UTMIP_CLR_WALK_PTR(inst);
1413 writel(val, pmc_base + PMC_TRIGGERS);
1414
1415 val = readl(base + UTMIP_PMC_WAKEUP0);
1416 val &= ~EVENT_INT_ENB;
1417 writel(val, base + UTMIP_PMC_WAKEUP0);
1418
1419 /* Disable PMC master mode by clearing MASTER_EN */
1420 val = readl(pmc_base + PMC_SLEEP_CFG);
1421 val &= ~(UTMIP_RCTRL_USE_PMC(inst) | UTMIP_TCTRL_USE_PMC(inst) |
1422 UTMIP_FSLS_USE_PMC(inst) | UTMIP_MASTER_ENABLE(inst));
1423 writel(val, pmc_base + PMC_SLEEP_CFG);
1424
1425 val = readl(pmc_base + PMC_TRIGGERS);
1426 val &= ~UTMIP_CAP_CFG(inst);
1427 writel(val, pmc_base + PMC_TRIGGERS);
1428
1429 /* turn off pad detectors */
1430 val = readl(pmc_base + PMC_USB_AO);
1431 val |= (USBOP_VAL_PD(inst) | USBON_VAL_PD(inst));
1432 writel(val, pmc_base + PMC_USB_AO);
1433
1434 phy->remote_wakeup = false;
1435#endif
1436}
1437
1438static void utmi_phy_enable_obs_bus(struct tegra_usb_phy *phy,
1439 enum tegra_usb_phy_port_speed port_speed)
1440{
1441 unsigned long val;
1442 void __iomem *base = phy->regs;
1443
1444 /* (2LS WAR)is not required for LS and FS devices and is only for HS */
1445 if (port_speed != TEGRA_USB_PHY_PORT_SPEED_HIGH) {
1446 /* do not enable the OBS bus */
1447 val = readl(base + UTMIP_MISC_CFG0);
1448 val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
1449 writel(val, base + UTMIP_MISC_CFG0);
1450 return;
1451 }
1452 /* Force DP/DM pulldown active for Host mode */
1453 val = readl(base + UTMIP_MISC_CFG0);
1454 val |= FORCE_PULLDN_DM | FORCE_PULLDN_DP |
1455 COMB_TERMS | ALWAYS_FREE_RUNNING_TERMS;
1456 writel(val, base + UTMIP_MISC_CFG0);
1457 val = readl(base + UTMIP_MISC_CFG0);
1458 val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
1459 if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
1460 val |= UTMIP_DPDM_OBSERVE_SEL_FS_J;
1461 else
1462 val |= UTMIP_DPDM_OBSERVE_SEL_FS_K;
1463 writel(val, base + UTMIP_MISC_CFG0);
1464 udelay(1);
1465
1466 val = readl(base + UTMIP_MISC_CFG0);
1467 val |= UTMIP_DPDM_OBSERVE;
1468 writel(val, base + UTMIP_MISC_CFG0);
1469 udelay(10);
1470}
1471
1472static void utmi_phy_disable_obs_bus(struct tegra_usb_phy *phy)
1473{
1474 unsigned long val;
1475 void __iomem *base = phy->regs;
1476
1477 /* check if OBS bus is already enabled */
1478 val = readl(base + UTMIP_MISC_CFG0);
1479 if (val & UTMIP_DPDM_OBSERVE) {
1480 /* Change the UTMIP OBS bus to drive SE0 */
1481 val = readl(base + UTMIP_MISC_CFG0);
1482 val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
1483 val |= UTMIP_DPDM_OBSERVE_SEL_FS_SE0;
1484 writel(val, base + UTMIP_MISC_CFG0);
1485
1486 /* Wait for 3us(2 LS bit times) */
1487 udelay (3);
1488
1489 /* Release UTMIP OBS bus */
1490 val = readl(base + UTMIP_MISC_CFG0);
1491 val &= ~UTMIP_DPDM_OBSERVE;
1492 writel(val, base + UTMIP_MISC_CFG0);
1493
1494 /* Release DP/DM pulldown for Host mode */
1495 val = readl(base + UTMIP_MISC_CFG0);
1496 val &= ~(FORCE_PULLDN_DM | FORCE_PULLDN_DP |
1497 COMB_TERMS | ALWAYS_FREE_RUNNING_TERMS);
1498 writel(val, base + UTMIP_MISC_CFG0);
1499 }
1500}
1501
1502
1503static int utmi_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup)
1504{
1505#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1506 unsigned long val;
1507 void __iomem *base = phy->regs;
1508 enum tegra_usb_phy_port_speed port_speed;
1509
1510 val = readl(base + UTMIP_TX_CFG0);
1511 val |= UTMIP_HS_DISCON_DISABLE;
1512 writel(val, base + UTMIP_TX_CFG0);
1513
1514 port_speed = (readl(base + USB_PORTSC1) >> 26) & 0x3;
1515 utmi_phy_enable_obs_bus(phy, port_speed);
1516
1517#else
1518 unsigned long val;
1519 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
1520 unsigned int inst = phy->instance;
1521 void __iomem *base = phy->regs;
1522 enum tegra_usb_phy_port_speed port_speed;
1523
1524 val = readl(pmc_base + PMC_SLEEP_CFG);
1525 if (val & UTMIP_MASTER_ENABLE(inst)) {
1526 if (!remote_wakeup)
1527 utmip_phy_disable_pmc_bus_ctrl(phy);
1528 } else {
1529 port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) &
1530 HOSTPC1_DEVLC_PSPD_MASK;
1531 utmi_phy_enable_obs_bus(phy, port_speed);
1532 }
1533#endif
1534
1535 return 0;
1536}
1537
1538static int utmi_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
1539{
1540 unsigned long val;
1541 void __iomem *base = phy->regs;
1542 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
1543 unsigned int inst = phy->instance;
1544
1545#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1546 val = readl(pmc_base + PMC_SLEEP_CFG);
1547 /* if PMC is not disabled by now then disable it */
1548 if (val & UTMIP_MASTER_ENABLE(inst)) {
1549 utmip_phy_disable_pmc_bus_ctrl(phy);
1550 }
1551#else
1552 val = readl(base + UTMIP_TX_CFG0);
1553 val &= ~UTMIP_HS_DISCON_DISABLE;
1554 writel(val, base + UTMIP_TX_CFG0);
1555#endif
1556
1557 utmi_phy_disable_obs_bus(phy);
1558
1559 return 0;
1560}
1561
1562static int uhsic_phy_postsuspend(struct tegra_usb_phy *phy, bool is_dpd)
1563{
1564 struct tegra_uhsic_config *uhsic_config = phy->config;
1565
1566 if (uhsic_config->postsuspend)
1567 uhsic_config->postsuspend();
1568
1569 return 0;
1570}
1571
1572static int uhsic_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup)
1573{
1574 struct tegra_uhsic_config *uhsic_config = phy->config;
1575
1576 if (uhsic_config->preresume)
1577 uhsic_config->preresume();
1578
1579 return 0;
1580}
1581
1582static int uhsic_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
1583{
1584 unsigned long val;
1585 void __iomem *base = phy->regs;
1586
1587 val = readl(base + USB_TXFILLTUNING);
1588 if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) {
1589 val = USB_FIFO_TXFILL_THRES(0x10);
1590 writel(val, base + USB_TXFILLTUNING);
1591 }
1592
1593 return 0;
1594}
1595
1596static void utmi_phy_restore_start(struct tegra_usb_phy *phy,
1597 enum tegra_usb_phy_port_speed port_speed)
1598{
1599#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1600 unsigned long val;
1601 void __iomem *base = phy->regs;
1602
1603 val = readl(base + UTMIP_MISC_CFG0);
1604 val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
1605 if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
1606 val |= UTMIP_DPDM_OBSERVE_SEL_FS_K;
1607 else
1608 val |= UTMIP_DPDM_OBSERVE_SEL_FS_J;
1609 writel(val, base + UTMIP_MISC_CFG0);
1610 udelay(1);
1611
1612 val = readl(base + UTMIP_MISC_CFG0);
1613 val |= UTMIP_DPDM_OBSERVE;
1614 writel(val, base + UTMIP_MISC_CFG0);
1615 udelay(10);
1616#else
1617 unsigned long val;
1618 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
1619 int inst = phy->instance;
1620
1621 val = readl(pmc_base + UTMIP_UHSIC_STATUS);
1622 /* check whether we wake up from the remote resume */
1623 if (UTMIP_WALK_PTR_VAL(inst) & val) {
1624 phy->remote_wakeup = true;
1625 } else {
1626 if (!((UTMIP_USBON_VAL(phy->instance) |
1627 UTMIP_USBOP_VAL(phy->instance)) & val)) {
1628 utmip_phy_disable_pmc_bus_ctrl(phy);
1629 }
1630 }
1631 utmi_phy_enable_obs_bus(phy, port_speed);
1632#endif
1633}
1634
1635static void utmi_phy_restore_end(struct tegra_usb_phy *phy)
1636{
1637#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1638 unsigned long val;
1639 void __iomem *base = phy->regs;
1640
1641 val = readl(base + UTMIP_MISC_CFG0);
1642 val &= ~UTMIP_DPDM_OBSERVE;
1643 writel(val, base + UTMIP_MISC_CFG0);
1644 udelay(10);
1645#else
1646 unsigned long val;
1647 void __iomem *base = phy->regs;
1648 int wait_time_us = 3000; /* FPR should be set by this time */
1649
1650 /* check whether we wake up from the remote resume */
1651 if (phy->remote_wakeup) {
1652 /* wait until FPR bit is set automatically on remote resume */
1653 do {
1654 val = readl(base + USB_PORTSC1);
1655 udelay(1);
1656 if (wait_time_us == 0) {
1657 utmip_phy_disable_pmc_bus_ctrl(phy);
1658 tegra_usb_phy_postresume(phy, false);
1659 return;
1660 }
1661 wait_time_us--;
1662 } while (!(val & USB_PORTSC1_RESUME));
1663 /* wait for 25 ms to port resume complete */
1664 msleep(25);
1665 /* disable PMC master control */
1666 utmip_phy_disable_pmc_bus_ctrl(phy);
1667
1668 /* Clear PCI and SRI bits to avoid an interrupt upon resume */
1669 val = readl(base + USB_USBSTS);
1670 writel(val, base + USB_USBSTS);
1671 /* wait to avoid SOF if there is any */
1672 if (utmi_wait_register(base + USB_USBSTS,
1673 USB_USBSTS_SRI, USB_USBSTS_SRI) < 0) {
1674 pr_err("%s: timeout waiting for SOF\n", __func__);
1675 }
1676 tegra_usb_phy_postresume(phy, false);
1677 }
1678#endif
1679}
1680
1681#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1682static void ulpi_set_tristate(bool enable)
1683{
1684 int tristate = (enable)? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
1685
1686 tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
1687 tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
1688 tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
1689}
1690#endif
1691
1692static void ulpi_phy_reset(void __iomem *base)
1693{
1694 unsigned long val;
1695
1696 val = readl(base + USB_SUSP_CTRL);
1697 val |= UHSIC_RESET;
1698 writel(val, base + USB_SUSP_CTRL);
1699
1700#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1701 val = readl(base + USB_SUSP_CTRL);
1702 val |= UTMIP_RESET;
1703 writel(val, base + USB_SUSP_CTRL);
1704#endif
1705}
1706
1707static void ulpi_set_host(void __iomem *base)
1708{
1709#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1710 unsigned long val;
1711
1712 val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET);
1713 val |= TEGRA_USB_USBMODE_HOST;
1714 writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET);
1715
1716 val = readl(base + HOSTPC1_DEVLC);
1717 val |= HOSTPC1_DEVLC_PTS(2);
1718 writel(val, base + HOSTPC1_DEVLC);
1719#endif
1720}
1721
1722static void ulpi_set_trimmer(void __iomem *base, u8 data, u8 sdn, u8 dir)
1723{
1724 unsigned long val;
1725
1726 val = ULPI_DATA_TRIMMER_SEL(data);
1727 val |= ULPI_STPDIRNXT_TRIMMER_SEL(sdn);
1728 val |= ULPI_DIR_TRIMMER_SEL(dir);
1729 writel(val, base + ULPI_TIMING_CTRL_1);
1730 udelay(10);
1731
1732 val |= ULPI_DATA_TRIMMER_LOAD;
1733 val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
1734 val |= ULPI_DIR_TRIMMER_LOAD;
1735 writel(val, base + ULPI_TIMING_CTRL_1);
1736}
1737
1738static inline void ulpi_pinmux_bypass(struct tegra_usb_phy *phy, bool enable)
1739{
1740 unsigned long val;
1741 void __iomem *base = phy->regs;
1742
1743 val = readl(base + ULPI_TIMING_CTRL_0);
1744
1745 if (enable)
1746 val |= ULPI_OUTPUT_PINMUX_BYP;
1747 else
1748 val &= ~ULPI_OUTPUT_PINMUX_BYP;
1749
1750 writel(val, base + ULPI_TIMING_CTRL_0);
1751}
1752
1753static void ulpi_phy_restore_start(struct tegra_usb_phy *phy,
1754 enum tegra_usb_phy_port_speed port_speed)
1755{
1756#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1757 unsigned long val;
1758 void __iomem *base = phy->regs;
1759
1760 /*Tristate ulpi interface before USB controller resume*/
1761 ulpi_set_tristate(true);
1762
1763 val = readl(base + ULPI_TIMING_CTRL_0);
1764 val &= ~ULPI_OUTPUT_PINMUX_BYP;
1765 writel(val, base + ULPI_TIMING_CTRL_0);
1766#endif
1767}
1768
1769static void ulpi_phy_restore_end(struct tegra_usb_phy *phy)
1770{
1771#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1772 unsigned long val;
1773 void __iomem *base = phy->regs;
1774
1775 val = readl(base + ULPI_TIMING_CTRL_0);
1776 val |= ULPI_OUTPUT_PINMUX_BYP;
1777 writel(val, base + ULPI_TIMING_CTRL_0);
1778
1779 ulpi_set_tristate(false);
1780#endif
1781}
1782
1783static int ulpi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
1784{
1785 int ret;
1786 unsigned long val;
1787 void __iomem *base = phy->regs;
1788#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1789 struct tegra_ulpi_config *config = phy->config;
1790#endif
1791
1792 if (phy->clk)
1793 clk_enable(phy->clk);
1794
1795 msleep(1);
1796
1797 if (!phy->initialized) {
1798 phy->initialized = 1;
1799#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1800 gpio_direction_output(config->reset_gpio, 0);
1801 msleep(5);
1802 gpio_direction_output(config->reset_gpio, 1);
1803#endif
1804 }
1805
1806 ulpi_phy_reset(base);
1807 ulpi_set_host(base);
1808
1809 val = readl(base + ULPI_TIMING_CTRL_0);
1810 val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
1811 writel(val, base + ULPI_TIMING_CTRL_0);
1812
1813 val = readl(base + USB_SUSP_CTRL);
1814 val |= ULPI_PHY_ENABLE;
1815 writel(val, base + USB_SUSP_CTRL);
1816
1817 val = readl(base + USB_SUSP_CTRL);
1818 val |= USB_SUSP_CLR;
1819 writel(val, base + USB_SUSP_CTRL);
1820
1821#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1822 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
1823 USB_PHY_CLK_VALID) < 0)
1824 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
1825
1826 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_CLKEN, USB_CLKEN) < 0)
1827 pr_err("%s: timeout waiting for AHB clock\n", __func__);
1828#else
1829 udelay(100);
1830#endif
1831
1832 val = readl(base + USB_SUSP_CTRL);
1833 val &= ~USB_SUSP_CLR;
1834 writel(val, base + USB_SUSP_CTRL);
1835
1836 val = 0;
1837 writel(val, base + ULPI_TIMING_CTRL_1);
1838
1839 ulpi_set_trimmer(base, 4, 4, 4);
1840
1841 /* Fix VbusInvalid due to floating VBUS */
1842 ret = otg_io_write(phy->ulpi, 0x40, 0x08);
1843 if (ret) {
1844 pr_err("%s: ulpi write failed\n", __func__);
1845 return ret;
1846 }
1847
1848 ret = otg_io_write(phy->ulpi, 0x80, 0x0B);
1849 if (ret) {
1850 pr_err("%s: ulpi write failed\n", __func__);
1851 return ret;
1852 }
1853
1854 val = readl(base + USB_PORTSC1);
1855 val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
1856 writel(val, base + USB_PORTSC1);
1857
1858 return 0;
1859}
1860
1861static int ulpi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
1862{
1863 unsigned long val;
1864 void __iomem *base = phy->regs;
1865#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1866 int ret;
1867
1868 /* Disable VbusValid, SessEnd comparators */
1869 ret = otg_io_write(phy->ulpi, 0x00, 0x0D);
1870 if (ret)
1871 pr_err("%s: ulpi write 0x0D failed\n", __func__);
1872
1873 ret = otg_io_write(phy->ulpi, 0x00, 0x10);
1874 if (ret)
1875 pr_err("%s: ulpi write 0x10 failed\n", __func__);
1876
1877 /* Disable IdFloat comparator */
1878 ret = otg_io_write(phy->ulpi, 0x00, 0x19);
1879 if (ret)
1880 pr_err("%s: ulpi write 0x19 failed\n", __func__);
1881
1882 ret = otg_io_write(phy->ulpi, 0x00, 0x1D);
1883 if (ret)
1884 pr_err("%s: ulpi write 0x1D failed\n", __func__);
1885
1886 /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB
1887 * Controller to immediately bring the ULPI PHY out of low power
1888 */
1889 val = readl(base + USB_PORTSC1);
1890 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
1891 writel(val, base + USB_PORTSC1);
1892
1893 /* Put the PHY in the low power mode */
1894 val = readl(base + USB_PORTSC1);
1895 val |= USB_PORTSC1_PHCD;
1896 writel(val, base + USB_PORTSC1);
1897
1898 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
1899 pr_err("%s: timeout waiting for phy to stop\n", __func__);
1900#else
1901 val = readl(base + HOSTPC1_DEVLC);
1902 val &= ~(HOSTPC1_DEVLC_PHCD);
1903 writel(val, base + HOSTPC1_DEVLC);
1904#endif
1905
1906 if(phy->clk)
1907 clk_disable(phy->clk);
1908
1909 return 0;
1910}
1911
1912static inline void null_phy_set_tristate(bool enable)
1913{
1914 int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
1915
1916#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1917 tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
1918 tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
1919 tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
1920#else
1921 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate);
1922 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate);
1923 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA2, tristate);
1924 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA3, tristate);
1925 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA4, tristate);
1926 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA5, tristate);
1927 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA6, tristate);
1928 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA7, tristate);
1929 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_NXT, tristate);
1930
1931 if (enable)
1932 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, tristate);
1933#endif
1934}
1935
1936static void null_phy_restore_start(struct tegra_usb_phy *phy,
1937 enum tegra_usb_phy_port_speed port_speed)
1938{
1939 struct tegra_ulpi_config *config = phy->config;
1940
1941 if (config->phy_restore_start)
1942 config->phy_restore_start();
1943}
1944
1945static void null_phy_restore_end(struct tegra_usb_phy *phy)
1946{
1947 unsigned long val;
1948 void __iomem *base = phy->regs;
1949 struct tegra_ulpi_config *config = phy->config;
1950
1951 /* disable ULPI pinmux bypass */
1952 ulpi_pinmux_bypass(phy, false);
1953
1954 /* driving linestate using GPIO */
1955 gpio_set_value(config->ulpi_d0_gpio, 0);
1956 gpio_set_value(config->ulpi_d1_gpio, 0);
1957
1958#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1959 /* driving DIR high */
1960 gpio_set_value(config->ulpi_dir_gpio, 1);
1961#endif
1962
1963 /* remove ULPI tristate */
1964 null_phy_set_tristate(false);
1965
1966 if (config->phy_restore_end)
1967 config->phy_restore_end();
1968
1969 if (gpio_is_valid(config->phy_restore_gpio)) {
1970 int phy_restore_gpio = config->phy_restore_gpio;
1971 int retry = 20000;
1972
1973 while (retry) {
1974 /* poll phy_restore_gpio high */
1975 if (gpio_get_value(phy_restore_gpio))
1976 break;
1977 retry--;
1978 }
1979
1980 if (retry == 0)
1981 pr_info("phy_restore_gpio timeout\n");
1982 }
1983
1984 /* enable ULPI CLK output pad */
1985 val = readl(base + ULPI_TIMING_CTRL_0);
1986 val |= ULPI_CLK_PADOUT_ENA;
1987 writel(val, base + ULPI_TIMING_CTRL_0);
1988
1989#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1990 udelay(5); /* wait for CLK stabilize */
1991
1992 /* enable ULPI pinmux bypass */
1993 ulpi_pinmux_bypass(phy, true);
1994#else
1995 /* enable ULPI pinmux bypass */
1996 ulpi_pinmux_bypass(phy, true);
1997 udelay(5);
1998
1999 /* remove DIR tristate */
2000 tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, TEGRA_TRI_NORMAL);
2001#endif
2002}
2003
2004static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
2005{
2006 const struct tegra_ulpi_trimmer default_trimmer = {0, 0, 4, 4};
2007 unsigned long val;
2008 void __iomem *base = phy->regs;
2009 struct tegra_ulpi_config *config = phy->config;
2010 static bool cold_boot = true;
2011
2012 if (!config->trimmer)
2013 config->trimmer = &default_trimmer;
2014
2015 ulpi_phy_reset(base);
2016
2017#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2018 /* remove ULPI PADS CLKEN reset */
2019 val = readl(base + USB_SUSP_CTRL);
2020 val &= ~ULPI_PADS_CLKEN_RESET;
2021 writel(val, base + USB_SUSP_CTRL);
2022 udelay(10);
2023#endif
2024 val = readl(base + ULPI_TIMING_CTRL_0);
2025 val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
2026 writel(val, base + ULPI_TIMING_CTRL_0);
2027
2028 if (config->pre_phy_on && config->pre_phy_on())
2029 return -EAGAIN;
2030
2031 val = readl(base + USB_SUSP_CTRL);
2032 val |= ULPI_PHY_ENABLE;
2033 writel(val, base + USB_SUSP_CTRL);
2034 udelay(10);
2035
2036 /* set timming parameters */
2037 val = readl(base + ULPI_TIMING_CTRL_0);
2038 val |= ULPI_SHADOW_CLK_LOOPBACK_EN;
2039#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2040 val &= ~ULPI_SHADOW_CLK_SEL;
2041 val &= ~ULPI_LBK_PAD_EN;
2042#else
2043 val |= ULPI_SHADOW_CLK_SEL;
2044 val |= ULPI_LBK_PAD_EN;
2045#endif
2046 val |= ULPI_SHADOW_CLK_DELAY(config->trimmer->shadow_clk_delay);
2047 val |= ULPI_CLOCK_OUT_DELAY(config->trimmer->clock_out_delay);
2048 val |= ULPI_LBK_PAD_E_INPUT_OR;
2049 writel(val, base + ULPI_TIMING_CTRL_0);
2050
2051 writel(0, base + ULPI_TIMING_CTRL_1);
2052 udelay(10);
2053
2054 /* start internal 60MHz clock */
2055 val = readl(base + ULPIS2S_CTRL);
2056 val |= ULPIS2S_ENA;
2057 val |= ULPIS2S_SUPPORT_DISCONNECT;
2058 val |= ULPIS2S_SPARE((phy->mode == TEGRA_USB_PHY_MODE_HOST) ? 3 : 1);
2059 val |= ULPIS2S_PLLU_MASTER_BLASTER60;
2060 writel(val, base + ULPIS2S_CTRL);
2061
2062 /* select ULPI_CORE_CLK_SEL to SHADOW_CLK */
2063 val = readl(base + ULPI_TIMING_CTRL_0);
2064 val |= ULPI_CORE_CLK_SEL;
2065 writel(val, base + ULPI_TIMING_CTRL_0);
2066 udelay(10);
2067
2068 /* enable ULPI null phy clock - can't set the trimmers before this */
2069 val = readl(base + ULPI_TIMING_CTRL_0);
2070 val |= ULPI_CLK_OUT_ENA;
2071 writel(val, base + ULPI_TIMING_CTRL_0);
2072 udelay(10);
2073
2074 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
2075 USB_PHY_CLK_VALID)) {
2076 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
2077 return -ETIMEDOUT;
2078 }
2079
2080 /* set ULPI trimmers */
2081 ulpi_set_trimmer(base, config->trimmer->data_trimmer,
2082 config->trimmer->stpdirnxt_trimmer, 1);
2083
2084 ulpi_set_host(base);
2085
2086#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2087 /* remove slave0 reset */
2088 val = readl(base + USB_SUSP_CTRL);
2089 val &= ~ULPIS2S_SLV0_RESET;
2090 writel(val, base + USB_SUSP_CTRL);
2091
2092 /* remove slave1 and line reset */
2093 val = readl(base + USB_SUSP_CTRL);
2094 val &= ~ULPIS2S_SLV1_RESET;
2095 val &= ~ULPIS2S_LINE_RESET;
2096
2097 /* remove ULPI PADS reset */
2098 val &= ~ULPI_PADS_RESET;
2099 writel(val, base + USB_SUSP_CTRL);
2100#endif
2101 if (cold_boot) {
2102 val = readl(base + ULPI_TIMING_CTRL_0);
2103 val |= ULPI_CLK_PADOUT_ENA;
2104 writel(val, base + ULPI_TIMING_CTRL_0);
2105 cold_boot = false;
2106 }
2107
2108 udelay(10);
2109
2110 if (config->post_phy_on && config->post_phy_on())
2111 return -EAGAIN;
2112
2113 return 0;
2114}
2115
2116static int null_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
2117{
2118 struct tegra_ulpi_config *config = phy->config;
2119
2120 if (config->pre_phy_off && config->pre_phy_off())
2121 return -EAGAIN;
2122
2123 null_phy_set_tristate(true);
2124
2125 if (config->post_phy_off && config->post_phy_off())
2126 return -EAGAIN;
2127
2128 return 0;
2129}
2130
2131static int null_phy_pre_usbcmd_reset(struct tegra_usb_phy *phy, bool is_dpd)
2132{
2133#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2134 unsigned long val;
2135 void __iomem *base = phy->regs;
2136
2137 val = readl(base + ULPIS2S_CTRL);
2138 val |= ULPIS2S_SLV0_CLAMP_XMIT;
2139 writel(val, base + ULPIS2S_CTRL);
2140
2141 val = readl(base + USB_SUSP_CTRL);
2142 val |= ULPIS2S_SLV0_RESET;
2143 writel(val, base + USB_SUSP_CTRL);
2144 udelay(10);
2145#endif
2146 return 0;
2147}
2148
2149static int null_phy_post_usbcmd_reset(struct tegra_usb_phy *phy, bool is_dpd)
2150{
2151#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2152 unsigned long val;
2153 void __iomem *base = phy->regs;
2154
2155 ulpi_set_host(base);
2156
2157 /* remove slave0 reset */
2158 val = readl(base + USB_SUSP_CTRL);
2159 val &= ~ULPIS2S_SLV0_RESET;
2160 writel(val, base + USB_SUSP_CTRL);
2161
2162 val = readl(base + ULPIS2S_CTRL);
2163 val &= ~ULPIS2S_SLV0_CLAMP_XMIT;
2164 writel(val, base + ULPIS2S_CTRL);
2165 udelay(10);
2166#endif
2167 return 0;
2168}
2169
2170static int uhsic_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
2171{
2172 unsigned long val;
2173 void __iomem *base = phy->regs;
2174 struct tegra_uhsic_config *uhsic_config = phy->config;
2175
2176 if (uhsic_config->enable_gpio != -1) {
2177 gpio_set_value_cansleep(uhsic_config->enable_gpio, 1);
2178 /* keep hsic reset asserted for 1 ms */
2179 udelay(1000);
2180 }
2181
2182 val = readl(base + UHSIC_PADS_CFG1);
2183 val &= ~(UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX |
2184 UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE);
2185 val |= UHSIC_RX_SEL;
2186 writel(val, base + UHSIC_PADS_CFG1);
2187 udelay(2);
2188
2189 val = readl(base + USB_SUSP_CTRL);
2190 val |= UHSIC_RESET;
2191 writel(val, base + USB_SUSP_CTRL);
2192 udelay(30);
2193
2194 val = readl(base + USB_SUSP_CTRL);
2195 val |= UHSIC_PHY_ENABLE;
2196 writel(val, base + USB_SUSP_CTRL);
2197
2198 val = readl(base + UHSIC_HSRX_CFG0);
2199 val |= UHSIC_IDLE_WAIT(uhsic_config->idle_wait_delay);
2200 val |= UHSIC_ELASTIC_UNDERRUN_LIMIT(uhsic_config->elastic_underrun_limit);
2201 val |= UHSIC_ELASTIC_OVERRUN_LIMIT(uhsic_config->elastic_overrun_limit);
2202 writel(val, base + UHSIC_HSRX_CFG0);
2203
2204 val = readl(base + UHSIC_HSRX_CFG1);
2205 val |= UHSIC_HS_SYNC_START_DLY(uhsic_config->sync_start_delay);
2206 writel(val, base + UHSIC_HSRX_CFG1);
2207
2208#ifdef CONFIG_ARCH_TEGRA_3x_SOC
2209 /* WAR HSIC TX */
2210 val = readl(base + UHSIC_TX_CFG0);
2211 val &= ~UHSIC_HS_READY_WAIT_FOR_VALID;
2212 writel(val, base + UHSIC_TX_CFG0);
2213#endif
2214
2215 val = readl(base + UHSIC_MISC_CFG0);
2216 val |= UHSIC_SUSPEND_EXIT_ON_EDGE;
2217#ifdef CONFIG_ARCH_TEGRA_3x_SOC
2218 /* Disable generic bus reset, to allow AP30 specific bus reset*/
2219 val |= UHSIC_DISABLE_BUSRESET;
2220#endif
2221 writel(val, base + UHSIC_MISC_CFG0);
2222
2223 val = readl(base + UHSIC_MISC_CFG1);
2224 val |= UHSIC_PLLU_STABLE_COUNT(phy->freq->stable_count);
2225 writel(val, base + UHSIC_MISC_CFG1);
2226
2227 val = readl(base + UHSIC_PLL_CFG1);
2228 val |= UHSIC_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
2229 val |= UHSIC_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count);
2230 writel(val, base + UHSIC_PLL_CFG1);
2231
2232 val = readl(base + USB_SUSP_CTRL);
2233 val &= ~(UHSIC_RESET);
2234 writel(val, base + USB_SUSP_CTRL);
2235 udelay(2);
2236
2237#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2238 val = readl(base + USB_PORTSC1);
2239 val &= ~USB_PORTSC1_PTS(~0);
2240 writel(val, base + USB_PORTSC1);
2241
2242#endif
2243#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2244 val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET);
2245 val |= TEGRA_USB_USBMODE_HOST;
2246 writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET);
2247
2248 /* Change the USB controller PHY type to HSIC */
2249 val = readl(base + HOSTPC1_DEVLC);
2250 val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK);
2251 val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
2252 val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
2253 val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
2254 writel(val, base + HOSTPC1_DEVLC);
2255#endif
2256 val = readl(base + USB_TXFILLTUNING);
2257 if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) {
2258 val = USB_FIFO_TXFILL_THRES(0x10);
2259 writel(val, base + USB_TXFILLTUNING);
2260 }
2261
2262 val = readl(base + USB_PORTSC1);
2263 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
2264 writel(val, base + USB_PORTSC1);
2265
2266 val = readl(base + UHSIC_PADS_CFG0);
2267 val &= ~(UHSIC_TX_RTUNEN);
2268#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2269 /* set Rtune impedance to 40 ohm */
2270 val |= UHSIC_TX_RTUNE(0);
2271#else
2272 /* set Rtune impedance to 50 ohm */
2273 val |= UHSIC_TX_RTUNE(8);
2274#endif
2275 writel(val, base + UHSIC_PADS_CFG0);
2276
2277 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
2278 USB_PHY_CLK_VALID)) {
2279 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
2280 return -ETIMEDOUT;
2281 }
2282
2283 return 0;
2284}
2285
2286static int uhsic_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
2287{
2288 unsigned long val;
2289 void __iomem *base = phy->regs;
2290 struct tegra_uhsic_config *uhsic_config = phy->config;
2291
2292 val = readl(base + UHSIC_PADS_CFG1);
2293 val &= ~UHSIC_RPU_STROBE;
2294 val |= UHSIC_RPD_STROBE;
2295 writel(val, base + UHSIC_PADS_CFG1);
2296
2297 val = readl(base + USB_SUSP_CTRL);
2298 val |= UHSIC_RESET;
2299 writel(val, base + USB_SUSP_CTRL);
2300 udelay(30);
2301
2302 if (uhsic_config->enable_gpio != -1) {
2303 gpio_set_value_cansleep(uhsic_config->enable_gpio, 0);
2304 /* keep hsic reset de-asserted for 1 ms */
2305 udelay(1000);
2306 }
2307 if (uhsic_config->post_phy_off && uhsic_config->post_phy_off())
2308 return -EAGAIN;
2309
2310 return 0;
2311}
2312
2313#ifdef CONFIG_USB_TEGRA_OTG
2314extern void tegra_otg_check_vbus_detection(void);
2315#endif
2316
2317static irqreturn_t usb_phy_vbus_irq_thr(int irq, void *pdata)
2318{
2319 struct tegra_usb_phy *phy = pdata;
2320
2321 if (phy->reg_vdd && !phy->regulator_on) {
2322 regulator_enable(phy->reg_vdd);
2323 phy->regulator_on = 1;
2324 /*
2325 * Optimal time to get the regulator turned on
2326 * before detecting vbus interrupt.
2327 */
2328 mdelay(15);
2329 }
2330
2331#ifdef CONFIG_USB_TEGRA_OTG
2332 tegra_otg_check_vbus_detection();
2333#endif
2334
2335 return IRQ_HANDLED;
2336}
2337
2338struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
2339 void *config, enum tegra_usb_phy_mode phy_mode,
2340 enum tegra_usb_phy_type usb_phy_type)
2341{
2342 struct tegra_usb_phy *phy;
2343 struct tegra_ulpi_config *ulpi_config;
2344 unsigned long parent_rate;
2345 int i;
2346 int err;
2347#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2348 struct tegra_ulpi_config *uhsic_config;
2349 int reset_gpio, enable_gpio;
2350#endif
2351
2352 phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
2353 if (!phy)
2354 return ERR_PTR(-ENOMEM);
2355
2356 phy->instance = instance;
2357 phy->regs = regs;
2358 phy->config = config;
2359 phy->mode = phy_mode;
2360 phy->usb_phy_type = usb_phy_type;
2361 phy->initialized = 0;
2362 phy->regulator_on = 0;
2363 phy->power_on = 0;
2364 phy->remote_wakeup = false;
2365 phy->hotplug = 0;
2366 phy->xcvr_setup_value = 0;
2367
2368 if (!phy->config) {
2369 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_LINK_ULPI ||
2370 phy->usb_phy_type == TEGRA_USB_PHY_TYPE_NULL_ULPI) {
2371 pr_err("%s: ulpi phy configuration missing", __func__);
2372 err = -EINVAL;
2373 goto err0;
2374 } else {
2375 phy->config = &utmip_default[instance];
2376 }
2377 }
2378
2379 phy->pll_u = clk_get_sys(NULL, "pll_u");
2380 if (IS_ERR(phy->pll_u)) {
2381 pr_err("Can't get pll_u clock\n");
2382 err = PTR_ERR(phy->pll_u);
2383 goto err0;
2384 }
2385 clk_enable(phy->pll_u);
2386
2387 parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
2388 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
2389 for (i = 0; i < ARRAY_SIZE(tegra_uhsic_freq_table); i++) {
2390 if (tegra_uhsic_freq_table[i].freq == parent_rate) {
2391 phy->freq = &tegra_uhsic_freq_table[i];
2392 break;
2393 }
2394 }
2395 } else {
2396 for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) {
2397 if (tegra_freq_table[i].freq == parent_rate) {
2398 phy->freq = &tegra_freq_table[i];
2399 break;
2400 }
2401 }
2402 }
2403 if (!phy->freq) {
2404 pr_err("invalid pll_u parent rate %ld\n", parent_rate);
2405 err = -EINVAL;
2406 goto err1;
2407 }
2408
2409 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) {
2410 err = utmip_pad_open(phy);
2411 phy->xcvr_setup_value = tegra_phy_xcvr_setup_value(phy->config);
2412 if (err < 0)
2413 goto err1;
2414 } else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_LINK_ULPI) {
2415 ulpi_config = config;
2416
2417 if (ulpi_config->clk) {
2418 phy->clk = clk_get_sys(NULL, ulpi_config->clk);
2419 if (IS_ERR(phy->clk)) {
2420 pr_err("%s: can't get ulpi clock\n", __func__);
2421 err = -ENXIO;
2422 goto err1;
2423 }
2424 } else {
2425 /* Some USB ULPI chips are not driven by Tegra clocks or PLL */
2426 phy->clk = NULL;
2427 }
2428 tegra_gpio_enable(ulpi_config->reset_gpio);
2429 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
2430 gpio_direction_output(ulpi_config->reset_gpio, 0);
2431 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
2432 phy->ulpi->io_priv = regs + ULPI_VIEWPORT;
2433 }
2434#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2435 else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
2436 uhsic_config = config;
2437 enable_gpio = gpio_request(uhsic_config->enable_gpio,
2438 "uhsic_enable");
2439 reset_gpio = gpio_request(uhsic_config->reset_gpio,
2440 "uhsic_reset");
2441 /* hsic enable signal deasserted, hsic reset asserted */
2442 if (!enable_gpio)
2443 gpio_direction_output(uhsic_config->enable_gpio,
2444 0 /* deasserted */);
2445 if (!reset_gpio)
2446 gpio_direction_output(uhsic_config->reset_gpio,
2447 0 /* asserted */);
2448 if (!enable_gpio)
2449 tegra_gpio_enable(uhsic_config->enable_gpio);
2450 if (!reset_gpio)
2451 tegra_gpio_enable(uhsic_config->reset_gpio);
2452 /* keep hsic reset asserted for 1 ms */
2453 udelay(1000);
2454 /* enable (power on) hsic */
2455 if (!enable_gpio)
2456 gpio_set_value_cansleep(uhsic_config->enable_gpio, 1);
2457 udelay(1000);
2458 /* deassert reset */
2459 if (!reset_gpio)
2460 gpio_set_value_cansleep(uhsic_config->reset_gpio, 1);
2461 }
2462#endif
2463
2464 phy->reg_vdd = regulator_get(NULL, "avdd_usb");
2465 if (IS_ERR_OR_NULL(phy->reg_vdd)) {
2466 pr_err("couldn't get regulator avdd_usb: %ld \n",
2467 PTR_ERR(phy->reg_vdd));
2468 phy->reg_vdd = NULL;
2469 }
2470
2471 if (instance == 0 && usb_phy_data[0].vbus_irq) {
2472 err = request_threaded_irq(usb_phy_data[0].vbus_irq, NULL, usb_phy_vbus_irq_thr, IRQF_SHARED,
2473 "usb_phy_vbus", phy);
2474 if (err) {
2475 pr_err("Failed to register IRQ\n");
2476 goto err1;
2477 }
2478 }
2479
2480#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2481 /* Power-up the VBUS detector for UTMIP PHY */
2482 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) {
2483 writel(readl((IO_ADDRESS(TEGRA_PMC_BASE) + TEGRA_PMC_USB_AO)) &
2484 ~(TEGRA_PMC_USB_AO_VBUS_WAKEUP_PD_P0 | TEGRA_PMC_USB_AO_ID_PD_P0),
2485 (IO_ADDRESS(TEGRA_PMC_BASE) + TEGRA_PMC_USB_AO));
2486
2487 if (usb_phy_data[phy->instance].vbus_reg_supply) {
2488 phy->reg_vbus = regulator_get(NULL, usb_phy_data[phy->instance].vbus_reg_supply);
2489 if (WARN_ON(IS_ERR_OR_NULL(phy->reg_vbus))) {
2490 pr_err("couldn't get regulator vdd_vbus_usb: %ld, instance : %d\n",
2491 PTR_ERR(phy->reg_vbus), phy->instance);
2492 err = PTR_ERR(phy->reg_vbus);
2493 goto err1;
2494 }
2495 }
2496 }
2497 if (instance == 2) {
2498 writel(readl((IO_ADDRESS(TEGRA_PMC_BASE) + TEGRA_PMC_USB_AO)) &
2499 (TEGRA_PMC_USB_AO_PD_P2),
2500 (IO_ADDRESS(TEGRA_PMC_BASE) + TEGRA_PMC_USB_AO));
2501 }
2502#endif
2503 if (((instance == 2) || (instance == 0)) &&
2504 (phy->mode == TEGRA_USB_PHY_MODE_HOST)) {
2505 vbus_enable(phy);
2506 }
2507 return phy;
2508
2509err1:
2510 clk_disable(phy->pll_u);
2511 clk_put(phy->pll_u);
2512err0:
2513 kfree(phy);
2514 return ERR_PTR(err);
2515}
2516
2517int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
2518{
2519 int ret = 0;
2520
2521 const tegra_phy_fp power_on[] = {
2522 utmi_phy_power_on,
2523 ulpi_phy_power_on,
2524 null_phy_power_on,
2525 uhsic_phy_power_on,
2526 };
2527
2528 if (phy->power_on)
2529 return ret;
2530
2531 if ((phy->instance == 0) && usb_phy_data[0].vbus_irq &&
2532 (phy->mode == TEGRA_USB_PHY_MODE_DEVICE))
2533 is_dpd = true;
2534
2535 if (phy->reg_vdd && !phy->regulator_on) {
2536 regulator_enable(phy->reg_vdd);
2537 phy->regulator_on = 1;
2538 }
2539
2540 if (power_on[phy->usb_phy_type])
2541 ret = power_on[phy->usb_phy_type](phy, is_dpd);
2542
2543 phy->power_on = true;
2544 return ret;
2545}
2546
2547void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
2548{
2549 const tegra_phy_fp power_off[] = {
2550 utmi_phy_power_off,
2551 ulpi_phy_power_off,
2552 null_phy_power_off,
2553 uhsic_phy_power_off,
2554 };
2555
2556 if (!phy->power_on)
2557 return;
2558
2559 if ((phy->instance == 0) && usb_phy_data[0].vbus_irq &&
2560 (phy->mode == TEGRA_USB_PHY_MODE_DEVICE))
2561 is_dpd = true;
2562
2563 if (power_off[phy->usb_phy_type])
2564 power_off[phy->usb_phy_type](phy, is_dpd);
2565
2566 if (phy->reg_vdd && phy->regulator_on && is_dpd) {
2567#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2568 if (tegra_get_revision() >= TEGRA_REVISION_A03)
2569#endif
2570 regulator_disable(phy->reg_vdd);
2571 phy->regulator_on = 0;
2572 }
2573 phy->power_on = false;
2574}
2575
2576void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup)
2577{
2578 const tegra_phy_fp preresume[] = {
2579 utmi_phy_preresume,
2580 NULL,
2581 NULL,
2582 uhsic_phy_preresume,
2583 };
2584
2585 if (preresume[phy->usb_phy_type])
2586 preresume[phy->usb_phy_type](phy, remote_wakeup);
2587}
2588
2589void tegra_usb_phy_postsuspend(struct tegra_usb_phy *phy, bool is_dpd)
2590
2591{
2592 const tegra_phy_fp postsuspend[] = {
2593 NULL,
2594 NULL,
2595 NULL,
2596 uhsic_phy_postsuspend,
2597 };
2598
2599 if (postsuspend[phy->usb_phy_type])
2600 postsuspend[phy->usb_phy_type](phy, is_dpd);
2601}
2602
2603void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
2604{
2605 const tegra_phy_fp postresume[] = {
2606 utmi_phy_postresume,
2607 NULL,
2608 NULL,
2609 uhsic_phy_postresume,
2610 };
2611
2612 if (postresume[phy->usb_phy_type])
2613 postresume[phy->usb_phy_type](phy, is_dpd);
2614}
2615
2616void tegra_ehci_pre_reset(struct tegra_usb_phy *phy, bool is_dpd)
2617{
2618 const tegra_phy_fp pre_reset[] = {
2619 NULL,
2620 NULL,
2621 null_phy_pre_usbcmd_reset,
2622 NULL,
2623 };
2624
2625 if (pre_reset[phy->usb_phy_type])
2626 pre_reset[phy->usb_phy_type](phy, is_dpd);
2627}
2628
2629void tegra_ehci_post_reset(struct tegra_usb_phy *phy, bool is_dpd)
2630{
2631 const tegra_phy_fp post_reset[] = {
2632 NULL,
2633 NULL,
2634 null_phy_post_usbcmd_reset,
2635 NULL,
2636 };
2637
2638 if (post_reset[phy->usb_phy_type])
2639 post_reset[phy->usb_phy_type](phy, is_dpd);
2640}
2641
2642void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
2643 enum tegra_usb_phy_port_speed port_speed)
2644{
2645 const tegra_phy_restore_start_fp phy_restore_start[] = {
2646 utmi_phy_restore_start,
2647 ulpi_phy_restore_start,
2648 null_phy_restore_start,
2649 NULL,
2650 };
2651
2652 if (phy_restore_start[phy->usb_phy_type])
2653 phy_restore_start[phy->usb_phy_type](phy, port_speed);
2654}
2655
2656void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy)
2657{
2658 const tegra_phy_restore_end_fp phy_restore_end[] = {
2659 utmi_phy_restore_end,
2660 ulpi_phy_restore_end,
2661 null_phy_restore_end,
2662 NULL,
2663 };
2664
2665 if (phy_restore_end[phy->usb_phy_type])
2666 phy_restore_end[phy->usb_phy_type](phy);
2667}
2668
2669void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy)
2670{
2671 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP)
2672 utmi_phy_clk_disable(phy);
2673}
2674
2675void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
2676{
2677 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP)
2678 utmi_phy_clk_enable(phy);
2679}
2680
2681void tegra_usb_phy_close(struct tegra_usb_phy *phy)
2682{
2683 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) {
2684 utmip_pad_close(phy);
2685 utmip_phy_disable_pmc_bus_ctrl(phy);
2686 }
2687 else if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_LINK_ULPI && phy->clk)
2688 clk_put(phy->clk);
2689 if (phy->mode == TEGRA_USB_PHY_MODE_HOST) {
2690 vbus_disable(phy);
2691 }
2692 clk_disable(phy->pll_u);
2693 clk_put(phy->pll_u);
2694 if (phy->reg_vbus)
2695 regulator_put(phy->reg_vbus);
2696 if (phy->reg_vdd)
2697 regulator_put(phy->reg_vdd);
2698 if (phy->instance == 0 && usb_phy_data[0].vbus_irq)
2699 free_irq(usb_phy_data[0].vbus_irq, phy);
2700 kfree(phy);
2701}
2702
2703int tegra_usb_phy_bus_connect(struct tegra_usb_phy *phy)
2704{
2705 unsigned long val;
2706 void __iomem *base = phy->regs;
2707 struct tegra_uhsic_config *uhsic_config = phy->config;
2708
2709 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
2710#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2711 val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET);
2712 val |= TEGRA_USB_USBMODE_HOST;
2713 writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET);
2714
2715 /* Change the USB controller PHY type to HSIC */
2716 val = readl(base + HOSTPC1_DEVLC);
2717 val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK);
2718 val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
2719 val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
2720 val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
2721 writel(val, base + HOSTPC1_DEVLC);
2722#endif
2723 val = readl(base + UHSIC_MISC_CFG0);
2724 val |= UHSIC_DETECT_SHORT_CONNECT;
2725 writel(val, base + UHSIC_MISC_CFG0);
2726 udelay(1);
2727
2728 val = readl(base + UHSIC_MISC_CFG0);
2729 val |= UHSIC_FORCE_XCVR_MODE;
2730 writel(val, base + UHSIC_MISC_CFG0);
2731
2732 val = readl(base + UHSIC_PADS_CFG1);
2733 val &= ~UHSIC_RPD_STROBE;
2734#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2735 val |= UHSIC_RPU_STROBE;
2736#endif
2737 writel(val, base + UHSIC_PADS_CFG1);
2738
2739 if (uhsic_config->usb_phy_ready &&
2740 uhsic_config->usb_phy_ready())
2741 return -EAGAIN;
2742
2743 /* connect detect on T30 requires extra wait */
2744 if (utmi_wait_register_timeout(base + UHSIC_STAT_CFG0,
2745 UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT,
2746 CONNECT_DETECT_TIMEOUT) < 0) {
2747 pr_err("%s: timeout waiting for hsic connect detect\n", __func__);
2748 return -ETIMEDOUT;
2749 }
2750
2751#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2752 if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(2), USB_PORTSC1_LS(2)) < 0) {
2753 pr_err("%s: timeout waiting for dplus state\n", __func__);
2754 return -ETIMEDOUT;
2755 }
2756#endif
2757 }
2758
2759 return 0;
2760}
2761
2762int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
2763{
2764 unsigned long val;
2765 void __iomem *base = phy->regs;
2766
2767 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
2768#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2769 /* Change the USB controller PHY type to HSIC */
2770 val = readl(base + HOSTPC1_DEVLC);
2771 val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK);
2772 val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
2773 val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
2774 val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
2775 writel(val, base + HOSTPC1_DEVLC);
2776 /* wait here, otherwise HOSTPC1_DEVLC_PSPD will timeout */
2777 mdelay(5);
2778#endif
2779 val = readl(base + USB_PORTSC1);
2780 val |= USB_PORTSC1_PTC(5);
2781 writel(val, base + USB_PORTSC1);
2782 udelay(2);
2783
2784 val = readl(base + USB_PORTSC1);
2785 val &= ~USB_PORTSC1_PTC(~0);
2786 writel(val, base + USB_PORTSC1);
2787 udelay(2);
2788
2789 if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(0), 0) < 0) {
2790 pr_err("%s: timeout waiting for SE0\n", __func__);
2791 return -ETIMEDOUT;
2792 }
2793
2794 if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_CCS, USB_PORTSC1_CCS) < 0) {
2795 pr_err("%s: timeout waiting for connection status\n", __func__);
2796 return -ETIMEDOUT;
2797 }
2798
2799#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
2800 if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_PSPD(2), USB_PORTSC1_PSPD(2)) < 0) {
2801 pr_err("%s: timeout waiting hsic high speed configuration\n", __func__);
2802 return -ETIMEDOUT;
2803 }
2804#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
2805 if (utmi_wait_register(base + HOSTPC1_DEVLC,
2806 HOSTPC1_DEVLC_PSPD(2),
2807 HOSTPC1_DEVLC_PSPD(2)) < 0) {
2808 pr_err("%s: timeout waiting hsic high speed configuration\n", __func__);
2809 return -ETIMEDOUT;
2810 }
2811#endif
2812 val = readl(base + USB_USBCMD);
2813 val &= ~USB_USBCMD_RS;
2814 writel(val, base + USB_USBCMD);
2815
2816 if (utmi_wait_register(base + USB_USBSTS, USB_USBSTS_HCH, USB_USBSTS_HCH) < 0) {
2817 pr_err("%s: timeout waiting for stopping the controller\n", __func__);
2818 return -ETIMEDOUT;
2819 }
2820
2821 val = readl(base + UHSIC_PADS_CFG1);
2822 val &= ~UHSIC_RPU_STROBE;
2823 val |= UHSIC_RPD_STROBE;
2824 writel(val, base + UHSIC_PADS_CFG1);
2825
2826 mdelay(50);
2827
2828 val = readl(base + UHSIC_PADS_CFG1);
2829 val &= ~UHSIC_RPD_STROBE;
2830 val |= UHSIC_RPU_STROBE;
2831 writel(val, base + UHSIC_PADS_CFG1);
2832
2833 val = readl(base + USB_USBCMD);
2834 val |= USB_USBCMD_RS;
2835 writel(val, base + USB_USBCMD);
2836
2837 val = readl(base + UHSIC_PADS_CFG1);
2838 val &= ~UHSIC_RPU_STROBE;
2839 writel(val, base + UHSIC_PADS_CFG1);
2840
2841 if (utmi_wait_register(base + USB_USBCMD, USB_USBCMD_RS, USB_USBCMD_RS) < 0) {
2842 pr_err("%s: timeout waiting for starting the controller\n", __func__);
2843 return -ETIMEDOUT;
2844 }
2845 }
2846
2847 return 0;
2848}
2849
2850int tegra_usb_phy_bus_idle(struct tegra_usb_phy *phy)
2851{
2852 unsigned long val;
2853 void __iomem *base = phy->regs;
2854 struct tegra_uhsic_config *uhsic_config = phy->config;
2855
2856 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
2857
2858#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2859 val = readl(base + TEGRA_USB_USBMODE_REG_OFFSET);
2860 val |= TEGRA_USB_USBMODE_HOST;
2861 writel(val, base + TEGRA_USB_USBMODE_REG_OFFSET);
2862
2863 /* Change the USB controller PHY type to HSIC */
2864 val = readl(base + HOSTPC1_DEVLC);
2865 val &= ~HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_MASK);
2866 val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
2867 val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
2868 val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
2869 writel(val, base + HOSTPC1_DEVLC);
2870#endif
2871 val = readl(base + UHSIC_MISC_CFG0);
2872 val |= UHSIC_DETECT_SHORT_CONNECT;
2873 writel(val, base + UHSIC_MISC_CFG0);
2874 udelay(1);
2875
2876 val = readl(base + UHSIC_MISC_CFG0);
2877 val |= UHSIC_FORCE_XCVR_MODE;
2878 writel(val, base + UHSIC_MISC_CFG0);
2879
2880 val = readl(base + UHSIC_PADS_CFG1);
2881 val &= ~UHSIC_RPD_STROBE;
2882 /* safe to enable RPU on STROBE at all times during idle */
2883 val |= UHSIC_RPU_STROBE;
2884 writel(val, base + UHSIC_PADS_CFG1);
2885
2886 val = readl(base + USB_USBCMD);
2887 val &= ~USB_USBCMD_RS;
2888 writel(val, base + USB_USBCMD);
2889
2890 if (uhsic_config->usb_phy_ready &&
2891 uhsic_config->usb_phy_ready())
2892 return -EAGAIN;
2893
2894 /* connect detect on T30 requires extra wait */
2895 if (utmi_wait_register_timeout(base + UHSIC_STAT_CFG0,
2896 UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT,
2897 CONNECT_DETECT_TIMEOUT) < 0) {
2898 pr_err("%s: timeout waiting for hsic connect detect\n",
2899 __func__);
2900 return -ETIMEDOUT;
2901 }
2902 }
2903 return 0;
2904}
2905
2906bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy)
2907{
2908 void __iomem *base = phy->regs;
2909
2910 if (phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) {
2911 if (utmi_wait_register(base + UHSIC_STAT_CFG0,
2912 UHSIC_CONNECT_DETECT, UHSIC_CONNECT_DETECT) < 0) {
2913 pr_err("%s: no hsic connection\n", __func__);
2914 return false;
2915 }
2916#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2917 if (utmi_wait_register(base + USB_PORTSC1, USB_PORTSC1_LS(2), USB_PORTSC1_LS(2)) < 0) {
2918 pr_err("%s: timeout waiting for dplus state\n", __func__);
2919 return false;
2920 }
2921#endif
2922 }
2923 return true;
2924}
2925
2926bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy)
2927{
2928 unsigned long val;
2929 void __iomem *base = phy->regs;
2930 bool status;
2931
2932 if (phy->usb_phy_type != TEGRA_USB_PHY_TYPE_UTMIP)
2933 {
2934 /* Charger detection is not there for ULPI
2935 * return Charger not available */
2936 return false;
2937 }
2938
2939 /* Enable charger detection logic */
2940 val = readl(base + UTMIP_BAT_CHRG_CFG0);
2941 val |= UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN;
2942 writel(val, base + UTMIP_BAT_CHRG_CFG0);
2943
2944 /* Source should be on for 100 ms as per USB charging spec */
2945 msleep(TDP_SRC_ON_MS);
2946
2947 val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
2948 /* If charger is not connected disable the interrupt */
2949 val &= ~VDAT_DET_INT_EN;
2950 val |= VDAT_DET_CHG_DET;
2951 writel(val,base + USB_PHY_VBUS_WAKEUP_ID);
2952
2953 val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
2954 if (val & VDAT_DET_STS)
2955 status = true;
2956 else
2957 status = false;
2958
2959 /* Disable charger detection logic */
2960 val = readl(base + UTMIP_BAT_CHRG_CFG0);
2961 val &= ~(UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN);
2962 writel(val, base + UTMIP_BAT_CHRG_CFG0);
2963
2964 /* Delay of 40 ms before we pull the D+ as per battery charger spec */
2965 msleep(TDPSRC_CON_MS);
2966
2967 return status;
2968}
2969
2970int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size)
2971{
2972 if (pdata) {
2973 int i;
2974
2975 for (i = 0; i < size; i++, pdata++) {
2976 usb_phy_data[pdata->instance].instance = pdata->instance;
2977 usb_phy_data[pdata->instance].vbus_irq = pdata->vbus_irq;
2978 usb_phy_data[pdata->instance].vbus_gpio = pdata->vbus_gpio;
2979 usb_phy_data[pdata->instance].vbus_reg_supply = pdata->vbus_reg_supply;
2980 }
2981 }
2982
2983 return 0;
2984}
2985
2986/* disable walk and wake events after resume from LP0 */
2987bool tegra_usb_phy_is_remotewake_detected(struct tegra_usb_phy *phy)
2988{
2989#ifndef CONFIG_ARCH_TEGRA_2x_SOC
2990 void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
2991 void __iomem *base = phy->regs;
2992 unsigned int inst = phy->instance;
2993 u32 val;
2994
2995 val = readl(base + UTMIP_PMC_WAKEUP0);
2996 if (val & EVENT_INT_ENB) {
2997 val = readl(pmc_base + UTMIP_UHSIC_STATUS);
2998 if (UTMIP_WAKE_ALARM(inst) & val) {
2999 val = readl(pmc_base + PMC_SLEEP_CFG);
3000 val &= ~UTMIP_WAKE_VAL(inst, 0x0);
3001 val |= UTMIP_WAKE_VAL(inst, WAKE_VAL_NONE);
3002 writel(val, pmc_base + PMC_SLEEP_CFG);
3003
3004 val = readl(pmc_base + PMC_TRIGGERS);
3005 val |= UTMIP_CLR_WAKE_ALARM(inst) |
3006 UTMIP_CLR_WALK_PTR(inst);
3007 writel(val, pmc_base + PMC_TRIGGERS);
3008
3009 val = readl(base + UTMIP_PMC_WAKEUP0);
3010 val &= ~EVENT_INT_ENB;
3011 writel(val, base + UTMIP_PMC_WAKEUP0);
3012 phy->remote_wakeup = true;
3013 return true;
3014 }
3015 }
3016#endif
3017 return false;
3018}
3019
diff --git a/arch/arm/mach-tegra/wakeups-t2.c b/arch/arm/mach-tegra/wakeups-t2.c
new file mode 100644
index 00000000000..7c5d12ac60d
--- /dev/null
+++ b/arch/arm/mach-tegra/wakeups-t2.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) 2011, Google, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/kernel.h>
16#include <linux/gpio.h>
17#include <linux/init.h>
18#include <linux/io.h>
19
20#include <mach/iomap.h>
21#include <mach/irqs.h>
22#include <mach/gpio.h>
23
24#include "gpio-names.h"
25
26static int tegra_wake_event_irq[] = {
27 [0] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5),
28 [1] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV3),
29 [2] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1),
30 [3] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PB6),
31 [4] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN7),
32 [5] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PA0),
33 [6] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5),
34 [7] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
35 [8] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC7),
36 [9] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2),
37 [10] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PAA1),
38 [11] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW3),
39 [12] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW2),
40 [13] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PY6),
41 [14] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6),
42 [15] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PJ7),
43 [16] = INT_RTC,
44 [17] = INT_KBC,
45 [18] = INT_EXTERNAL_PMU,
46 [19] = -EINVAL, /* TEGRA_USB1_VBUS, */
47 [20] = -EINVAL, /* TEGRA_USB3_VBUS, */
48 [21] = -EINVAL, /* TEGRA_USB1_ID, */
49 [22] = -EINVAL, /* TEGRA_USB3_ID, */
50 [23] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PI5),
51 [24] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV2),
52 [25] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS4),
53 [26] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS5),
54 [27] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0),
55 [28] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ6),
56 [29] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ7),
57 [30] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN2),
58};
59
60int tegra_irq_to_wake(int irq)
61{
62 int i;
63 int wake_irq;
64 int search_gpio;
65 static int last_wake = -1;
66
67 /* Two level wake irq search for gpio based wakeups -
68 * 1. check for GPIO irq(based on tegra_wake_event_irq table)
69 * e.g. for a board, wake7 based on GPIO PU6 and irq==358 done first
70 * 2. check for gpio bank irq assuming search for GPIO irq
71 * preceded this search.
72 * e.g. in this step check for gpio bank irq GPIO6 irq==119
73 */
74 for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
75 /* return if step 1 matches */
76 if (tegra_wake_event_irq[i] == irq) {
77 pr_info("Wake%d for irq=%d\n", i, irq);
78 last_wake = i;
79 return i;
80 }
81
82 /* step 2 below uses saved last_wake from step 1
83 * in previous call */
84 search_gpio = irq_to_gpio(
85 tegra_wake_event_irq[i]);
86 if (search_gpio < 0)
87 continue;
88 wake_irq = tegra_gpio_get_bank_int_nr(search_gpio);
89 if (wake_irq < 0)
90 continue;
91 if ((last_wake == i) &&
92 (wake_irq == irq)) {
93 pr_info("gpio bank wake found: wake%d for irq=%d\n",
94 i, irq);
95 return i;
96 }
97 }
98
99 return -EINVAL;
100}
101
102int tegra_wake_to_irq(int wake)
103{
104 if (wake < 0)
105 return -EINVAL;
106
107 if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
108 return -EINVAL;
109
110 return tegra_wake_event_irq[wake];
111}
diff --git a/arch/arm/mach-tegra/wakeups-t2.h b/arch/arm/mach-tegra/wakeups-t2.h
new file mode 100644
index 00000000000..eb193c0aaf9
--- /dev/null
+++ b/arch/arm/mach-tegra/wakeups-t2.h
@@ -0,0 +1,65 @@
1/*
2 * arch/arm/mach-tegra/wakeups-t2.h
3 *
4 * Declarations of Tegra 2 LP0 wakeup sources
5 *
6 * Copyright (c) 2010, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef __MACH_TEGRA_WAKEUPS_T2_H
24#define __MACH_TEGRA_WAKEUPS_T2_H
25
26#ifndef CONFIG_ARCH_TEGRA_2x_SOC
27#error "Tegra 2 wakeup sources valid only for CONFIG_ARCH_TEGRA_2x_SOC"
28#endif
29
30int tegra_irq_to_wake(int irq);
31int tegra_wake_to_irq(int wake);
32
33#define TEGRA_WAKE_GPIO_PO5 (1 << 0)
34#define TEGRA_WAKE_GPIO_PV3 (1 << 1)
35#define TEGRA_WAKE_GPIO_PL1 (1 << 2)
36#define TEGRA_WAKE_GPIO_PB6 (1 << 3)
37#define TEGRA_WAKE_GPIO_PN7 (1 << 4)
38#define TEGRA_WAKE_GPIO_PA0 (1 << 5)
39#define TEGRA_WAKE_GPIO_PU5 (1 << 6)
40#define TEGRA_WAKE_GPIO_PU6 (1 << 7)
41#define TEGRA_WAKE_GPIO_PC7 (1 << 8)
42#define TEGRA_WAKE_GPIO_PS2 (1 << 9)
43#define TEGRA_WAKE_GPIO_PAA1 (1 << 10)
44#define TEGRA_WAKE_GPIO_PW3 (1 << 11)
45#define TEGRA_WAKE_GPIO_PW2 (1 << 12)
46#define TEGRA_WAKE_GPIO_PY6 (1 << 13)
47#define TEGRA_WAKE_GPIO_PV6 (1 << 14)
48#define TEGRA_WAKE_GPIO_PJ7 (1 << 15)
49#define TEGRA_WAKE_RTC_ALARM (1 << 16)
50#define TEGRA_WAKE_KBC_EVENT (1 << 17)
51#define TEGRA_WAKE_PWR_INT (1 << 18)
52#define TEGRA_WAKE_USB1_VBUS (1 << 19)
53#define TEGRA_WAKE_USB3_VBUS (1 << 20)
54#define TEGRA_WAKE_USB1_ID (1 << 21)
55#define TEGRA_WAKE_USB3_ID (1 << 22)
56#define TEGRA_WAKE_GPIO_PI5 (1 << 23)
57#define TEGRA_WAKE_GPIO_PV2 (1 << 24)
58#define TEGRA_WAKE_GPIO_PS4 (1 << 25)
59#define TEGRA_WAKE_GPIO_PS5 (1 << 26)
60#define TEGRA_WAKE_GPIO_PS0 (1 << 27)
61#define TEGRA_WAKE_GPIO_PQ6 (1 << 28)
62#define TEGRA_WAKE_GPIO_PQ7 (1 << 29)
63#define TEGRA_WAKE_GPIO_PN2 (1 << 30)
64
65#endif
diff --git a/arch/arm/mach-tegra/wakeups-t3.c b/arch/arm/mach-tegra/wakeups-t3.c
new file mode 100644
index 00000000000..82373620436
--- /dev/null
+++ b/arch/arm/mach-tegra/wakeups-t3.c
@@ -0,0 +1,122 @@
1/*
2 * Copyright (c) 2011, NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/kernel.h>
16#include <linux/gpio.h>
17#include <linux/init.h>
18#include <linux/io.h>
19
20#include <mach/iomap.h>
21#include <mach/irqs.h>
22#include <mach/gpio.h>
23
24#include "gpio-names.h"
25
26static int tegra_wake_event_irq[] = {
27 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5), /* wake0 */
28 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV1), /* wake1 */
29 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1), /* wake2 */
30 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PB6), /* wake3 */
31 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN7), /* wake4 */
32 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PBB6), /* wake5 */
33 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5), /* wake6 */
34 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6), /* wake7 */
35 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC7), /* wake8 */
36 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2), /* wake9 */
37 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PAA1), /* wake10 */
38 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW3), /* wake11 */
39 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW2), /* wake12 */
40 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PY6), /* wake13 */
41 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PDD3), /* wake14 */
42 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PJ2), /* wake15 */
43 INT_RTC, /* wake16 */
44 INT_KBC, /* wake17 */
45 INT_EXTERNAL_PMU, /* wake18 */
46 -EINVAL, /* TEGRA_USB1_VBUS, */ /* wake19 */
47 -EINVAL, /* TEGRA_USB2_VBUS, */ /* wake20 */
48 -EINVAL, /* TEGRA_USB1_ID, */ /* wake21 */
49 -EINVAL, /* TEGRA_USB2_ID, */ /* wake22 */
50 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PI5), /* wake23 */
51 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV0), /* wake24 */
52 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS4), /* wake25 */
53 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS5), /* wake26 */
54 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0), /* wake27 */
55 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS6), /* wake28 */
56 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS7), /* wake29 */
57 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN2), /* wake30 */
58 -EINVAL, /* not used */ /* wake31 */
59 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO4), /* wake32 */
60 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PJ0), /* wake33 */
61 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PK2), /* wake34 */
62 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PI6), /* wake35 */
63 TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PBB1), /* wake36 */
64 -EINVAL, /* TEGRA_USB3_VBUS, */ /* wake37 */
65 -EINVAL, /* TEGRA_USB3_ID, */ /* wake38 */
66 INT_USB, /* TEGRA_USB1_UTMIP, */ /* wake39 */
67 INT_USB2, /* TEGRA_USB2_UTMIP, */ /* wake40 */
68 INT_USB3, /* TEGRA_USB3_UTMIP, */ /* wake41 */
69};
70
71int tegra_irq_to_wake(int irq)
72{
73 int i;
74 int wake_irq;
75 int search_gpio;
76 static int last_wake = -1;
77
78 /* Two level wake irq search for gpio based wakeups -
79 * 1. check for GPIO irq(based on tegra_wake_event_irq table)
80 * e.g. for a board, wake7 based on GPIO PU6 and irq==390 done first
81 * 2. check for gpio bank irq assuming search for GPIO irq
82 * preceded this search.
83 * e.g. in this step check for gpio bank irq GPIO6 irq==119
84 */
85 for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
86 /* return if step 1 matches */
87 if (tegra_wake_event_irq[i] == irq) {
88 pr_info("Wake%d for irq=%d\n", i, irq);
89 last_wake = i;
90 return i;
91 }
92
93 /* step 2 below uses saved last_wake from step 1
94 * in previous call */
95 search_gpio = irq_to_gpio(
96 tegra_wake_event_irq[i]);
97 if (search_gpio < 0)
98 continue;
99 wake_irq = tegra_gpio_get_bank_int_nr(search_gpio);
100 if (wake_irq < 0)
101 continue;
102 if ((last_wake == i) &&
103 (wake_irq == irq)) {
104 pr_info("gpio bank wake found: wake%d for irq=%d\n",
105 i, irq);
106 return i;
107 }
108 }
109
110 return -EINVAL;
111}
112
113int tegra_wake_to_irq(int wake)
114{
115 if (wake < 0)
116 return -EINVAL;
117
118 if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
119 return -EINVAL;
120
121 return tegra_wake_event_irq[wake];
122}
diff --git a/arch/arm/mach-tegra/wakeups-t3.h b/arch/arm/mach-tegra/wakeups-t3.h
new file mode 100644
index 00000000000..f811d893938
--- /dev/null
+++ b/arch/arm/mach-tegra/wakeups-t3.h
@@ -0,0 +1,71 @@
1/*
2 * arch/arm/mach-tegra/wakeups-t3.h
3 *
4 * Declarations of Tegra 3 LP0 wakeup sources
5 *
6 * Copyright (c) 2010, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef __MACH_TEGRA_WAKEUPS_T3_H
24#define __MACH_TEGRA_WAKEUPS_T3_H
25
26#ifndef CONFIG_ARCH_TEGRA_3x_SOC
27#error "Tegra 3 wakeup sources valid only for CONFIG_ARCH_TEGRA_3x_SOC"
28#endif
29
30#define TEGRA_WAKE_GPIO_PO5 (1ull << 0)
31#define TEGRA_WAKE_GPIO_PV1 (1ull << 1)
32#define TEGRA_WAKE_GPIO_PL1 (1ull << 2)
33#define TEGRA_WAKE_GPIO_PB6 (1ull << 3)
34#define TEGRA_WAKE_GPIO_PN7 (1ull << 4)
35#define TEGRA_WAKE_GPIO_PBB6 (1ull << 5)
36#define TEGRA_WAKE_GPIO_PU5 (1ull << 6)
37#define TEGRA_WAKE_GPIO_PU6 (1ull << 7)
38#define TEGRA_WAKE_GPIO_PC7 (1ull << 8)
39#define TEGRA_WAKE_GPIO_PS2 (1ull << 9)
40#define TEGRA_WAKE_GPIO_PAA1 (1ull << 10)
41#define TEGRA_WAKE_GPIO_PW3 (1ull << 11)
42#define TEGRA_WAKE_GPIO_PW2 (1ull << 12)
43#define TEGRA_WAKE_GPIO_PY6 (1ull << 13)
44#define TEGRA_WAKE_GPIO_PDD3 (1ull << 14)
45#define TEGRA_WAKE_GPIO_PJ2 (1ull << 15)
46#define TEGRA_WAKE_RTC_ALARM (1ull << 16)
47#define TEGRA_WAKE_KBC_EVENT (1ull << 17)
48#define TEGRA_WAKE_PWR_INT (1ull << 18)
49#define TEGRA_WAKE_USB1_VBUS (1ull << 19)
50#define TEGRA_WAKE_USB2_VBUS (1ull << 20)
51#define TEGRA_WAKE_USB1_ID (1ull << 21)
52#define TEGRA_WAKE_USB2_ID (1ull << 22)
53#define TEGRA_WAKE_GPIO_PI5 (1ull << 23)
54#define TEGRA_WAKE_GPIO_PV0 (1ull << 24)
55#define TEGRA_WAKE_GPIO_PS4 (1ull << 25)
56#define TEGRA_WAKE_GPIO_PS5 (1ull << 26)
57#define TEGRA_WAKE_GPIO_PS0 (1ull << 27)
58#define TEGRA_WAKE_GPIO_PS6 (1ull << 28)
59#define TEGRA_WAKE_GPIO_PS7 (1ull << 29)
60#define TEGRA_WAKE_GPIO_PN2 (1ull << 30)
61/* bit 31 is unused */
62
63#define TEGRA_WAKE_GPIO_PO4 (1ull << 32)
64#define TEGRA_WAKE_GPIO_PJ0 (1ull << 33)
65#define TEGRA_WAKE_GPIO_PK2 (1ull << 34)
66#define TEGRA_WAKE_GPIO_PI6 (1ull << 35)
67#define TEGRA_WAKE_GPIO_PBB1 (1ull << 36)
68#define TEGRA_WAKE_USB3_ID (1ull << 37)
69#define TEGRA_WAKE_USB3_VBUS (1ull << 38)
70
71#endif
diff --git a/arch/arm/mach-tegra/wdt-recovery.c b/arch/arm/mach-tegra/wdt-recovery.c
new file mode 100644
index 00000000000..537b1c0db85
--- /dev/null
+++ b/arch/arm/mach-tegra/wdt-recovery.c
@@ -0,0 +1,131 @@
1/*
2 * arch/arm/mach-tegra/wdt-recovery.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/delay.h>
22#include <linux/suspend.h>
23#include <linux/resource.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/syscore_ops.h>
27#include <linux/io.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/time.h>
31#include <asm/localtimer.h>
32
33#include <mach/nvmap.h>
34#include <mach/irqs.h>
35#include <mach/iomap.h>
36#include <mach/clk.h>
37#include <mach/io.h>
38
39static int wdt_heartbeat = 30;
40
41#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
42#define TIMER_PTV 0
43 #define TIMER_EN (1 << 31)
44 #define TIMER_PERIODIC (1 << 30)
45#define TIMER_PCR 0x4
46 #define TIMER_PCR_INTR (1 << 30)
47#define WDT_CFG (0)
48 #define WDT_CFG_TMR_SRC (7 << 0) /* for TMR7. */
49 #define WDT_CFG_PERIOD (1 << 4)
50 #define WDT_CFG_INT_EN (1 << 12)
51 #define WDT_CFG_SYS_RST_EN (1 << 14)
52 #define WDT_CFG_PMC2CAR_RST_EN (1 << 15)
53#define WDT_CMD (8)
54 #define WDT_CMD_START_COUNTER (1 << 0)
55 #define WDT_CMD_DISABLE_COUNTER (1 << 1)
56#define WDT_UNLOCK (0xC)
57 #define WDT_UNLOCK_PATTERN (0xC45A << 0)
58
59static void __iomem *wdt_timer = IO_ADDRESS(TEGRA_TMR7_BASE);
60static void __iomem *wdt_source = IO_ADDRESS(TEGRA_WDT0_BASE);
61
62static void tegra_wdt_reset_enable(void)
63{
64 u32 val;
65
66 writel(TIMER_PCR_INTR, wdt_timer + TIMER_PCR);
67 val = (wdt_heartbeat * 1000000ul) / 4;
68 val |= (TIMER_EN | TIMER_PERIODIC);
69 writel(val, wdt_timer + TIMER_PTV);
70
71 val = WDT_CFG_TMR_SRC | WDT_CFG_PERIOD | /*WDT_CFG_INT_EN |*/
72 /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
73 writel(val, wdt_source + WDT_CFG);
74 writel(WDT_CMD_START_COUNTER, wdt_source + WDT_CMD);
75 pr_info("%s: WDT Recovery Enabled\n", __func__);
76}
77
78static int tegra_wdt_reset_disable(void)
79{
80 writel(TIMER_PCR_INTR, wdt_timer + TIMER_PCR);
81 writel(WDT_UNLOCK_PATTERN, wdt_source + WDT_UNLOCK);
82 writel(WDT_CMD_DISABLE_COUNTER, wdt_source + WDT_CMD);
83
84 writel(0, wdt_timer + TIMER_PTV);
85 pr_info("%s: WDT Recovery Disabled\n", __func__);
86
87 return 0;
88}
89#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
90
91static void tegra_wdt_reset_enable(void)
92{
93}
94static int tegra_wdt_reset_disable(void)
95{
96 return 0;
97}
98#endif
99
100static int tegra_pm_notify(struct notifier_block *nb,
101 unsigned long event, void *nouse)
102{
103 switch (event) {
104 case PM_SUSPEND_PREPARE:
105 tegra_wdt_reset_enable();
106 break;
107 case PM_POST_SUSPEND:
108 tegra_wdt_reset_disable();
109 break;
110 }
111
112 return NOTIFY_OK;
113}
114
115static struct notifier_block tegra_wdt_notify = {
116 .notifier_call = tegra_pm_notify,
117};
118
119static struct syscore_ops tegra_wdt_syscore_ops = {
120 .suspend = tegra_wdt_reset_disable,
121 .resume = tegra_wdt_reset_enable,
122};
123
124void __init tegra_wdt_recovery_init(void)
125{
126#ifdef CONFIG_PM
127 /* Register PM notifier. */
128 register_pm_notifier(&tegra_wdt_notify);
129#endif
130 register_syscore_ops(&tegra_wdt_syscore_ops);
131}
diff --git a/arch/arm/mach-tegra/wdt-recovery.h b/arch/arm/mach-tegra/wdt-recovery.h
new file mode 100644
index 00000000000..e26c1d03857
--- /dev/null
+++ b/arch/arm/mach-tegra/wdt-recovery.h
@@ -0,0 +1,17 @@
1/*
2 * arch/arm/mach-tegra/wdt-recovery.h
3 *
4 * Copyright (C) 2011 NVIDIA Corporation.
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
17void __init tegra_wdt_recovery_init(void);