aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-19 16:35:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-19 16:35:07 -0400
commite4e47eb15b7884963efe7f98231009c5770a2c3d (patch)
treeebd3536a3aa728089168f072c88858578535046d /arch
parent711f77f53c5ff6aa61dbe8e5f518e50d6306e89d (diff)
parent7b52161d14fa8a22a2387f4aa2fb7b854587830d (diff)
Merge branch 'msm-core' of git://codeaurora.org/quic/kernel/dwalker/linux-msm
* 'msm-core' of git://codeaurora.org/quic/kernel/dwalker/linux-msm: (72 commits) msm: 7x30 Kconfig and makefile changes msm: clock support for the MSM7x30 CPU. msm: physical offset for MSM7X30 msm: io: add io support for 7x30 msm: Add extern for 7x30 clock list. msm: dma: add 7x30 security domain abstraction msm: update basic board layout for MSM7x30 msm: add devices-msm7x30.c msm: add msm_iomap-7x30.h for MSM7x30 support msm: irqs: add irqs-7x30.h for MSM7x30 support msm: 8x50 Kconfig changes msm: physical offset for QSD8x50 msm: io: add io support for 8x50 msm: add extern for 8x50 clock list. msm: add devices-qsd8x50.c msm: update basic board layout for QSD8x50 msm: add msm_iomap-8x50.h for QSD8x50 support msm: irqs: add irqs-8x50.h for QSD8x50 support msm: timer: allow MSM_DGT_BASE to be overriden msm: add Qualcomm 7x30 interrupt controller driver. ...
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-msm/Kconfig92
-rw-r--r--arch/arm/mach-msm/Makefile23
-rw-r--r--arch/arm/mach-msm/acpuclock-arm11.c526
-rw-r--r--arch/arm/mach-msm/acpuclock.h32
-rw-r--r--arch/arm/mach-msm/board-halibut.c17
-rw-r--r--arch/arm/mach-msm/board-mahimahi.c87
-rw-r--r--arch/arm/mach-msm/board-msm7x27.c179
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c120
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c94
-rw-r--r--arch/arm/mach-msm/board-sapphire.c118
-rw-r--r--arch/arm/mach-msm/board-trout.c (renamed from arch/arm/mach-msm/board-dream.c)8
-rw-r--r--arch/arm/mach-msm/board-trout.h (renamed from arch/arm/mach-msm/board-dream.h)0
-rw-r--r--arch/arm/mach-msm/clock-7x01a.c126
-rw-r--r--arch/arm/mach-msm/clock-7x30.h168
-rw-r--r--arch/arm/mach-msm/clock-pcom.c131
-rw-r--r--arch/arm/mach-msm/clock-pcom.h153
-rw-r--r--arch/arm/mach-msm/clock.c258
-rw-r--r--arch/arm/mach-msm/clock.h71
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c (renamed from arch/arm/mach-msm/devices.c)125
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c128
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c92
-rw-r--r--arch/arm/mach-msm/devices.h11
-rw-r--r--arch/arm/mach-msm/dma.c23
-rw-r--r--arch/arm/mach-msm/gpio.c85
-rw-r--r--arch/arm/mach-msm/include/mach/board.h14
-rw-r--r--arch/arm/mach-msm/include/mach/clk.h57
-rw-r--r--arch/arm/mach-msm/include/mach/dma.h32
-rw-r--r--arch/arm/mach-msm/include/mach/gpio.h142
-rw-r--r--arch/arm/mach-msm/include/mach/io.h5
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-7x00.h75
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-7x30.h170
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x50.h105
-rw-r--r--arch/arm/mach-msm/include/mach/irqs.h81
-rw-r--r--arch/arm/mach-msm/include/mach/memory.h8
-rw-r--r--arch/arm/mach-msm/include/mach/msm_fb.h147
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x00.h139
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x30.h122
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x50.h147
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap.h95
-rw-r--r--arch/arm/mach-msm/include/mach/msm_smd.h109
-rw-r--r--arch/arm/mach-msm/include/mach/sirc.h115
-rw-r--r--arch/arm/mach-msm/include/mach/system.h5
-rw-r--r--arch/arm/mach-msm/include/mach/vreg.h2
-rw-r--r--arch/arm/mach-msm/io.c75
-rw-r--r--arch/arm/mach-msm/irq-vic.c365
-rw-r--r--arch/arm/mach-msm/irq.c4
-rw-r--r--arch/arm/mach-msm/last_radio_log.c82
-rw-r--r--arch/arm/mach-msm/proc_comm.c26
-rw-r--r--arch/arm/mach-msm/proc_comm.h105
-rw-r--r--arch/arm/mach-msm/sirc.c177
-rw-r--r--arch/arm/mach-msm/smd.c1046
-rw-r--r--arch/arm/mach-msm/smd_debug.c315
-rw-r--r--arch/arm/mach-msm/smd_private.h403
-rw-r--r--arch/arm/mach-msm/timer.c2
-rw-r--r--arch/arm/mach-msm/vreg.c154
55 files changed, 6538 insertions, 453 deletions
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index b9fd5c528e5b..47264a76eeb3 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1,7 +1,80 @@
1if ARCH_MSM 1if ARCH_MSM
2 2
3comment "MSM Board Type" 3choice
4 prompt "Qualcomm MSM SoC Type"
5 default ARCH_MSM7X00A
6
7config ARCH_MSM7X00A
8 bool "MSM7x00A / MSM7x01A"
9 select ARCH_MSM_ARM11
10 select MSM_SMD
11 select MSM_SMD_PKG3
12 select CPU_V6
13
14config ARCH_MSM7X30
15 bool "MSM7x30"
16 select ARCH_MSM_SCORPION
17 select MSM_SMD
18 select MSM_VIC
19 select CPU_V7
20 select MSM_REMOTE_SPINLOCK_DEKKERS
21
22config ARCH_QSD8X50
23 bool "QSD8X50"
24 select ARCH_MSM_SCORPION
25 select MSM_SMD
26 select MSM_VIC
27 select CPU_V7
28 select MSM_REMOTE_SPINLOCK_LDREX
29endchoice
30
31config MSM_SOC_REV_A
32 bool
33
34config ARCH_MSM_ARM11
35 bool
36config ARCH_MSM_SCORPION
37 bool
38
39config MSM_VIC
40 bool
41
42menu "Qualcomm MSM Board Type"
43
44config MACH_HALIBUT
4 depends on ARCH_MSM 45 depends on ARCH_MSM
46 depends on ARCH_MSM7X00A
47 bool "Halibut Board (QCT SURF7201A)"
48 help
49 Support for the Qualcomm SURF7201A eval board.
50
51config MACH_TROUT
52 depends on ARCH_MSM
53 depends on ARCH_MSM7X00A
54 bool "HTC Dream (aka trout)"
55 help
56 Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
57
58config MACH_MSM7X30_SURF
59 depends on ARCH_MSM7X30
60 bool "MSM7x30 SURF"
61 help
62 Support for the Qualcomm MSM7x30 SURF eval board.
63
64config MACH_QSD8X50_SURF
65 depends on ARCH_QSD8X50
66 bool "QSD8x50 SURF"
67 help
68 Support for the Qualcomm QSD8x50 SURF eval board.
69
70config MACH_QSD8X50A_ST1_5
71 depends on ARCH_QSD8X50
72 select MSM_SOC_REV_A
73 bool "QSD8x50A ST1.5"
74 help
75 Support for the Qualcomm ST1.5.
76
77endmenu
5 78
6config MSM_DEBUG_UART 79config MSM_DEBUG_UART
7 int 80 int
@@ -27,19 +100,10 @@ choice
27 bool "UART3" 100 bool "UART3"
28endchoice 101endchoice
29 102
30config MACH_HALIBUT 103config MSM_SMD_PKG3
31 depends on ARCH_MSM 104 bool
32 select CPU_V6
33 default y
34 bool "Halibut Board (QCT SURF7201A)"
35 help
36 Support for the Qualcomm SURF7201A eval board.
37 105
38config MACH_TROUT 106config MSM_SMD
39 select CPU_V6 107 bool
40 default y
41 bool "HTC Dream (aka trout)"
42 help
43 Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
44 108
45endif 109endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 91e6f5c95dc1..66677f0acaed 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,9 +1,22 @@
1obj-y += io.o idle.o irq.o timer.o dma.o
2obj-y += devices.o
3obj-y += proc_comm.o 1obj-y += proc_comm.o
2obj-y += io.o idle.o timer.o dma.o
4obj-y += vreg.o 3obj-y += vreg.o
5obj-y += clock.o clock-7x01a.o 4obj-y += acpuclock-arm11.o
5obj-y += clock.o clock-pcom.o
6obj-y += gpio.o
6 7
7obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o 8ifdef CONFIG_MSM_VIC
9obj-y += irq-vic.o
10else
11obj-y += irq.o
12endif
13
14obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
15obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
16obj-$(CONFIG_MSM_SMD) += last_radio_log.o
17
18obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o
19obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
20obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
21obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
8 22
9obj-$(CONFIG_MACH_TROUT) += board-dream.o
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c
new file mode 100644
index 000000000000..af5e85b91d02
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-arm11.c
@@ -0,0 +1,526 @@
1/* arch/arm/mach-msm/acpuclock.c
2 *
3 * MSM architecture clock driver
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Copyright (c) 2007 QUALCOMM Incorporated
7 * Author: San Mehat <san@android.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/version.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/list.h>
24#include <linux/errno.h>
25#include <linux/string.h>
26#include <linux/delay.h>
27#include <linux/clk.h>
28#include <linux/cpufreq.h>
29#include <linux/mutex.h>
30#include <linux/io.h>
31#include <mach/board.h>
32#include <mach/msm_iomap.h>
33
34#include "proc_comm.h"
35#include "acpuclock.h"
36
37
38#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
39#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
40#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
41
42/*
43 * ARM11 clock configuration for specific ACPU speeds
44 */
45
46#define ACPU_PLL_TCXO -1
47#define ACPU_PLL_0 0
48#define ACPU_PLL_1 1
49#define ACPU_PLL_2 2
50#define ACPU_PLL_3 3
51
52#define PERF_SWITCH_DEBUG 0
53#define PERF_SWITCH_STEP_DEBUG 0
54
55struct clock_state
56{
57 struct clkctl_acpu_speed *current_speed;
58 struct mutex lock;
59 uint32_t acpu_switch_time_us;
60 uint32_t max_speed_delta_khz;
61 uint32_t vdd_switch_time_us;
62 unsigned long power_collapse_khz;
63 unsigned long wait_for_irq_khz;
64};
65
66static struct clk *ebi1_clk;
67static struct clock_state drv_state = { 0 };
68
69static void __init acpuclk_init(void);
70
71/* MSM7201A Levels 3-6 all correspond to 1.2V, level 7 corresponds to 1.325V. */
72enum {
73 VDD_0 = 0,
74 VDD_1 = 1,
75 VDD_2 = 2,
76 VDD_3 = 3,
77 VDD_4 = 3,
78 VDD_5 = 3,
79 VDD_6 = 3,
80 VDD_7 = 7,
81 VDD_END
82};
83
84struct clkctl_acpu_speed {
85 unsigned int a11clk_khz;
86 int pll;
87 unsigned int a11clk_src_sel;
88 unsigned int a11clk_src_div;
89 unsigned int ahbclk_khz;
90 unsigned int ahbclk_div;
91 int vdd;
92 unsigned int axiclk_khz;
93 unsigned long lpj; /* loops_per_jiffy */
94/* Index in acpu_freq_tbl[] for steppings. */
95 short down;
96 short up;
97};
98
99/*
100 * ACPU speed table. Complete table is shown but certain speeds are commented
101 * out to optimized speed switching. Initalize loops_per_jiffy to 0.
102 *
103 * Table stepping up/down is optimized for 256mhz jumps while staying on the
104 * same PLL.
105 */
106#if (0)
107static struct clkctl_acpu_speed acpu_freq_tbl[] = {
108 { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 8 },
109 { 61440, ACPU_PLL_0, 4, 3, 61440, 0, VDD_0, 30720, 0, 0, 8 },
110 { 81920, ACPU_PLL_0, 4, 2, 40960, 1, VDD_0, 61440, 0, 0, 8 },
111 { 96000, ACPU_PLL_1, 1, 7, 48000, 1, VDD_0, 61440, 0, 0, 9 },
112 { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 8 },
113 { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 12 },
114 { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 11 },
115 { 192000, ACPU_PLL_1, 1, 3, 64000, 2, VDD_3, 61440, 0, 0, 12 },
116 { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 12 },
117 { 256000, ACPU_PLL_1, 1, 2, 128000, 2, VDD_5, 128000, 0, 0, 12 },
118 { 264000, ACPU_PLL_2, 2, 3, 88000, 2, VDD_5, 128000, 0, 6, 13 },
119 { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 6, 13 },
120 { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 5, -1 },
121 { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 11, -1 },
122 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
123};
124#else /* Table of freq we currently use. */
125static struct clkctl_acpu_speed acpu_freq_tbl[] = {
126 { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 4 },
127 { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 4 },
128 { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 6 },
129 { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 5 },
130 { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 5 },
131 { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 3, 7 },
132 { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 2, -1 },
133 { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 5, -1 },
134 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
135};
136#endif
137
138
139#ifdef CONFIG_CPU_FREQ_TABLE
140static struct cpufreq_frequency_table freq_table[] = {
141 { 0, 122880 },
142 { 1, 128000 },
143 { 2, 245760 },
144 { 3, 384000 },
145 { 4, 528000 },
146 { 5, CPUFREQ_TABLE_END },
147};
148#endif
149
150static int pc_pll_request(unsigned id, unsigned on)
151{
152 int res;
153 on = !!on;
154
155#if PERF_SWITCH_DEBUG
156 if (on)
157 printk(KERN_DEBUG "Enabling PLL %d\n", id);
158 else
159 printk(KERN_DEBUG "Disabling PLL %d\n", id);
160#endif
161
162 res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
163 if (res < 0)
164 return res;
165
166#if PERF_SWITCH_DEBUG
167 if (on)
168 printk(KERN_DEBUG "PLL %d enabled\n", id);
169 else
170 printk(KERN_DEBUG "PLL %d disabled\n", id);
171#endif
172 return res;
173}
174
175
176/*----------------------------------------------------------------------------
177 * ARM11 'owned' clock control
178 *---------------------------------------------------------------------------*/
179
180unsigned long acpuclk_power_collapse(void) {
181 int ret = acpuclk_get_rate();
182 ret *= 1000;
183 if (ret > drv_state.power_collapse_khz)
184 acpuclk_set_rate(drv_state.power_collapse_khz, 1);
185 return ret;
186}
187
188unsigned long acpuclk_get_wfi_rate(void)
189{
190 return drv_state.wait_for_irq_khz;
191}
192
193unsigned long acpuclk_wait_for_irq(void) {
194 int ret = acpuclk_get_rate();
195 ret *= 1000;
196 if (ret > drv_state.wait_for_irq_khz)
197 acpuclk_set_rate(drv_state.wait_for_irq_khz, 1);
198 return ret;
199}
200
201static int acpuclk_set_vdd_level(int vdd)
202{
203 uint32_t current_vdd;
204
205 current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07;
206
207#if PERF_SWITCH_DEBUG
208 printk(KERN_DEBUG "acpuclock: Switching VDD from %u -> %d\n",
209 current_vdd, vdd);
210#endif
211 writel((1 << 7) | (vdd << 3), A11S_VDD_SVS_PLEVEL_ADDR);
212 udelay(drv_state.vdd_switch_time_us);
213 if ((readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x7) != vdd) {
214#if PERF_SWITCH_DEBUG
215 printk(KERN_ERR "acpuclock: VDD set failed\n");
216#endif
217 return -EIO;
218 }
219
220#if PERF_SWITCH_DEBUG
221 printk(KERN_DEBUG "acpuclock: VDD switched\n");
222#endif
223 return 0;
224}
225
226/* Set proper dividers for the given clock speed. */
227static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s) {
228 uint32_t reg_clkctl, reg_clksel, clk_div;
229
230 /* AHB_CLK_DIV */
231 clk_div = (readl(A11S_CLK_SEL_ADDR) >> 1) & 0x03;
232 /*
233 * If the new clock divider is higher than the previous, then
234 * program the divider before switching the clock
235 */
236 if (hunt_s->ahbclk_div > clk_div) {
237 reg_clksel = readl(A11S_CLK_SEL_ADDR);
238 reg_clksel &= ~(0x3 << 1);
239 reg_clksel |= (hunt_s->ahbclk_div << 1);
240 writel(reg_clksel, A11S_CLK_SEL_ADDR);
241 }
242 if ((readl(A11S_CLK_SEL_ADDR) & 0x01) == 0) {
243 /* SRC0 */
244
245 /* Program clock source */
246 reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
247 reg_clkctl &= ~(0x07 << 4);
248 reg_clkctl |= (hunt_s->a11clk_src_sel << 4);
249 writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
250
251 /* Program clock divider */
252 reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
253 reg_clkctl &= ~0xf;
254 reg_clkctl |= hunt_s->a11clk_src_div;
255 writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
256
257 /* Program clock source selection */
258 reg_clksel = readl(A11S_CLK_SEL_ADDR);
259 reg_clksel |= 1; /* CLK_SEL_SRC1NO == SRC1 */
260 writel(reg_clksel, A11S_CLK_SEL_ADDR);
261 } else {
262 /* SRC1 */
263
264 /* Program clock source */
265 reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
266 reg_clkctl &= ~(0x07 << 12);
267 reg_clkctl |= (hunt_s->a11clk_src_sel << 12);
268 writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
269
270 /* Program clock divider */
271 reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
272 reg_clkctl &= ~(0xf << 8);
273 reg_clkctl |= (hunt_s->a11clk_src_div << 8);
274 writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
275
276 /* Program clock source selection */
277 reg_clksel = readl(A11S_CLK_SEL_ADDR);
278 reg_clksel &= ~1; /* CLK_SEL_SRC1NO == SRC0 */
279 writel(reg_clksel, A11S_CLK_SEL_ADDR);
280 }
281
282 /*
283 * If the new clock divider is lower than the previous, then
284 * program the divider after switching the clock
285 */
286 if (hunt_s->ahbclk_div < clk_div) {
287 reg_clksel = readl(A11S_CLK_SEL_ADDR);
288 reg_clksel &= ~(0x3 << 1);
289 reg_clksel |= (hunt_s->ahbclk_div << 1);
290 writel(reg_clksel, A11S_CLK_SEL_ADDR);
291 }
292}
293
294int acpuclk_set_rate(unsigned long rate, int for_power_collapse)
295{
296 uint32_t reg_clkctl;
297 struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s;
298 int rc = 0;
299 unsigned int plls_enabled = 0, pll;
300
301 strt_s = cur_s = drv_state.current_speed;
302
303 WARN_ONCE(cur_s == NULL, "acpuclk_set_rate: not initialized\n");
304 if (cur_s == NULL)
305 return -ENOENT;
306
307 if (rate == (cur_s->a11clk_khz * 1000))
308 return 0;
309
310 for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) {
311 if (tgt_s->a11clk_khz == (rate / 1000))
312 break;
313 }
314
315 if (tgt_s->a11clk_khz == 0)
316 return -EINVAL;
317
318 /* Choose the highest speed speed at or below 'rate' with same PLL. */
319 if (for_power_collapse && tgt_s->a11clk_khz < cur_s->a11clk_khz) {
320 while (tgt_s->pll != ACPU_PLL_TCXO && tgt_s->pll != cur_s->pll)
321 tgt_s--;
322 }
323
324 if (strt_s->pll != ACPU_PLL_TCXO)
325 plls_enabled |= 1 << strt_s->pll;
326
327 if (!for_power_collapse) {
328 mutex_lock(&drv_state.lock);
329 if (strt_s->pll != tgt_s->pll && tgt_s->pll != ACPU_PLL_TCXO) {
330 rc = pc_pll_request(tgt_s->pll, 1);
331 if (rc < 0) {
332 pr_err("PLL%d enable failed (%d)\n",
333 tgt_s->pll, rc);
334 goto out;
335 }
336 plls_enabled |= 1 << tgt_s->pll;
337 }
338 /* Increase VDD if needed. */
339 if (tgt_s->vdd > cur_s->vdd) {
340 if ((rc = acpuclk_set_vdd_level(tgt_s->vdd)) < 0) {
341 printk(KERN_ERR "Unable to switch ACPU vdd\n");
342 goto out;
343 }
344 }
345 }
346
347 /* Set wait states for CPU inbetween frequency changes */
348 reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
349 reg_clkctl |= (100 << 16); /* set WT_ST_CNT */
350 writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
351
352#if PERF_SWITCH_DEBUG
353 printk(KERN_INFO "acpuclock: Switching from ACPU rate %u -> %u\n",
354 strt_s->a11clk_khz * 1000, tgt_s->a11clk_khz * 1000);
355#endif
356
357 while (cur_s != tgt_s) {
358 /*
359 * Always jump to target freq if within 256mhz, regulardless of
360 * PLL. If differnece is greater, use the predefinied
361 * steppings in the table.
362 */
363 int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz));
364 if (d > drv_state.max_speed_delta_khz) {
365 /* Step up or down depending on target vs current. */
366 int clk_index = tgt_s->a11clk_khz > cur_s->a11clk_khz ?
367 cur_s->up : cur_s->down;
368 if (clk_index < 0) { /* This should not happen. */
369 printk(KERN_ERR "cur:%u target: %u\n",
370 cur_s->a11clk_khz, tgt_s->a11clk_khz);
371 rc = -EINVAL;
372 goto out;
373 }
374 cur_s = &acpu_freq_tbl[clk_index];
375 } else {
376 cur_s = tgt_s;
377 }
378#if PERF_SWITCH_STEP_DEBUG
379 printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n",
380 __FUNCTION__, cur_s->a11clk_khz, cur_s->pll);
381#endif
382 if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO
383 && !(plls_enabled & (1 << cur_s->pll))) {
384 rc = pc_pll_request(cur_s->pll, 1);
385 if (rc < 0) {
386 pr_err("PLL%d enable failed (%d)\n",
387 cur_s->pll, rc);
388 goto out;
389 }
390 plls_enabled |= 1 << cur_s->pll;
391 }
392
393 acpuclk_set_div(cur_s);
394 drv_state.current_speed = cur_s;
395 /* Re-adjust lpj for the new clock speed. */
396 loops_per_jiffy = cur_s->lpj;
397 udelay(drv_state.acpu_switch_time_us);
398 }
399
400 /* Nothing else to do for power collapse. */
401 if (for_power_collapse)
402 return 0;
403
404 /* Disable PLLs we are not using anymore. */
405 plls_enabled &= ~(1 << tgt_s->pll);
406 for (pll = ACPU_PLL_0; pll <= ACPU_PLL_2; pll++)
407 if (plls_enabled & (1 << pll)) {
408 rc = pc_pll_request(pll, 0);
409 if (rc < 0) {
410 pr_err("PLL%d disable failed (%d)\n", pll, rc);
411 goto out;
412 }
413 }
414
415 /* Change the AXI bus frequency if we can. */
416 if (strt_s->axiclk_khz != tgt_s->axiclk_khz) {
417 rc = clk_set_rate(ebi1_clk, tgt_s->axiclk_khz * 1000);
418 if (rc < 0)
419 pr_err("Setting AXI min rate failed!\n");
420 }
421
422 /* Drop VDD level if we can. */
423 if (tgt_s->vdd < strt_s->vdd) {
424 if (acpuclk_set_vdd_level(tgt_s->vdd) < 0)
425 printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd\n");
426 }
427
428#if PERF_SWITCH_DEBUG
429 printk(KERN_DEBUG "%s: ACPU speed change complete\n", __FUNCTION__);
430#endif
431out:
432 if (!for_power_collapse)
433 mutex_unlock(&drv_state.lock);
434 return rc;
435}
436
437static void __init acpuclk_init(void)
438{
439 struct clkctl_acpu_speed *speed;
440 uint32_t div, sel;
441 int rc;
442
443 /*
444 * Determine the rate of ACPU clock
445 */
446
447 if (!(readl(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */
448 /* CLK_SRC0_SEL */
449 sel = (readl(A11S_CLK_CNTL_ADDR) >> 12) & 0x7;
450 /* CLK_SRC0_DIV */
451 div = (readl(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f;
452 } else {
453 /* CLK_SRC1_SEL */
454 sel = (readl(A11S_CLK_CNTL_ADDR) >> 4) & 0x07;
455 /* CLK_SRC1_DIV */
456 div = readl(A11S_CLK_CNTL_ADDR) & 0x0f;
457 }
458
459 for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) {
460 if (speed->a11clk_src_sel == sel
461 && (speed->a11clk_src_div == div))
462 break;
463 }
464 if (speed->a11clk_khz == 0) {
465 printk(KERN_WARNING "Warning - ACPU clock reports invalid speed\n");
466 return;
467 }
468
469 drv_state.current_speed = speed;
470
471 rc = clk_set_rate(ebi1_clk, speed->axiclk_khz * 1000);
472 if (rc < 0)
473 pr_err("Setting AXI min rate failed!\n");
474
475 printk(KERN_INFO "ACPU running at %d KHz\n", speed->a11clk_khz);
476}
477
478unsigned long acpuclk_get_rate(void)
479{
480 WARN_ONCE(drv_state.current_speed == NULL,
481 "acpuclk_get_rate: not initialized\n");
482 if (drv_state.current_speed)
483 return drv_state.current_speed->a11clk_khz;
484 else
485 return 0;
486}
487
488uint32_t acpuclk_get_switch_time(void)
489{
490 return drv_state.acpu_switch_time_us;
491}
492
493/*----------------------------------------------------------------------------
494 * Clock driver initialization
495 *---------------------------------------------------------------------------*/
496
497/* Initalize the lpj field in the acpu_freq_tbl. */
498static void __init lpj_init(void)
499{
500 int i;
501 const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
502 for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
503 acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
504 base_clk->a11clk_khz,
505 acpu_freq_tbl[i].a11clk_khz);
506 }
507}
508
509void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
510{
511 pr_info("acpu_clock_init()\n");
512
513 ebi1_clk = clk_get(NULL, "ebi1_clk");
514
515 mutex_init(&drv_state.lock);
516 drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us;
517 drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz;
518 drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
519 drv_state.power_collapse_khz = clkdata->power_collapse_khz;
520 drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz;
521 acpuclk_init();
522 lpj_init();
523#ifdef CONFIG_CPU_FREQ_TABLE
524 cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
525#endif
526}
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
new file mode 100644
index 000000000000..415de2eb9a5e
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -0,0 +1,32 @@
1/* arch/arm/mach-msm/acpuclock.h
2 *
3 * MSM architecture clock driver header
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Copyright (c) 2007 QUALCOMM Incorporated
7 * Author: San Mehat <san@android.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_H
21#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_H
22
23int acpuclk_set_rate(unsigned long rate, int for_power_collapse);
24unsigned long acpuclk_get_rate(void);
25uint32_t acpuclk_get_switch_time(void);
26unsigned long acpuclk_wait_for_irq(void);
27unsigned long acpuclk_power_collapse(void);
28unsigned long acpuclk_get_wfi_rate(void);
29
30
31#endif
32
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index e61967dde9a1..7bd72e8f127e 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -26,6 +26,7 @@
26#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
27#include <asm/mach/map.h> 27#include <asm/mach/map.h>
28#include <asm/mach/flash.h> 28#include <asm/mach/flash.h>
29#include <asm/setup.h>
29 30
30#include <mach/irqs.h> 31#include <mach/irqs.h>
31#include <mach/board.h> 32#include <mach/board.h>
@@ -77,14 +78,28 @@ static void __init halibut_init(void)
77 platform_add_devices(devices, ARRAY_SIZE(devices)); 78 platform_add_devices(devices, ARRAY_SIZE(devices));
78} 79}
79 80
81static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
82 char **cmdline, struct meminfo *mi)
83{
84 mi->nr_banks=1;
85 mi->bank[0].start = PHYS_OFFSET;
86 mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
87 mi->bank[0].size = (101*1024*1024);
88}
89
80static void __init halibut_map_io(void) 90static void __init halibut_map_io(void)
81{ 91{
82 msm_map_common_io(); 92 msm_map_common_io();
83 msm_clock_init(); 93 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
84} 94}
85 95
86MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") 96MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
97#ifdef CONFIG_MSM_DEBUG_UART
98 .phys_io = MSM_DEBUG_UART_PHYS,
99 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
100#endif
87 .boot_params = 0x10000100, 101 .boot_params = 0x10000100,
102 .fixup = halibut_fixup,
88 .map_io = halibut_map_io, 103 .map_io = halibut_map_io,
89 .init_irq = halibut_init_irq, 104 .init_irq = halibut_init_irq,
90 .init_machine = halibut_init, 105 .init_machine = halibut_init,
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
new file mode 100644
index 000000000000..bcbefdfe7b5e
--- /dev/null
+++ b/arch/arm/mach-msm/board-mahimahi.c
@@ -0,0 +1,87 @@
1/* linux/arch/arm/mach-msm/board-mahimahi.c
2 *
3 * Copyright (C) 2009 Google, Inc.
4 * Copyright (C) 2009 HTC Corporation.
5 * Author: Dima Zavin <dima@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/delay.h>
19#include <linux/gpio.h>
20#include <linux/init.h>
21#include <linux/input.h>
22#include <linux/io.h>
23#include <linux/kernel.h>
24#include <linux/platform_device.h>
25
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/setup.h>
30
31#include <mach/board.h>
32#include <mach/hardware.h>
33#include <mach/system.h>
34
35#include "board-mahimahi.h"
36#include "devices.h"
37#include "proc_comm.h"
38
39static uint debug_uart;
40
41module_param_named(debug_uart, debug_uart, uint, 0);
42
43static struct platform_device *devices[] __initdata = {
44#if !defined(CONFIG_MSM_SERIAL_DEBUGGER)
45 &msm_device_uart1,
46#endif
47 &msm_device_uart_dm1,
48 &msm_device_nand,
49};
50
51static void __init mahimahi_init(void)
52{
53 platform_add_devices(devices, ARRAY_SIZE(devices));
54}
55
56static void __init mahimahi_fixup(struct machine_desc *desc, struct tag *tags,
57 char **cmdline, struct meminfo *mi)
58{
59 mi->nr_banks = 2;
60 mi->bank[0].start = PHYS_OFFSET;
61 mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
62 mi->bank[0].size = (219*1024*1024);
63 mi->bank[1].start = MSM_HIGHMEM_BASE;
64 mi->bank[1].node = PHYS_TO_NID(MSM_HIGHMEM_BASE);
65 mi->bank[1].size = MSM_HIGHMEM_SIZE;
66}
67
68static void __init mahimahi_map_io(void)
69{
70 msm_map_common_io();
71 msm_clock_init();
72}
73
74extern struct sys_timer msm_timer;
75
76MACHINE_START(MAHIMAHI, "mahimahi")
77#ifdef CONFIG_MSM_DEBUG_UART
78 .phys_io = MSM_DEBUG_UART_PHYS,
79 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
80#endif
81 .boot_params = 0x20000100,
82 .fixup = mahimahi_fixup,
83 .map_io = mahimahi_map_io,
84 .init_irq = msm_init_irq,
85 .init_machine = mahimahi_init,
86 .timer = &msm_timer,
87MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
new file mode 100644
index 000000000000..cccb9f3c9d01
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -0,0 +1,179 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/input.h>
21#include <linux/io.h>
22#include <linux/delay.h>
23#include <linux/bootmem.h>
24#include <linux/power_supply.h>
25
26#include <mach/hardware.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/mach/flash.h>
31#include <asm/setup.h>
32#ifdef CONFIG_CACHE_L2X0
33#include <asm/hardware/cache-l2x0.h>
34#endif
35
36#include <mach/vreg.h>
37#include <mach/mpp.h>
38#include <mach/gpio.h>
39#include <mach/board.h>
40#include <mach/msm_iomap.h>
41
42#include <linux/mtd/nand.h>
43#include <linux/mtd/partitions.h>
44
45#include "devices.h"
46#include "socinfo.h"
47#include "clock.h"
48
49static struct resource smc91x_resources[] = {
50 [0] = {
51 .start = 0x9C004300,
52 .end = 0x9C0043ff,
53 .flags = IORESOURCE_MEM,
54 },
55 [1] = {
56 .start = MSM_GPIO_TO_INT(132),
57 .end = MSM_GPIO_TO_INT(132),
58 .flags = IORESOURCE_IRQ,
59 },
60};
61
62static struct platform_device smc91x_device = {
63 .name = "smc91x",
64 .id = 0,
65 .num_resources = ARRAY_SIZE(smc91x_resources),
66 .resource = smc91x_resources,
67};
68
69static struct platform_device *devices[] __initdata = {
70 &msm_device_uart3,
71 &msm_device_smd,
72 &msm_device_dmov,
73 &msm_device_nand,
74 &smc91x_device,
75};
76
77extern struct sys_timer msm_timer;
78
79static void __init msm7x2x_init_irq(void)
80{
81 msm_init_irq();
82}
83
84static void __init msm7x2x_init(void)
85{
86 if (socinfo_init() < 0)
87 BUG();
88
89 if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) {
90 smc91x_resources[0].start = 0x98000300;
91 smc91x_resources[0].end = 0x980003ff;
92 smc91x_resources[1].start = MSM_GPIO_TO_INT(85);
93 smc91x_resources[1].end = MSM_GPIO_TO_INT(85);
94 if (gpio_tlmm_config(GPIO_CFG(85, 0,
95 GPIO_INPUT,
96 GPIO_PULL_DOWN,
97 GPIO_2MA),
98 GPIO_ENABLE)) {
99 printk(KERN_ERR
100 "%s: Err: Config GPIO-85 INT\n",
101 __func__);
102 }
103 }
104
105 platform_add_devices(devices, ARRAY_SIZE(devices));
106}
107
108static void __init msm7x2x_map_io(void)
109{
110 msm_map_common_io();
111 /* Technically dependent on the SoC but using machine_is
112 * macros since socinfo is not available this early and there
113 * are plans to restructure the code which will eliminate the
114 * need for socinfo.
115 */
116 if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa())
117 msm_clock_init(msm_clocks_7x27, msm_num_clocks_7x27);
118
119 if (machine_is_msm7x25_surf() || machine_is_msm7x25_ffa())
120 msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25);
121
122#ifdef CONFIG_CACHE_L2X0
123 if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) {
124 /* 7x27 has 256KB L2 cache:
125 64Kb/Way and 4-Way Associativity;
126 R/W latency: 3 cycles;
127 evmon/parity/share disabled. */
128 l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000);
129 }
130#endif
131}
132
133MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
134#ifdef CONFIG_MSM_DEBUG_UART
135 .phys_io = MSM_DEBUG_UART_PHYS,
136 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
137#endif
138 .boot_params = PHYS_OFFSET + 0x100,
139 .map_io = msm7x2x_map_io,
140 .init_irq = msm7x2x_init_irq,
141 .init_machine = msm7x2x_init,
142 .timer = &msm_timer,
143MACHINE_END
144
145MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
146#ifdef CONFIG_MSM_DEBUG_UART
147 .phys_io = MSM_DEBUG_UART_PHYS,
148 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
149#endif
150 .boot_params = PHYS_OFFSET + 0x100,
151 .map_io = msm7x2x_map_io,
152 .init_irq = msm7x2x_init_irq,
153 .init_machine = msm7x2x_init,
154 .timer = &msm_timer,
155MACHINE_END
156
157MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
158#ifdef CONFIG_MSM_DEBUG_UART
159 .phys_io = MSM_DEBUG_UART_PHYS,
160 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
161#endif
162 .boot_params = PHYS_OFFSET + 0x100,
163 .map_io = msm7x2x_map_io,
164 .init_irq = msm7x2x_init_irq,
165 .init_machine = msm7x2x_init,
166 .timer = &msm_timer,
167MACHINE_END
168
169MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
170#ifdef CONFIG_MSM_DEBUG_UART
171 .phys_io = MSM_DEBUG_UART_PHYS,
172 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
173#endif
174 .boot_params = PHYS_OFFSET + 0x100,
175 .map_io = msm7x2x_map_io,
176 .init_irq = msm7x2x_init_irq,
177 .init_machine = msm7x2x_init,
178 .timer = &msm_timer,
179MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
new file mode 100644
index 000000000000..bac1f3c38a3b
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -0,0 +1,120 @@
1/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/irq.h>
20#include <linux/gpio.h>
21#include <linux/platform_device.h>
22#include <linux/delay.h>
23#include <linux/bootmem.h>
24#include <linux/io.h>
25#include <linux/smsc911x.h>
26
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/setup.h>
30
31#include <mach/gpio.h>
32#include <mach/board.h>
33#include <mach/memory.h>
34#include <mach/msm_iomap.h>
35#include <mach/dma.h>
36
37#include <mach/vreg.h>
38#include "devices.h"
39#include "proc_comm.h"
40
41extern struct sys_timer msm_timer;
42
43#ifdef CONFIG_SERIAL_MSM_CONSOLE
44static struct msm_gpio uart2_config_data[] = {
45 { GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"},
46 { GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"},
47 { GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
48 { GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
49};
50
51static void msm7x30_init_uart2(void)
52{
53 msm_gpios_request_enable(uart2_config_data,
54 ARRAY_SIZE(uart2_config_data));
55
56}
57#endif
58
59static struct platform_device *devices[] __initdata = {
60#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
61 &msm_device_uart2,
62#endif
63
64};
65
66static void __init msm7x30_init_irq(void)
67{
68 msm_init_irq();
69}
70
71static void __init msm7x30_init(void)
72{
73 platform_add_devices(devices, ARRAY_SIZE(devices));
74#ifdef CONFIG_SERIAL_MSM_CONSOLE
75 msm7x30_init_uart2();
76#endif
77
78}
79
80static void __init msm7x30_map_io(void)
81{
82 msm_map_msm7x30_io();
83 msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
84}
85
86MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
87#ifdef CONFIG_MSM_DEBUG_UART
88 .phys_io = MSM_DEBUG_UART_PHYS,
89 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
90#endif
91 .boot_params = PHYS_OFFSET + 0x100,
92 .map_io = msm7x30_map_io,
93 .init_irq = msm7x30_init_irq,
94 .init_machine = msm7x30_init,
95 .timer = &msm_timer,
96MACHINE_END
97
98MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
99#ifdef CONFIG_MSM_DEBUG_UART
100 .phys_io = MSM_DEBUG_UART_PHYS,
101 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
102#endif
103 .boot_params = PHYS_OFFSET + 0x100,
104 .map_io = msm7x30_map_io,
105 .init_irq = msm7x30_init_irq,
106 .init_machine = msm7x30_init,
107 .timer = &msm_timer,
108MACHINE_END
109
110MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
111#ifdef CONFIG_MSM_DEBUG_UART
112 .phys_io = MSM_DEBUG_UART_PHYS,
113 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
114#endif
115 .boot_params = PHYS_OFFSET + 0x100,
116 .map_io = msm7x30_map_io,
117 .init_irq = msm7x30_init_irq,
118 .init_machine = msm7x30_init,
119 .timer = &msm_timer,
120MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
new file mode 100644
index 000000000000..ec4606643d2c
--- /dev/null
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -0,0 +1,94 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/irq.h>
20#include <linux/gpio.h>
21#include <linux/platform_device.h>
22#include <linux/bootmem.h>
23#include <linux/delay.h>
24
25#include <asm/mach-types.h>
26#include <asm/mach/arch.h>
27#include <asm/io.h>
28#include <asm/setup.h>
29
30#include <mach/board.h>
31#include <mach/irqs.h>
32#include <mach/sirc.h>
33#include <mach/gpio.h>
34
35#include "devices.h"
36
37extern struct sys_timer msm_timer;
38
39static struct msm_gpio uart3_config_data[] = {
40 { GPIO_CFG(86, 1, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
41 { GPIO_CFG(87, 1, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
42};
43
44static struct platform_device *devices[] __initdata = {
45 &msm_device_uart3,
46};
47
48static void msm8x50_init_uart3(void)
49{
50 msm_gpios_request_enable(uart3_config_data,
51 ARRAY_SIZE(uart3_config_data));
52}
53
54static void __init qsd8x50_map_io(void)
55{
56 msm_map_qsd8x50_io();
57 msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);
58}
59
60static void __init qsd8x50_init_irq(void)
61{
62 msm_init_irq();
63 msm_init_sirc();
64}
65
66static void __init qsd8x50_init(void)
67{
68 msm8x50_init_uart3();
69 platform_add_devices(devices, ARRAY_SIZE(devices));
70}
71
72MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
73#ifdef CONFIG_MSM_DEBUG_UART
74 .phys_io = MSM_DEBUG_UART_PHYS,
75 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
76#endif
77 .boot_params = PHYS_OFFSET + 0x100,
78 .map_io = qsd8x50_map_io,
79 .init_irq = qsd8x50_init_irq,
80 .init_machine = qsd8x50_init,
81 .timer = &msm_timer,
82MACHINE_END
83
84MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
85#ifdef CONFIG_MSM_DEBUG_UART
86 .phys_io = MSM_DEBUG_UART_PHYS,
87 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
88#endif
89 .boot_params = PHYS_OFFSET + 0x100,
90 .map_io = qsd8x50_map_io,
91 .init_irq = qsd8x50_init_irq,
92 .init_machine = qsd8x50_init,
93 .timer = &msm_timer,
94MACHINE_END
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
new file mode 100644
index 000000000000..2bc1b9d5623e
--- /dev/null
+++ b/arch/arm/mach-msm/board-sapphire.c
@@ -0,0 +1,118 @@
1/* linux/arch/arm/mach-msm/board-sapphire.c
2 * Copyright (C) 2007-2009 HTC Corporation.
3 * Author: Thomas Tsai <thomas_tsai@htc.com>
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 <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/input.h>
19#include <linux/interrupt.h>
20#include <linux/irq.h>
21#include <linux/sysdev.h>
22
23#include <linux/delay.h>
24
25#include <asm/gpio.h>
26#include <mach/hardware.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/mach/flash.h>
31#include <asm/system.h>
32#include <mach/system.h>
33#include <mach/vreg.h>
34#include <mach/board.h>
35
36#include <asm/io.h>
37#include <asm/delay.h>
38#include <asm/setup.h>
39
40#include <linux/mtd/nand.h>
41#include <linux/mtd/partitions.h>
42
43#include "gpio_chip.h"
44#include "board-sapphire.h"
45#include "proc_comm.h"
46#include "devices.h"
47
48void msm_init_irq(void);
49void msm_init_gpio(void);
50
51static struct platform_device *devices[] __initdata = {
52 &msm_device_smd,
53 &msm_device_dmov,
54 &msm_device_nand,
55 &msm_device_uart1,
56 &msm_device_uart3,
57};
58
59extern struct sys_timer msm_timer;
60
61static void __init sapphire_init_irq(void)
62{
63 msm_init_irq();
64}
65
66static void __init sapphire_init(void)
67{
68 platform_add_devices(devices, ARRAY_SIZE(devices));
69}
70
71static struct map_desc sapphire_io_desc[] __initdata = {
72 {
73 .virtual = SAPPHIRE_CPLD_BASE,
74 .pfn = __phys_to_pfn(SAPPHIRE_CPLD_START),
75 .length = SAPPHIRE_CPLD_SIZE,
76 .type = MT_DEVICE_NONSHARED
77 }
78};
79
80static void __init sapphire_fixup(struct machine_desc *desc, struct tag *tags,
81 char **cmdline, struct meminfo *mi)
82{
83 int smi_sz = parse_tag_smi((const struct tag *)tags);
84
85 mi->nr_banks = 1;
86 mi->bank[0].start = PHYS_OFFSET;
87 mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
88 if (smi_sz == 32) {
89 mi->bank[0].size = (84*1024*1024);
90 } else if (smi_sz == 64) {
91 mi->bank[0].size = (101*1024*1024);
92 } else {
93 /* Give a default value when not get smi size */
94 smi_sz = 64;
95 mi->bank[0].size = (101*1024*1024);
96 }
97}
98
99static void __init sapphire_map_io(void)
100{
101 msm_map_common_io();
102 iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc));
103 msm_clock_init();
104}
105
106MACHINE_START(SAPPHIRE, "sapphire")
107/* Maintainer: Brian Swetland <swetland@google.com> */
108#ifdef CONFIG_MSM_DEBUG_UART
109 .phys_io = MSM_DEBUG_UART_PHYS,
110 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
111#endif
112 .boot_params = PHYS_OFFSET + 0x100,
113 .fixup = sapphire_fixup,
114 .map_io = sapphire_map_io,
115 .init_irq = sapphire_init_irq,
116 .init_machine = sapphire_init,
117 .timer = &msm_timer,
118MACHINE_END
diff --git a/arch/arm/mach-msm/board-dream.c b/arch/arm/mach-msm/board-trout.c
index 21afa8513168..dca5a5f062dc 100644
--- a/arch/arm/mach-msm/board-dream.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-msm/board-dream.c 1/* linux/arch/arm/mach-msm/board-trout.c
2 * 2 *
3 * Copyright (C) 2009 Google, Inc. 3 * Copyright (C) 2009 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com> 4 * Author: Brian Swetland <swetland@google.com>
@@ -28,7 +28,7 @@
28#include <mach/msm_iomap.h> 28#include <mach/msm_iomap.h>
29 29
30#include "devices.h" 30#include "devices.h"
31#include "board-dream.h" 31#include "board-trout.h"
32 32
33static struct platform_device *devices[] __initdata = { 33static struct platform_device *devices[] __initdata = {
34 &msm_device_uart3, 34 &msm_device_uart3,
@@ -78,12 +78,14 @@ static void __init trout_map_io(void)
78 writeb(0x80, TROUT_CPLD_BASE + 0x00); 78 writeb(0x80, TROUT_CPLD_BASE + 0x00);
79#endif 79#endif
80 80
81 msm_clock_init(); 81 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
82} 82}
83 83
84MACHINE_START(TROUT, "HTC Dream") 84MACHINE_START(TROUT, "HTC Dream")
85#ifdef CONFIG_MSM_DEBUG_UART
85 .phys_io = MSM_DEBUG_UART_PHYS, 86 .phys_io = MSM_DEBUG_UART_PHYS,
86 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, 87 .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
88#endif
87 .boot_params = 0x10000100, 89 .boot_params = 0x10000100,
88 .fixup = trout_fixup, 90 .fixup = trout_fixup,
89 .map_io = trout_map_io, 91 .map_io = trout_map_io,
diff --git a/arch/arm/mach-msm/board-dream.h b/arch/arm/mach-msm/board-trout.h
index 4f345a5a0a61..4f345a5a0a61 100644
--- a/arch/arm/mach-msm/board-dream.h
+++ b/arch/arm/mach-msm/board-trout.h
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c
deleted file mode 100644
index 62230a3428ee..000000000000
--- a/arch/arm/mach-msm/clock-7x01a.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/* arch/arm/mach-msm/clock-7x01a.c
2 *
3 * Clock tables for MSM7X01A
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Copyright (c) 2007 QUALCOMM Incorporated
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/platform_device.h>
21
22#include "clock.h"
23#include "devices.h"
24
25/* clock IDs used by the modem processor */
26
27#define ACPU_CLK 0 /* Applications processor clock */
28#define ADM_CLK 1 /* Applications data mover clock */
29#define ADSP_CLK 2 /* ADSP clock */
30#define EBI1_CLK 3 /* External bus interface 1 clock */
31#define EBI2_CLK 4 /* External bus interface 2 clock */
32#define ECODEC_CLK 5 /* External CODEC clock */
33#define EMDH_CLK 6 /* External MDDI host clock */
34#define GP_CLK 7 /* General purpose clock */
35#define GRP_CLK 8 /* Graphics clock */
36#define I2C_CLK 9 /* I2C clock */
37#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
38#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
39#define IMEM_CLK 12 /* Internal graphics memory clock */
40#define MDC_CLK 13 /* MDDI client clock */
41#define MDP_CLK 14 /* Mobile display processor clock */
42#define PBUS_CLK 15 /* Peripheral bus clock */
43#define PCM_CLK 16 /* PCM clock */
44#define PMDH_CLK 17 /* Primary MDDI host clock */
45#define SDAC_CLK 18 /* Stereo DAC clock */
46#define SDC1_CLK 19 /* Secure Digital Card clocks */
47#define SDC1_PCLK 20
48#define SDC2_CLK 21
49#define SDC2_PCLK 22
50#define SDC3_CLK 23
51#define SDC3_PCLK 24
52#define SDC4_CLK 25
53#define SDC4_PCLK 26
54#define TSIF_CLK 27 /* Transport Stream Interface clocks */
55#define TSIF_REF_CLK 28
56#define TV_DAC_CLK 29 /* TV clocks */
57#define TV_ENC_CLK 30
58#define UART1_CLK 31 /* UART clocks */
59#define UART2_CLK 32
60#define UART3_CLK 33
61#define UART1DM_CLK 34
62#define UART2DM_CLK 35
63#define USB_HS_CLK 36 /* High speed USB core clock */
64#define USB_HS_PCLK 37 /* High speed USB pbus clock */
65#define USB_OTG_CLK 38 /* Full speed USB clock */
66#define VDC_CLK 39 /* Video controller clock */
67#define VFE_CLK 40 /* Camera / Video Front End clock */
68#define VFE_MDC_CLK 41 /* VFE MDDI client clock */
69
70#define NR_CLKS 42
71
72#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \
73 .name = clk_name, \
74 .id = clk_id, \
75 .flags = clk_flags, \
76 .dev = clk_dev, \
77 }
78
79#define OFF CLKFLAG_AUTO_OFF
80#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
81
82struct clk msm_clocks[] = {
83 CLOCK("adm_clk", ADM_CLK, NULL, 0),
84 CLOCK("adsp_clk", ADSP_CLK, NULL, 0),
85 CLOCK("ebi1_clk", EBI1_CLK, NULL, 0),
86 CLOCK("ebi2_clk", EBI2_CLK, NULL, 0),
87 CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0),
88 CLOCK("emdh_clk", EMDH_CLK, NULL, OFF),
89 CLOCK("gp_clk", GP_CLK, NULL, 0),
90 CLOCK("grp_clk", GRP_CLK, NULL, OFF),
91 CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0),
92 CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
93 CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
94 CLOCK("imem_clk", IMEM_CLK, NULL, OFF),
95 CLOCK("mdc_clk", MDC_CLK, NULL, 0),
96 CLOCK("mdp_clk", MDP_CLK, NULL, OFF),
97 CLOCK("pbus_clk", PBUS_CLK, NULL, 0),
98 CLOCK("pcm_clk", PCM_CLK, NULL, 0),
99 CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX),
100 CLOCK("sdac_clk", SDAC_CLK, NULL, OFF),
101 CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
102 CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF),
103 CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF),
104 CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF),
105 CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF),
106 CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF),
107 CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF),
108 CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF),
109 CLOCK("tsif_clk", TSIF_CLK, NULL, 0),
110 CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
111 CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0),
112 CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0),
113 CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF),
114 CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
115 CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
116 CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF),
117 CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0),
118 CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF),
119 CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF),
120 CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0),
121 CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX),
122 CLOCK("vfe_clk", VFE_CLK, NULL, OFF),
123 CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
124};
125
126unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);
diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h
new file mode 100644
index 000000000000..e16f72f32829
--- /dev/null
+++ b/arch/arm/mach-msm/clock-7x30.h
@@ -0,0 +1,168 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
31#define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
32
33enum {
34 L_7X30_NONE_CLK = -1,
35 L_7X30_ADM_CLK,
36 L_7X30_I2C_CLK,
37 L_7X30_I2C_2_CLK,
38 L_7X30_QUP_I2C_CLK,
39 L_7X30_UART1DM_CLK,
40 L_7X30_UART1DM_P_CLK,
41 L_7X30_UART2DM_CLK,
42 L_7X30_UART2DM_P_CLK,
43 L_7X30_EMDH_CLK,
44 L_7X30_EMDH_P_CLK,
45 L_7X30_PMDH_CLK,
46 L_7X30_PMDH_P_CLK,
47 L_7X30_GRP_2D_CLK,
48 L_7X30_GRP_2D_P_CLK,
49 L_7X30_GRP_3D_SRC_CLK,
50 L_7X30_GRP_3D_CLK,
51 L_7X30_GRP_3D_P_CLK,
52 L_7X30_IMEM_CLK,
53 L_7X30_SDC1_CLK,
54 L_7X30_SDC1_P_CLK,
55 L_7X30_SDC2_CLK,
56 L_7X30_SDC2_P_CLK,
57 L_7X30_SDC3_CLK,
58 L_7X30_SDC3_P_CLK,
59 L_7X30_SDC4_CLK,
60 L_7X30_SDC4_P_CLK,
61 L_7X30_MDP_CLK,
62 L_7X30_MDP_P_CLK,
63 L_7X30_MDP_LCDC_PCLK_CLK,
64 L_7X30_MDP_LCDC_PAD_PCLK_CLK,
65 L_7X30_MDP_VSYNC_CLK,
66 L_7X30_MI2S_CODEC_RX_M_CLK,
67 L_7X30_MI2S_CODEC_RX_S_CLK,
68 L_7X30_MI2S_CODEC_TX_M_CLK,
69 L_7X30_MI2S_CODEC_TX_S_CLK,
70 L_7X30_MI2S_M_CLK,
71 L_7X30_MI2S_S_CLK,
72 L_7X30_LPA_CODEC_CLK,
73 L_7X30_LPA_CORE_CLK,
74 L_7X30_LPA_P_CLK,
75 L_7X30_MIDI_CLK,
76 L_7X30_MDC_CLK,
77 L_7X30_ROTATOR_IMEM_CLK,
78 L_7X30_ROTATOR_P_CLK,
79 L_7X30_SDAC_M_CLK,
80 L_7X30_SDAC_CLK,
81 L_7X30_UART1_CLK,
82 L_7X30_UART2_CLK,
83 L_7X30_UART3_CLK,
84 L_7X30_TV_CLK,
85 L_7X30_TV_DAC_CLK,
86 L_7X30_TV_ENC_CLK,
87 L_7X30_HDMI_CLK,
88 L_7X30_TSIF_REF_CLK,
89 L_7X30_TSIF_P_CLK,
90 L_7X30_USB_HS_SRC_CLK,
91 L_7X30_USB_HS_CLK,
92 L_7X30_USB_HS_CORE_CLK,
93 L_7X30_USB_HS_P_CLK,
94 L_7X30_USB_HS2_CLK,
95 L_7X30_USB_HS2_CORE_CLK,
96 L_7X30_USB_HS2_P_CLK,
97 L_7X30_USB_HS3_CLK,
98 L_7X30_USB_HS3_CORE_CLK,
99 L_7X30_USB_HS3_P_CLK,
100 L_7X30_VFE_CLK,
101 L_7X30_VFE_P_CLK,
102 L_7X30_VFE_MDC_CLK,
103 L_7X30_VFE_CAMIF_CLK,
104 L_7X30_CAMIF_PAD_P_CLK,
105 L_7X30_CAM_M_CLK,
106 L_7X30_JPEG_CLK,
107 L_7X30_JPEG_P_CLK,
108 L_7X30_VPE_CLK,
109 L_7X30_MFC_CLK,
110 L_7X30_MFC_DIV2_CLK,
111 L_7X30_MFC_P_CLK,
112 L_7X30_SPI_CLK,
113 L_7X30_SPI_P_CLK,
114 L_7X30_CSI0_CLK,
115 L_7X30_CSI0_VFE_CLK,
116 L_7X30_CSI0_P_CLK,
117 L_7X30_CSI1_CLK,
118 L_7X30_CSI1_VFE_CLK,
119 L_7X30_CSI1_P_CLK,
120 L_7X30_GLBL_ROOT_CLK,
121
122 L_7X30_AXI_LI_VG_CLK,
123 L_7X30_AXI_LI_GRP_CLK,
124 L_7X30_AXI_LI_JPEG_CLK,
125 L_7X30_AXI_GRP_2D_CLK,
126 L_7X30_AXI_MFC_CLK,
127 L_7X30_AXI_VPE_CLK,
128 L_7X30_AXI_LI_VFE_CLK,
129 L_7X30_AXI_LI_APPS_CLK,
130 L_7X30_AXI_MDP_CLK,
131 L_7X30_AXI_IMEM_CLK,
132 L_7X30_AXI_LI_ADSP_A_CLK,
133 L_7X30_AXI_ROTATOR_CLK,
134
135 L_7X30_NR_CLKS
136};
137
138struct clk_ops;
139extern struct clk_ops clk_ops_7x30;
140
141struct clk_ops *clk_7x30_is_local(uint32_t id);
142int clk_7x30_init(void);
143
144void pll_enable(uint32_t pll);
145void pll_disable(uint32_t pll);
146
147extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable);
148
149#define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) { \
150 .name = clk_name, \
151 .id = L_7X30_##clk_id, \
152 .remote_id = P_##clk_id, \
153 .flags = clk_flags, \
154 .dev = clk_dev, \
155 .dbg_name = #clk_id, \
156 }
157
158#define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) { \
159 .name = clk_name, \
160 .id = L_7X30_##l_id, \
161 .remote_id = P_##r_id, \
162 .flags = clk_flags, \
163 .dev = clk_dev, \
164 .dbg_name = #l_id, \
165 }
166
167#endif
168
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
new file mode 100644
index 000000000000..a3b45627eb4a
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
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
16#include <linux/err.h>
17#include <linux/ctype.h>
18#include <linux/stddef.h>
19#include <mach/clk.h>
20
21#include "proc_comm.h"
22#include "clock.h"
23
24/*
25 * glue for the proc_comm interface
26 */
27int pc_clk_enable(unsigned id)
28{
29 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
30 if (rc < 0)
31 return rc;
32 else
33 return (int)id < 0 ? -EINVAL : 0;
34}
35
36void pc_clk_disable(unsigned id)
37{
38 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
39}
40
41int pc_clk_reset(unsigned id, enum clk_reset_action action)
42{
43 int rc;
44
45 if (action == CLK_RESET_ASSERT)
46 rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
47 else
48 rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
49
50 if (rc < 0)
51 return rc;
52 else
53 return (int)id < 0 ? -EINVAL : 0;
54}
55
56int pc_clk_set_rate(unsigned id, unsigned rate)
57{
58 /* The rate _might_ be rounded off to the nearest KHz value by the
59 * remote function. So a return value of 0 doesn't necessarily mean
60 * that the exact rate was set successfully.
61 */
62 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
63 if (rc < 0)
64 return rc;
65 else
66 return (int)id < 0 ? -EINVAL : 0;
67}
68
69int pc_clk_set_min_rate(unsigned id, unsigned rate)
70{
71 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
72 if (rc < 0)
73 return rc;
74 else
75 return (int)id < 0 ? -EINVAL : 0;
76}
77
78int pc_clk_set_max_rate(unsigned id, unsigned rate)
79{
80 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
81 if (rc < 0)
82 return rc;
83 else
84 return (int)id < 0 ? -EINVAL : 0;
85}
86
87int pc_clk_set_flags(unsigned id, unsigned flags)
88{
89 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
90 if (rc < 0)
91 return rc;
92 else
93 return (int)id < 0 ? -EINVAL : 0;
94}
95
96unsigned pc_clk_get_rate(unsigned id)
97{
98 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
99 return 0;
100 else
101 return id;
102}
103
104unsigned pc_clk_is_enabled(unsigned id)
105{
106 if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
107 return 0;
108 else
109 return id;
110}
111
112long pc_clk_round_rate(unsigned id, unsigned rate)
113{
114
115 /* Not really supported; pc_clk_set_rate() does rounding on it's own. */
116 return rate;
117}
118
119struct clk_ops clk_ops_pcom = {
120 .enable = pc_clk_enable,
121 .disable = pc_clk_disable,
122 .auto_off = pc_clk_disable,
123 .reset = pc_clk_reset,
124 .set_rate = pc_clk_set_rate,
125 .set_min_rate = pc_clk_set_min_rate,
126 .set_max_rate = pc_clk_set_max_rate,
127 .set_flags = pc_clk_set_flags,
128 .get_rate = pc_clk_get_rate,
129 .is_enabled = pc_clk_is_enabled,
130 .round_rate = pc_clk_round_rate,
131};
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
new file mode 100644
index 000000000000..17d027b23501
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -0,0 +1,153 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
31#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
32
33/* clock IDs used by the modem processor */
34
35#define P_ACPU_CLK 0 /* Applications processor clock */
36#define P_ADM_CLK 1 /* Applications data mover clock */
37#define P_ADSP_CLK 2 /* ADSP clock */
38#define P_EBI1_CLK 3 /* External bus interface 1 clock */
39#define P_EBI2_CLK 4 /* External bus interface 2 clock */
40#define P_ECODEC_CLK 5 /* External CODEC clock */
41#define P_EMDH_CLK 6 /* External MDDI host clock */
42#define P_GP_CLK 7 /* General purpose clock */
43#define P_GRP_3D_CLK 8 /* Graphics clock */
44#define P_I2C_CLK 9 /* I2C clock */
45#define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
46#define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
47#define P_IMEM_CLK 12 /* Internal graphics memory clock */
48#define P_MDC_CLK 13 /* MDDI client clock */
49#define P_MDP_CLK 14 /* Mobile display processor clock */
50#define P_PBUS_CLK 15 /* Peripheral bus clock */
51#define P_PCM_CLK 16 /* PCM clock */
52#define P_PMDH_CLK 17 /* Primary MDDI host clock */
53#define P_SDAC_CLK 18 /* Stereo DAC clock */
54#define P_SDC1_CLK 19 /* Secure Digital Card clocks */
55#define P_SDC1_P_CLK 20
56#define P_SDC2_CLK 21
57#define P_SDC2_P_CLK 22
58#define P_SDC3_CLK 23
59#define P_SDC3_P_CLK 24
60#define P_SDC4_CLK 25
61#define P_SDC4_P_CLK 26
62#define P_TSIF_CLK 27 /* Transport Stream Interface clocks */
63#define P_TSIF_REF_CLK 28
64#define P_TV_DAC_CLK 29 /* TV clocks */
65#define P_TV_ENC_CLK 30
66#define P_UART1_CLK 31 /* UART clocks */
67#define P_UART2_CLK 32
68#define P_UART3_CLK 33
69#define P_UART1DM_CLK 34
70#define P_UART2DM_CLK 35
71#define P_USB_HS_CLK 36 /* High speed USB core clock */
72#define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */
73#define P_USB_OTG_CLK 38 /* Full speed USB clock */
74#define P_VDC_CLK 39 /* Video controller clock */
75#define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */
76#define P_VFE_CLK 41 /* VFE MDDI client clock */
77#define P_MDP_LCDC_PCLK_CLK 42
78#define P_MDP_LCDC_PAD_PCLK_CLK 43
79#define P_MDP_VSYNC_CLK 44
80#define P_SPI_CLK 45
81#define P_VFE_AXI_CLK 46
82#define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */
83#define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */
84#define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */
85#define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */
86#define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */
87#define P_USB_PHY_CLK 52 /* USB PHY clock */
88#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */
89#define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */
90#define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */
91#define P_CAM_M_CLK 56
92#define P_CAMIF_PAD_P_CLK 57
93#define P_GRP_2D_CLK 58
94#define P_GRP_2D_P_CLK 59
95#define P_I2S_CLK 60
96#define P_JPEG_CLK 61
97#define P_JPEG_P_CLK 62
98#define P_LPA_CODEC_CLK 63
99#define P_LPA_CORE_CLK 64
100#define P_LPA_P_CLK 65
101#define P_MDC_IO_CLK 66
102#define P_MDC_P_CLK 67
103#define P_MFC_CLK 68
104#define P_MFC_DIV2_CLK 69
105#define P_MFC_P_CLK 70
106#define P_QUP_I2C_CLK 71
107#define P_ROTATOR_IMEM_CLK 72
108#define P_ROTATOR_P_CLK 73
109#define P_VFE_CAMIF_CLK 74
110#define P_VFE_P_CLK 75
111#define P_VPE_CLK 76
112#define P_I2C_2_CLK 77
113#define P_MI2S_CODEC_RX_S_CLK 78
114#define P_MI2S_CODEC_RX_M_CLK 79
115#define P_MI2S_CODEC_TX_S_CLK 80
116#define P_MI2S_CODEC_TX_M_CLK 81
117#define P_PMDH_P_CLK 82
118#define P_EMDH_P_CLK 83
119#define P_SPI_P_CLK 84
120#define P_TSIF_P_CLK 85
121#define P_MDP_P_CLK 86
122#define P_SDAC_M_CLK 87
123#define P_MI2S_S_CLK 88
124#define P_MI2S_M_CLK 89
125#define P_AXI_ROTATOR_CLK 90
126#define P_HDMI_CLK 91
127#define P_CSI0_CLK 92
128#define P_CSI0_VFE_CLK 93
129#define P_CSI0_P_CLK 94
130#define P_CSI1_CLK 95
131#define P_CSI1_VFE_CLK 96
132#define P_CSI1_P_CLK 97
133#define P_GSBI_CLK 98
134#define P_GSBI_P_CLK 99
135
136#define P_NR_CLKS 100
137
138struct clk_ops;
139extern struct clk_ops clk_ops_pcom;
140
141int pc_clk_reset(unsigned id, enum clk_reset_action action);
142
143#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \
144 .name = clk_name, \
145 .id = P_##clk_id, \
146 .remote_id = P_##clk_id, \
147 .ops = &clk_ops_pcom, \
148 .flags = clk_flags, \
149 .dev = clk_dev, \
150 .dbg_name = #clk_id, \
151 }
152
153#endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 3b1ce36f1032..9cb1276ab749 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
1/* arch/arm/mach-msm/clock.c 1/* arch/arm/mach-msm/clock.c
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007 QUALCOMM Incorporated 4 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -22,68 +22,27 @@
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/debugfs.h>
26#include <linux/ctype.h>
27#include <linux/pm_qos_params.h>
28#include <mach/clk.h>
25 29
26#include "clock.h" 30#include "clock.h"
27#include "proc_comm.h" 31#include "proc_comm.h"
32#include "clock-7x30.h"
28 33
29static DEFINE_MUTEX(clocks_mutex); 34static DEFINE_MUTEX(clocks_mutex);
30static DEFINE_SPINLOCK(clocks_lock); 35static DEFINE_SPINLOCK(clocks_lock);
31static LIST_HEAD(clocks); 36static LIST_HEAD(clocks);
37struct clk *msm_clocks;
38unsigned msm_num_clocks;
32 39
33/* 40/*
34 * glue for the proc_comm interface 41 * Bitmap of enabled clocks, excluding ACPU which is always
42 * enabled
35 */ 43 */
36static inline int pc_clk_enable(unsigned id) 44static DECLARE_BITMAP(clock_map_enabled, NR_CLKS);
37{ 45static DEFINE_SPINLOCK(clock_map_lock);
38 return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
39}
40
41static inline void pc_clk_disable(unsigned id)
42{
43 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
44}
45
46static inline int pc_clk_set_rate(unsigned id, unsigned rate)
47{
48 return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
49}
50
51static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
52{
53 return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
54}
55
56static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
57{
58 return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
59}
60
61static inline int pc_clk_set_flags(unsigned id, unsigned flags)
62{
63 return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
64}
65
66static inline unsigned pc_clk_get_rate(unsigned id)
67{
68 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
69 return 0;
70 else
71 return id;
72}
73
74static inline unsigned pc_clk_is_enabled(unsigned id)
75{
76 if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
77 return 0;
78 else
79 return id;
80}
81
82static inline int pc_pll_request(unsigned id, unsigned on)
83{
84 on = !!on;
85 return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
86}
87 46
88/* 47/*
89 * Standard clock functions defined in include/linux/clk.h 48 * Standard clock functions defined in include/linux/clk.h
@@ -119,8 +78,12 @@ int clk_enable(struct clk *clk)
119 unsigned long flags; 78 unsigned long flags;
120 spin_lock_irqsave(&clocks_lock, flags); 79 spin_lock_irqsave(&clocks_lock, flags);
121 clk->count++; 80 clk->count++;
122 if (clk->count == 1) 81 if (clk->count == 1) {
123 pc_clk_enable(clk->id); 82 clk->ops->enable(clk->id);
83 spin_lock(&clock_map_lock);
84 clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id);
85 spin_unlock(&clock_map_lock);
86 }
124 spin_unlock_irqrestore(&clocks_lock, flags); 87 spin_unlock_irqrestore(&clocks_lock, flags);
125 return 0; 88 return 0;
126} 89}
@@ -132,31 +95,54 @@ void clk_disable(struct clk *clk)
132 spin_lock_irqsave(&clocks_lock, flags); 95 spin_lock_irqsave(&clocks_lock, flags);
133 BUG_ON(clk->count == 0); 96 BUG_ON(clk->count == 0);
134 clk->count--; 97 clk->count--;
135 if (clk->count == 0) 98 if (clk->count == 0) {
136 pc_clk_disable(clk->id); 99 clk->ops->disable(clk->id);
100 spin_lock(&clock_map_lock);
101 clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id);
102 spin_unlock(&clock_map_lock);
103 }
137 spin_unlock_irqrestore(&clocks_lock, flags); 104 spin_unlock_irqrestore(&clocks_lock, flags);
138} 105}
139EXPORT_SYMBOL(clk_disable); 106EXPORT_SYMBOL(clk_disable);
140 107
108int clk_reset(struct clk *clk, enum clk_reset_action action)
109{
110 if (!clk->ops->reset)
111 clk->ops->reset = &pc_clk_reset;
112 return clk->ops->reset(clk->remote_id, action);
113}
114EXPORT_SYMBOL(clk_reset);
115
141unsigned long clk_get_rate(struct clk *clk) 116unsigned long clk_get_rate(struct clk *clk)
142{ 117{
143 return pc_clk_get_rate(clk->id); 118 return clk->ops->get_rate(clk->id);
144} 119}
145EXPORT_SYMBOL(clk_get_rate); 120EXPORT_SYMBOL(clk_get_rate);
146 121
147int clk_set_rate(struct clk *clk, unsigned long rate) 122int clk_set_rate(struct clk *clk, unsigned long rate)
148{ 123{
149 int ret; 124 return clk->ops->set_rate(clk->id, rate);
150 if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
151 ret = pc_clk_set_max_rate(clk->id, rate);
152 if (ret)
153 return ret;
154 return pc_clk_set_min_rate(clk->id, rate);
155 }
156 return pc_clk_set_rate(clk->id, rate);
157} 125}
158EXPORT_SYMBOL(clk_set_rate); 126EXPORT_SYMBOL(clk_set_rate);
159 127
128long clk_round_rate(struct clk *clk, unsigned long rate)
129{
130 return clk->ops->round_rate(clk->id, rate);
131}
132EXPORT_SYMBOL(clk_round_rate);
133
134int clk_set_min_rate(struct clk *clk, unsigned long rate)
135{
136 return clk->ops->set_min_rate(clk->id, rate);
137}
138EXPORT_SYMBOL(clk_set_min_rate);
139
140int clk_set_max_rate(struct clk *clk, unsigned long rate)
141{
142 return clk->ops->set_max_rate(clk->id, rate);
143}
144EXPORT_SYMBOL(clk_set_max_rate);
145
160int clk_set_parent(struct clk *clk, struct clk *parent) 146int clk_set_parent(struct clk *clk, struct clk *parent)
161{ 147{
162 return -ENOSYS; 148 return -ENOSYS;
@@ -173,22 +159,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags)
173{ 159{
174 if (clk == NULL || IS_ERR(clk)) 160 if (clk == NULL || IS_ERR(clk))
175 return -EINVAL; 161 return -EINVAL;
176 return pc_clk_set_flags(clk->id, flags); 162 return clk->ops->set_flags(clk->id, flags);
177} 163}
178EXPORT_SYMBOL(clk_set_flags); 164EXPORT_SYMBOL(clk_set_flags);
179 165
166/* EBI1 is the only shared clock that several clients want to vote on as of
167 * this commit. If this changes in the future, then it might be better to
168 * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
169 * generic to support different clocks.
170 */
171static struct clk *ebi1_clk;
180 172
181void __init msm_clock_init(void) 173static void __init set_clock_ops(struct clk *clk)
174{
175 if (!clk->ops) {
176 clk->ops = &clk_ops_pcom;
177 clk->id = clk->remote_id;
178 }
179}
180
181void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks)
182{ 182{
183 unsigned n; 183 unsigned n;
184 184
185 spin_lock_init(&clocks_lock); 185 spin_lock_init(&clocks_lock);
186 mutex_lock(&clocks_mutex); 186 mutex_lock(&clocks_mutex);
187 for (n = 0; n < msm_num_clocks; n++) 187 msm_clocks = clock_tbl;
188 msm_num_clocks = num_clocks;
189 for (n = 0; n < msm_num_clocks; n++) {
190 set_clock_ops(&msm_clocks[n]);
188 list_add_tail(&msm_clocks[n].list, &clocks); 191 list_add_tail(&msm_clocks[n].list, &clocks);
192 }
189 mutex_unlock(&clocks_mutex); 193 mutex_unlock(&clocks_mutex);
194
195 ebi1_clk = clk_get(NULL, "ebi1_clk");
196 BUG_ON(ebi1_clk == NULL);
197
198}
199
200#if defined(CONFIG_DEBUG_FS)
201static struct clk *msm_clock_get_nth(unsigned index)
202{
203 if (index < msm_num_clocks)
204 return msm_clocks + index;
205 else
206 return 0;
207}
208
209static int clock_debug_rate_set(void *data, u64 val)
210{
211 struct clk *clock = data;
212 int ret;
213
214 /* Only increases to max rate will succeed, but that's actually good
215 * for debugging purposes. So we don't check for error. */
216 if (clock->flags & CLK_MAX)
217 clk_set_max_rate(clock, val);
218 if (clock->flags & CLK_MIN)
219 ret = clk_set_min_rate(clock, val);
220 else
221 ret = clk_set_rate(clock, val);
222 if (ret != 0)
223 printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
224 (clock->flags & CLK_MIN) ? "_min" : "", ret);
225 return ret;
226}
227
228static int clock_debug_rate_get(void *data, u64 *val)
229{
230 struct clk *clock = data;
231 *val = clk_get_rate(clock);
232 return 0;
233}
234
235static int clock_debug_enable_set(void *data, u64 val)
236{
237 struct clk *clock = data;
238 int rc = 0;
239
240 if (val)
241 rc = clock->ops->enable(clock->id);
242 else
243 clock->ops->disable(clock->id);
244
245 return rc;
190} 246}
191 247
248static int clock_debug_enable_get(void *data, u64 *val)
249{
250 struct clk *clock = data;
251
252 *val = clock->ops->is_enabled(clock->id);
253
254 return 0;
255}
256
257static int clock_debug_local_get(void *data, u64 *val)
258{
259 struct clk *clock = data;
260
261 *val = clock->ops != &clk_ops_pcom;
262
263 return 0;
264}
265
266DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
267 clock_debug_rate_set, "%llu\n");
268DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
269 clock_debug_enable_set, "%llu\n");
270DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
271 NULL, "%llu\n");
272
273static int __init clock_debug_init(void)
274{
275 struct dentry *dent_rate, *dent_enable, *dent_local;
276 struct clk *clock;
277 unsigned n = 0;
278 char temp[50], *ptr;
279
280 dent_rate = debugfs_create_dir("clk_rate", 0);
281 if (IS_ERR(dent_rate))
282 return PTR_ERR(dent_rate);
283
284 dent_enable = debugfs_create_dir("clk_enable", 0);
285 if (IS_ERR(dent_enable))
286 return PTR_ERR(dent_enable);
287
288 dent_local = debugfs_create_dir("clk_local", NULL);
289 if (IS_ERR(dent_local))
290 return PTR_ERR(dent_local);
291
292 while ((clock = msm_clock_get_nth(n++)) != 0) {
293 strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
294 for (ptr = temp; *ptr; ptr++)
295 *ptr = tolower(*ptr);
296 debugfs_create_file(temp, 0644, dent_rate,
297 clock, &clock_rate_fops);
298 debugfs_create_file(temp, 0644, dent_enable,
299 clock, &clock_enable_fops);
300 debugfs_create_file(temp, S_IRUGO, dent_local,
301 clock, &clock_local_fops);
302 }
303 return 0;
304}
305
306device_initcall(clock_debug_init);
307#endif
308
192/* The bootloader and/or AMSS may have left various clocks enabled. 309/* The bootloader and/or AMSS may have left various clocks enabled.
193 * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have 310 * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
194 * not been explicitly enabled by a clk_enable() call. 311 * not been explicitly enabled by a clk_enable() call.
@@ -205,7 +322,7 @@ static int __init clock_late_init(void)
205 spin_lock_irqsave(&clocks_lock, flags); 322 spin_lock_irqsave(&clocks_lock, flags);
206 if (!clk->count) { 323 if (!clk->count) {
207 count++; 324 count++;
208 pc_clk_disable(clk->id); 325 clk->ops->auto_off(clk->id);
209 } 326 }
210 spin_unlock_irqrestore(&clocks_lock, flags); 327 spin_unlock_irqrestore(&clocks_lock, flags);
211 } 328 }
@@ -216,3 +333,4 @@ static int __init clock_late_init(void)
216} 333}
217 334
218late_initcall(clock_late_init); 335late_initcall(clock_late_init);
336
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index f875e1544e5f..c270b552ed13 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -1,7 +1,7 @@
1/* arch/arm/mach-msm/clock.h 1/* arch/arm/mach-msm/clock.h
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007 QUALCOMM Incorporated 4 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -18,6 +18,10 @@
18#define __ARCH_ARM_MACH_MSM_CLOCK_H 18#define __ARCH_ARM_MACH_MSM_CLOCK_H
19 19
20#include <linux/list.h> 20#include <linux/list.h>
21#include <mach/clk.h>
22
23#include "clock-pcom.h"
24#include "clock-7x30.h"
21 25
22#define CLKFLAG_INVERT 0x00000001 26#define CLKFLAG_INVERT 0x00000001
23#define CLKFLAG_NOINVERT 0x00000002 27#define CLKFLAG_NOINVERT 0x00000002
@@ -25,14 +29,32 @@
25#define CLKFLAG_NORESET 0x00000008 29#define CLKFLAG_NORESET 0x00000008
26 30
27#define CLK_FIRST_AVAILABLE_FLAG 0x00000100 31#define CLK_FIRST_AVAILABLE_FLAG 0x00000100
28#define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200 32#define CLKFLAG_AUTO_OFF 0x00000200
29#define CLKFLAG_AUTO_OFF 0x00000400 33#define CLKFLAG_MIN 0x00000400
34#define CLKFLAG_MAX 0x00000800
35
36struct clk_ops {
37 int (*enable)(unsigned id);
38 void (*disable)(unsigned id);
39 void (*auto_off)(unsigned id);
40 int (*reset)(unsigned id, enum clk_reset_action action);
41 int (*set_rate)(unsigned id, unsigned rate);
42 int (*set_min_rate)(unsigned id, unsigned rate);
43 int (*set_max_rate)(unsigned id, unsigned rate);
44 int (*set_flags)(unsigned id, unsigned flags);
45 unsigned (*get_rate)(unsigned id);
46 unsigned (*is_enabled)(unsigned id);
47 long (*round_rate)(unsigned id, unsigned rate);
48};
30 49
31struct clk { 50struct clk {
32 uint32_t id; 51 uint32_t id;
52 uint32_t remote_id;
33 uint32_t count; 53 uint32_t count;
34 uint32_t flags; 54 uint32_t flags;
35 const char *name; 55 const char *name;
56 struct clk_ops *ops;
57 const char *dbg_name;
36 struct list_head list; 58 struct list_head list;
37 struct device *dev; 59 struct device *dev;
38}; 60};
@@ -41,8 +63,47 @@ struct clk {
41#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) 63#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
42#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) 64#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
43 65
44extern struct clk msm_clocks[]; 66#ifdef CONFIG_DEBUG_FS
45extern unsigned msm_num_clocks; 67#define CLOCK_DBG_NAME(x) .dbg_name = x,
68#else
69#define CLOCK_DBG_NAME(x)
70#endif
71
72#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \
73 .name = clk_name, \
74 .id = clk_id, \
75 .flags = clk_flags, \
76 .dev = clk_dev, \
77 CLOCK_DBG_NAME(#clk_id) \
78 }
79
80#define OFF CLKFLAG_AUTO_OFF
81#define CLK_MIN CLKFLAG_MIN
82#define CLK_MAX CLKFLAG_MAX
83#define CLK_MINMAX (CLK_MIN | CLK_MAX)
84#define NR_CLKS P_NR_CLKS
85
86enum {
87 PLL_0 = 0,
88 PLL_1,
89 PLL_2,
90 PLL_3,
91 PLL_4,
92 PLL_5,
93 PLL_6,
94 NUM_PLL
95};
96
97enum clkvote_client {
98 CLKVOTE_ACPUCLK = 0,
99 CLKVOTE_PMQOS,
100 CLKVOTE_MAX,
101};
102
103int msm_clock_require_tcxo(unsigned long *reason, int nbits);
104int msm_clock_get_name(uint32_t id, char *name, uint32_t size);
105int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate);
106unsigned long clk_get_max_axi_khz(void);
46 107
47#endif 108#endif
48 109
diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices-msm7x00.c
index 31b6b30e98bf..fde9d8f69f10 100644
--- a/arch/arm/mach-msm/devices.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -24,6 +24,10 @@
24#include <linux/mtd/nand.h> 24#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26 26
27
28#include "clock.h"
29#include <mach/mmc.h>
30
27static struct resource resources_uart1[] = { 31static struct resource resources_uart1[] = {
28 { 32 {
29 .start = INT_UART1, 33 .start = INT_UART1,
@@ -163,8 +167,19 @@ static struct resource resources_sdc1[] = {
163 }, 167 },
164 { 168 {
165 .start = INT_SDC1_0, 169 .start = INT_SDC1_0,
170 .end = INT_SDC1_0,
171 .flags = IORESOURCE_IRQ,
172 .name = "cmd_irq",
173 },
174 {
175 .start = INT_SDC1_1,
166 .end = INT_SDC1_1, 176 .end = INT_SDC1_1,
167 .flags = IORESOURCE_IRQ, 177 .flags = IORESOURCE_IRQ,
178 .name = "pio_irq",
179 },
180 {
181 .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
182 .name = "status_irq"
168 }, 183 },
169 { 184 {
170 .start = 8, 185 .start = 8,
@@ -181,8 +196,19 @@ static struct resource resources_sdc2[] = {
181 }, 196 },
182 { 197 {
183 .start = INT_SDC2_0, 198 .start = INT_SDC2_0,
199 .end = INT_SDC2_0,
200 .flags = IORESOURCE_IRQ,
201 .name = "cmd_irq",
202 },
203 {
204 .start = INT_SDC2_1,
184 .end = INT_SDC2_1, 205 .end = INT_SDC2_1,
185 .flags = IORESOURCE_IRQ, 206 .flags = IORESOURCE_IRQ,
207 .name = "pio_irq",
208 },
209 {
210 .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
211 .name = "status_irq"
186 }, 212 },
187 { 213 {
188 .start = 8, 214 .start = 8,
@@ -199,8 +225,19 @@ static struct resource resources_sdc3[] = {
199 }, 225 },
200 { 226 {
201 .start = INT_SDC3_0, 227 .start = INT_SDC3_0,
228 .end = INT_SDC3_0,
229 .flags = IORESOURCE_IRQ,
230 .name = "cmd_irq",
231 },
232 {
233 .start = INT_SDC3_1,
202 .end = INT_SDC3_1, 234 .end = INT_SDC3_1,
203 .flags = IORESOURCE_IRQ, 235 .flags = IORESOURCE_IRQ,
236 .name = "pio_irq",
237 },
238 {
239 .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
240 .name = "status_irq"
204 }, 241 },
205 { 242 {
206 .start = 8, 243 .start = 8,
@@ -217,8 +254,19 @@ static struct resource resources_sdc4[] = {
217 }, 254 },
218 { 255 {
219 .start = INT_SDC4_0, 256 .start = INT_SDC4_0,
257 .end = INT_SDC4_0,
258 .flags = IORESOURCE_IRQ,
259 .name = "cmd_irq",
260 },
261 {
262 .start = INT_SDC4_1,
220 .end = INT_SDC4_1, 263 .end = INT_SDC4_1,
221 .flags = IORESOURCE_IRQ, 264 .flags = IORESOURCE_IRQ,
265 .name = "pio_irq",
266 },
267 {
268 .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
269 .name = "status_irq"
222 }, 270 },
223 { 271 {
224 .start = 8, 272 .start = 8,
@@ -266,3 +314,80 @@ struct platform_device msm_device_sdc4 = {
266 .coherent_dma_mask = 0xffffffff, 314 .coherent_dma_mask = 0xffffffff,
267 }, 315 },
268}; 316};
317
318static struct platform_device *msm_sdcc_devices[] __initdata = {
319 &msm_device_sdc1,
320 &msm_device_sdc2,
321 &msm_device_sdc3,
322 &msm_device_sdc4,
323};
324
325int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat,
326 unsigned int stat_irq, unsigned long stat_irq_flags)
327{
328 struct platform_device *pdev;
329 struct resource *res;
330
331 if (controller < 1 || controller > 4)
332 return -EINVAL;
333
334 pdev = msm_sdcc_devices[controller-1];
335 pdev->dev.platform_data = plat;
336
337 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
338 if (!res)
339 return -EINVAL;
340 else if (stat_irq) {
341 res->start = res->end = stat_irq;
342 res->flags &= ~IORESOURCE_DISABLED;
343 res->flags |= stat_irq_flags;
344 }
345
346 return platform_device_register(pdev);
347}
348
349struct clk msm_clocks_7x01a[] = {
350 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
351 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
352 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0),
353 CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
354 CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
355 CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF),
356 CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
357 CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF),
358 CLK_PCOM("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0),
359 CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
360 CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
361 CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
362 CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
363 CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
364 CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0),
365 CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
366 CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ),
367 CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
368 CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
369 CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF),
370 CLK_PCOM("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF),
371 CLK_PCOM("sdc_pclk", SDC2_P_CLK, &msm_device_sdc2.dev, OFF),
372 CLK_PCOM("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF),
373 CLK_PCOM("sdc_pclk", SDC3_P_CLK, &msm_device_sdc3.dev, OFF),
374 CLK_PCOM("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF),
375 CLK_PCOM("sdc_pclk", SDC4_P_CLK, &msm_device_sdc4.dev, OFF),
376 CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
377 CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
378 CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
379 CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
380 CLK_PCOM("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF),
381 CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
382 CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
383 CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF),
384 CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0),
385 CLK_PCOM("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF),
386 CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, &msm_device_hsusb.dev, OFF),
387 CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
388 CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ),
389 CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
390 CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
391};
392
393unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
new file mode 100644
index 000000000000..b449e8ad2904
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -0,0 +1,128 @@
1/*
2 * Copyright (C) 2008 Google, Inc.
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
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
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <linux/dma-mapping.h>
20#include <mach/irqs.h>
21#include <mach/msm_iomap.h>
22#include <mach/dma.h>
23#include <mach/board.h>
24
25#include "devices.h"
26#include "smd_private.h"
27
28#include <asm/mach/flash.h>
29
30#include "clock-pcom.h"
31
32#include <mach/mmc.h>
33
34static struct resource resources_uart2[] = {
35 {
36 .start = INT_UART2,
37 .end = INT_UART2,
38 .flags = IORESOURCE_IRQ,
39 },
40 {
41 .start = MSM_UART2_PHYS,
42 .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
43 .flags = IORESOURCE_MEM,
44 },
45};
46
47struct platform_device msm_device_uart2 = {
48 .name = "msm_serial",
49 .id = 1,
50 .num_resources = ARRAY_SIZE(resources_uart2),
51 .resource = resources_uart2,
52};
53
54struct clk msm_clocks_7x30[] = {
55 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
56 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
57 CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0),
58 CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF),
59 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
60 CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
61 CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX),
62 CLK_PCOM("emdh_pclk", EMDH_P_CLK, NULL, OFF),
63 CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
64 CLK_PCOM("grp_2d_clk", GRP_2D_CLK, NULL, 0),
65 CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK, NULL, 0),
66 CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0),
67 CLK_PCOM("grp_pclk", GRP_3D_P_CLK, NULL, 0),
68 CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK, NULL, 0),
69 CLK_PCOM("hdmi_clk", HDMI_CLK, NULL, 0),
70 CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
71 CLK_PCOM("jpeg_clk", JPEG_CLK, NULL, OFF),
72 CLK_PCOM("jpeg_pclk", JPEG_P_CLK, NULL, OFF),
73 CLK_PCOM("lpa_codec_clk", LPA_CODEC_CLK, NULL, 0),
74 CLK_PCOM("lpa_core_clk", LPA_CORE_CLK, NULL, 0),
75 CLK_PCOM("lpa_pclk", LPA_P_CLK, NULL, 0),
76 CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
77 CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
78 CLK_PCOM("mddi_pclk", PMDH_P_CLK, NULL, 0),
79 CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
80 CLK_PCOM("mdp_pclk", MDP_P_CLK, NULL, 0),
81 CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
82 CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
83 CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0),
84 CLK_PCOM("mfc_clk", MFC_CLK, NULL, 0),
85 CLK_PCOM("mfc_div2_clk", MFC_DIV2_CLK, NULL, 0),
86 CLK_PCOM("mfc_pclk", MFC_P_CLK, NULL, 0),
87 CLK_PCOM("mi2s_m_clk", MI2S_M_CLK, NULL, 0),
88 CLK_PCOM("mi2s_s_clk", MI2S_S_CLK, NULL, 0),
89 CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK, NULL, 0),
90 CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK, NULL, 0),
91 CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK, NULL, 0),
92 CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK, NULL, 0),
93 CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN),
94 CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
95 CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK, NULL, 0),
96 CLK_PCOM("rotator_imem_clk", ROTATOR_IMEM_CLK, NULL, OFF),
97 CLK_PCOM("rotator_pclk", ROTATOR_P_CLK, NULL, OFF),
98 CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
99 CLK_PCOM("spi_clk", SPI_CLK, NULL, 0),
100 CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0),
101 CLK_7X30S("tv_src_clk", TV_CLK, TV_ENC_CLK, NULL, 0),
102 CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
103 CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
104 CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
105 CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
106 CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
107 CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, OFF),
108 CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF),
109 CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF),
110 CLK_PCOM("usb_hs2_core_clk", USB_HS2_CORE_CLK, NULL, OFF),
111 CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF),
112 CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF),
113 CLK_PCOM("usb_hs3_core_clk", USB_HS3_CORE_CLK, NULL, OFF),
114 CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN),
115 CLK_PCOM("vfe_camif_clk", VFE_CAMIF_CLK, NULL, 0),
116 CLK_PCOM("vfe_clk", VFE_CLK, NULL, 0),
117 CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, 0),
118 CLK_PCOM("vfe_pclk", VFE_P_CLK, NULL, OFF),
119 CLK_PCOM("vpe_clk", VPE_CLK, NULL, 0),
120
121 /* 7x30 v2 hardware only. */
122 CLK_PCOM("csi_clk", CSI0_CLK, NULL, 0),
123 CLK_PCOM("csi_pclk", CSI0_P_CLK, NULL, 0),
124 CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK, NULL, 0),
125};
126
127unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30);
128
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
new file mode 100644
index 000000000000..4d4a50785e34
--- /dev/null
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -0,0 +1,92 @@
1/*
2 * Copyright (C) 2008 Google, Inc.
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
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
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <linux/dma-mapping.h>
20#include <mach/irqs.h>
21#include <mach/msm_iomap.h>
22#include <mach/dma.h>
23#include <mach/board.h>
24
25#include "devices.h"
26
27#include <asm/mach/flash.h>
28
29#include <mach/mmc.h>
30
31static struct resource resources_uart3[] = {
32 {
33 .start = INT_UART3,
34 .end = INT_UART3,
35 .flags = IORESOURCE_IRQ,
36 },
37 {
38 .start = MSM_UART3_PHYS,
39 .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
40 .flags = IORESOURCE_MEM,
41 },
42};
43
44struct platform_device msm_device_uart3 = {
45 .name = "msm_serial",
46 .id = 2,
47 .num_resources = ARRAY_SIZE(resources_uart3),
48 .resource = resources_uart3,
49};
50
51struct clk msm_clocks_8x50[] = {
52 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
53 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
54 CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
55 CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
56 CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX),
57 CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
58 CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0),
59 CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
60 CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
61 CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
62 CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
63 CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
64 CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
65 CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
66 CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
67 CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0),
68 CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN),
69 CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
70 CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
71 CLK_PCOM("spi_clk", SPI_CLK, NULL, 0),
72 CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
73 CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
74 CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
75 CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
76 CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
77 CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
78 CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
79 CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
80 CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN),
81 CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
82 CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
83 CLK_PCOM("vfe_axi_clk", VFE_AXI_CLK, NULL, OFF),
84 CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF),
85 CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF),
86 CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF),
87 CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF),
88 CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0),
89};
90
91unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50);
92
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 0744c4a27d6a..568443e76423 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -16,6 +16,8 @@
16#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H 16#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
17#define __ARCH_ARM_MACH_MSM_DEVICES_H 17#define __ARCH_ARM_MACH_MSM_DEVICES_H
18 18
19#include "clock.h"
20
19extern struct platform_device msm_device_uart1; 21extern struct platform_device msm_device_uart1;
20extern struct platform_device msm_device_uart2; 22extern struct platform_device msm_device_uart2;
21extern struct platform_device msm_device_uart3; 23extern struct platform_device msm_device_uart3;
@@ -33,4 +35,13 @@ extern struct platform_device msm_device_smd;
33 35
34extern struct platform_device msm_device_nand; 36extern struct platform_device msm_device_nand;
35 37
38extern struct clk msm_clocks_7x01a[];
39extern unsigned msm_num_clocks_7x01a;
40
41extern struct clk msm_clocks_7x30[];
42extern unsigned msm_num_clocks_7x30;
43
44extern struct clk msm_clocks_8x50[];
45extern unsigned msm_num_clocks_8x50;
46
36#endif 47#endif
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index f5420f9585c5..3d725ae518e4 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -13,6 +13,8 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/clk.h>
17#include <linux/err.h>
16#include <linux/io.h> 18#include <linux/io.h>
17#include <linux/interrupt.h> 19#include <linux/interrupt.h>
18#include <mach/dma.h> 20#include <mach/dma.h>
@@ -26,6 +28,7 @@ enum {
26}; 28};
27 29
28static DEFINE_SPINLOCK(msm_dmov_lock); 30static DEFINE_SPINLOCK(msm_dmov_lock);
31static struct clk *msm_dmov_clk;
29static unsigned int channel_active; 32static unsigned int channel_active;
30static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; 33static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
31static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; 34static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
@@ -54,6 +57,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
54 unsigned int status; 57 unsigned int status;
55 58
56 spin_lock_irqsave(&msm_dmov_lock, irq_flags); 59 spin_lock_irqsave(&msm_dmov_lock, irq_flags);
60 if (!channel_active)
61 clk_enable(msm_dmov_clk);
62 dsb();
57 status = readl(DMOV_STATUS(id)); 63 status = readl(DMOV_STATUS(id));
58 if (list_empty(&ready_commands[id]) && 64 if (list_empty(&ready_commands[id]) &&
59 (status & DMOV_STATUS_CMD_PTR_RDY)) { 65 (status & DMOV_STATUS_CMD_PTR_RDY)) {
@@ -70,6 +76,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
70 channel_active |= 1U << id; 76 channel_active |= 1U << id;
71 writel(cmd->cmdptr, DMOV_CMD_PTR(id)); 77 writel(cmd->cmdptr, DMOV_CMD_PTR(id));
72 } else { 78 } else {
79 if (!channel_active)
80 clk_disable(msm_dmov_clk);
73 if (list_empty(&active_commands[id])) 81 if (list_empty(&active_commands[id]))
74 PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); 82 PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
75 83
@@ -165,6 +173,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
165 "for %p, result %x\n", id, cmd, ch_result); 173 "for %p, result %x\n", id, cmd, ch_result);
166 if (cmd) { 174 if (cmd) {
167 list_del(&cmd->list); 175 list_del(&cmd->list);
176 dsb();
168 cmd->complete_func(cmd, ch_result, NULL); 177 cmd->complete_func(cmd, ch_result, NULL);
169 } 178 }
170 } 179 }
@@ -181,6 +190,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
181 PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); 190 PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
182 if (cmd) { 191 if (cmd) {
183 list_del(&cmd->list); 192 list_del(&cmd->list);
193 dsb();
184 cmd->complete_func(cmd, ch_result, &errdata); 194 cmd->complete_func(cmd, ch_result, &errdata);
185 } 195 }
186 } 196 }
@@ -198,6 +208,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
198 PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); 208 PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
199 if (cmd) { 209 if (cmd) {
200 list_del(&cmd->list); 210 list_del(&cmd->list);
211 dsb();
201 cmd->complete_func(cmd, ch_result, &errdata); 212 cmd->complete_func(cmd, ch_result, &errdata);
202 } 213 }
203 /* this does not seem to work, once we get an error */ 214 /* this does not seem to work, once we get an error */
@@ -219,8 +230,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
219 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); 230 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
220 } 231 }
221 232
222 if (!channel_active) 233 if (!channel_active) {
223 disable_irq(INT_ADM_AARM); 234 disable_irq_nosync(INT_ADM_AARM);
235 clk_disable(msm_dmov_clk);
236 }
224 237
225 spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); 238 spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
226 return IRQ_HANDLED; 239 return IRQ_HANDLED;
@@ -230,11 +243,17 @@ static int __init msm_init_datamover(void)
230{ 243{
231 int i; 244 int i;
232 int ret; 245 int ret;
246 struct clk *clk;
247
233 for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { 248 for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
234 INIT_LIST_HEAD(&ready_commands[i]); 249 INIT_LIST_HEAD(&ready_commands[i]);
235 INIT_LIST_HEAD(&active_commands[i]); 250 INIT_LIST_HEAD(&active_commands[i]);
236 writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); 251 writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
237 } 252 }
253 clk = clk_get(NULL, "adm_clk");
254 if (IS_ERR(clk))
255 return PTR_ERR(clk);
256 msm_dmov_clk = clk;
238 ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); 257 ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
239 if (ret) 258 if (ret)
240 return ret; 259 return ret;
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
new file mode 100644
index 000000000000..bc32c845c7b0
--- /dev/null
+++ b/arch/arm/mach-msm/gpio.c
@@ -0,0 +1,85 @@
1/* linux/arch/arm/mach-msm/gpio.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2009, Code Aurora Forum. 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
17#include <linux/module.h>
18#include <mach/gpio.h>
19#include "proc_comm.h"
20
21int gpio_tlmm_config(unsigned config, unsigned disable)
22{
23 return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
24}
25EXPORT_SYMBOL(gpio_tlmm_config);
26
27int msm_gpios_enable(const struct msm_gpio *table, int size)
28{
29 int rc;
30 int i;
31 const struct msm_gpio *g;
32 for (i = 0; i < size; i++) {
33 g = table + i;
34 rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
35 if (rc) {
36 pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)"
37 " <%s> failed: %d\n",
38 g->gpio_cfg, g->label ?: "?", rc);
39 pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
40 GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
41 GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
42 GPIO_DRVSTR(g->gpio_cfg));
43 goto err;
44 }
45 }
46 return 0;
47err:
48 msm_gpios_disable(table, i);
49 return rc;
50}
51EXPORT_SYMBOL(msm_gpios_enable);
52
53void msm_gpios_disable(const struct msm_gpio *table, int size)
54{
55 int rc;
56 int i;
57 const struct msm_gpio *g;
58 for (i = size-1; i >= 0; i--) {
59 g = table + i;
60 rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE);
61 if (rc) {
62 pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)"
63 " <%s> failed: %d\n",
64 g->gpio_cfg, g->label ?: "?", rc);
65 pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
66 GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
67 GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
68 GPIO_DRVSTR(g->gpio_cfg));
69 }
70 }
71}
72EXPORT_SYMBOL(msm_gpios_disable);
73
74int msm_gpios_request_enable(const struct msm_gpio *table, int size)
75{
76 int rc = msm_gpios_enable(table, size);
77 return rc;
78}
79EXPORT_SYMBOL(msm_gpios_request_enable);
80
81void msm_gpios_disable_free(const struct msm_gpio *table, int size)
82{
83 msm_gpios_disable(table, size);
84}
85EXPORT_SYMBOL(msm_gpios_disable_free);
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 264d62e519f3..e302fbdc439b 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -21,18 +21,24 @@
21 21
22/* platform device data structures */ 22/* platform device data structures */
23 23
24struct msm_mddi_platform_data 24struct msm_acpu_clock_platform_data
25{ 25{
26 void (*panel_power)(int on); 26 uint32_t acpu_switch_time_us;
27 unsigned has_vsync_irq:1; 27 uint32_t max_speed_delta_khz;
28 uint32_t vdd_switch_time_us;
29 unsigned long power_collapse_khz;
30 unsigned long wait_for_irq_khz;
28}; 31};
29 32
33struct clk;
34
30/* common init routines for use by arch/arm/mach-msm/board-*.c */ 35/* common init routines for use by arch/arm/mach-msm/board-*.c */
31 36
32void __init msm_add_devices(void); 37void __init msm_add_devices(void);
33void __init msm_map_common_io(void); 38void __init msm_map_common_io(void);
34void __init msm_init_irq(void); 39void __init msm_init_irq(void);
35void __init msm_init_gpio(void); 40void __init msm_init_gpio(void);
36void __init msm_clock_init(void); 41void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks);
42void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *);
37 43
38#endif 44#endif
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
new file mode 100644
index 000000000000..c05ca40478c7
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -0,0 +1,57 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#ifndef __MACH_CLK_H
30#define __MACH_CLK_H
31
32/* Magic rate value for use with PM QOS to request the board's maximum
33 * supported AXI rate. PM QOS will only pass positive s32 rate values
34 * through to the clock driver, so INT_MAX is used.
35 */
36#define MSM_AXI_MAX_FREQ LONG_MAX
37
38enum clk_reset_action {
39 CLK_RESET_DEASSERT = 0,
40 CLK_RESET_ASSERT = 1
41};
42
43struct clk;
44
45/* Rate is minimum clock rate in Hz */
46int clk_set_min_rate(struct clk *clk, unsigned long rate);
47
48/* Rate is maximum clock rate in Hz */
49int clk_set_max_rate(struct clk *clk, unsigned long rate);
50
51/* Assert/Deassert reset to a hardware block associated with a clock */
52int clk_reset(struct clk *clk, enum clk_reset_action action);
53
54/* Set clock-specific configuration parameters */
55int clk_set_flags(struct clk *clk, unsigned long flags);
56
57#endif
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 5ab5bdffab07..04c51cc04f31 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -41,40 +41,42 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
41#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) 41#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
42#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) 42#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
43 43
44/* only security domain 3 is available to the ARM11 44#if defined(CONFIG_ARCH_MSM7X30)
45 * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM 45#define DMOV_SD_AARM DMOV_SD2
46 */ 46#else
47#define DMOV_SD_AARM DMOV_SD3
48#endif
47 49
48#define DMOV_CMD_PTR(ch) DMOV_SD3(0x000, ch) 50#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch)
49#define DMOV_CMD_LIST (0 << 29) /* does not work */ 51#define DMOV_CMD_LIST (0 << 29) /* does not work */
50#define DMOV_CMD_PTR_LIST (1 << 29) /* works */ 52#define DMOV_CMD_PTR_LIST (1 << 29) /* works */
51#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ 53#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */
52#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ 54#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */
53#define DMOV_CMD_ADDR(addr) ((addr) >> 3) 55#define DMOV_CMD_ADDR(addr) ((addr) >> 3)
54 56
55#define DMOV_RSLT(ch) DMOV_SD3(0x040, ch) 57#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch)
56#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ 58#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */
57#define DMOV_RSLT_ERROR (1 << 3) 59#define DMOV_RSLT_ERROR (1 << 3)
58#define DMOV_RSLT_FLUSH (1 << 2) 60#define DMOV_RSLT_FLUSH (1 << 2)
59#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ 61#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */
60#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ 62#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */
61 63
62#define DMOV_FLUSH0(ch) DMOV_SD3(0x080, ch) 64#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch)
63#define DMOV_FLUSH1(ch) DMOV_SD3(0x0C0, ch) 65#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch)
64#define DMOV_FLUSH2(ch) DMOV_SD3(0x100, ch) 66#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch)
65#define DMOV_FLUSH3(ch) DMOV_SD3(0x140, ch) 67#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch)
66#define DMOV_FLUSH4(ch) DMOV_SD3(0x180, ch) 68#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch)
67#define DMOV_FLUSH5(ch) DMOV_SD3(0x1C0, ch) 69#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch)
68 70
69#define DMOV_STATUS(ch) DMOV_SD3(0x200, ch) 71#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch)
70#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) 72#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29))
71#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) 73#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3)
72#define DMOV_STATUS_RSLT_VALID (1 << 1) 74#define DMOV_STATUS_RSLT_VALID (1 << 1)
73#define DMOV_STATUS_CMD_PTR_RDY (1 << 0) 75#define DMOV_STATUS_CMD_PTR_RDY (1 << 0)
74 76
75#define DMOV_ISR DMOV_SD3(0x380, 0) 77#define DMOV_ISR DMOV_SD_AARM(0x380, 0)
76 78
77#define DMOV_CONFIG(ch) DMOV_SD3(0x300, ch) 79#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch)
78#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) 80#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
79#define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1) 81#define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1)
80#define DMOV_CONFIG_IRQ_EN (1 << 0) 82#define DMOV_CONFIG_IRQ_EN (1 << 0)
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
new file mode 100644
index 000000000000..262b441b4374
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -0,0 +1,142 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
4 * Author: Mike Lockwood <lockwood@android.com>
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 __ASM_ARCH_MSM_GPIO_H
17#define __ASM_ARCH_MSM_GPIO_H
18
19/**
20 * struct msm_gpio - GPIO pin description
21 * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
22 * @label - textual label
23 *
24 * Usually, GPIO's are operated by sets.
25 * This struct accumulate all GPIO information in single source
26 * and facilitete group operations provided by msm_gpios_xxx()
27 */
28struct msm_gpio {
29 u32 gpio_cfg;
30 const char *label;
31};
32
33/**
34 * msm_gpios_request_enable() - request and enable set of GPIOs
35 *
36 * Request and configure set of GPIO's
37 * In case of error, all operations rolled back.
38 * Return error code.
39 *
40 * @table: GPIO table
41 * @size: number of entries in @table
42 */
43int msm_gpios_request_enable(const struct msm_gpio *table, int size);
44
45/**
46 * msm_gpios_disable_free() - disable and free set of GPIOs
47 *
48 * @table: GPIO table
49 * @size: number of entries in @table
50 */
51void msm_gpios_disable_free(const struct msm_gpio *table, int size);
52
53/**
54 * msm_gpios_request() - request set of GPIOs
55 * In case of error, all operations rolled back.
56 * Return error code.
57 *
58 * @table: GPIO table
59 * @size: number of entries in @table
60 */
61int msm_gpios_request(const struct msm_gpio *table, int size);
62
63/**
64 * msm_gpios_free() - free set of GPIOs
65 *
66 * @table: GPIO table
67 * @size: number of entries in @table
68 */
69void msm_gpios_free(const struct msm_gpio *table, int size);
70
71/**
72 * msm_gpios_enable() - enable set of GPIOs
73 * In case of error, all operations rolled back.
74 * Return error code.
75 *
76 * @table: GPIO table
77 * @size: number of entries in @table
78 */
79int msm_gpios_enable(const struct msm_gpio *table, int size);
80
81/**
82 * msm_gpios_disable() - disable set of GPIOs
83 *
84 * @table: GPIO table
85 * @size: number of entries in @table
86 */
87void msm_gpios_disable(const struct msm_gpio *table, int size);
88
89/* GPIO TLMM (Top Level Multiplexing) Definitions */
90
91/* GPIO TLMM: Function -- GPIO specific */
92
93/* GPIO TLMM: Direction */
94enum {
95 GPIO_INPUT,
96 GPIO_OUTPUT,
97};
98
99/* GPIO TLMM: Pullup/Pulldown */
100enum {
101 GPIO_NO_PULL,
102 GPIO_PULL_DOWN,
103 GPIO_KEEPER,
104 GPIO_PULL_UP,
105};
106
107/* GPIO TLMM: Drive Strength */
108enum {
109 GPIO_2MA,
110 GPIO_4MA,
111 GPIO_6MA,
112 GPIO_8MA,
113 GPIO_10MA,
114 GPIO_12MA,
115 GPIO_14MA,
116 GPIO_16MA,
117};
118
119enum {
120 GPIO_ENABLE,
121 GPIO_DISABLE,
122};
123
124#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
125 ((((gpio) & 0x3FF) << 4) | \
126 ((func) & 0xf) | \
127 (((dir) & 0x1) << 14) | \
128 (((pull) & 0x3) << 15) | \
129 (((drvstr) & 0xF) << 17))
130
131/**
132 * extract GPIO pin from bit-field used for gpio_tlmm_config
133 */
134#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff)
135#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf)
136#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1)
137#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3)
138#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
139
140int gpio_tlmm_config(unsigned config, unsigned disable);
141
142#endif /* __ASM_ARCH_MSM_GPIO_H */
diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h
index aab964591db4..c35b29f9ac0f 100644
--- a/arch/arm/mach-msm/include/mach/io.h
+++ b/arch/arm/mach-msm/include/mach/io.h
@@ -26,4 +26,9 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m
26#define __io(a) __typesafe_io(a) 26#define __io(a) __typesafe_io(a)
27#define __mem_pci(a) (a) 27#define __mem_pci(a) (a)
28 28
29void msm_map_qsd8x50_io(void);
30void msm_map_msm7x30_io(void);
31
32extern unsigned int msm_shared_ram_phys;
33
29#endif 34#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h
new file mode 100644
index 000000000000..f1fe70612fe9
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com>
5 */
6
7#ifndef __ASM_ARCH_MSM_IRQS_7X00_H
8#define __ASM_ARCH_MSM_IRQS_7X00_H
9
10/* MSM ARM11 Interrupt Numbers */
11/* See 80-VE113-1 A, pp219-221 */
12
13#define INT_A9_M2A_0 0
14#define INT_A9_M2A_1 1
15#define INT_A9_M2A_2 2
16#define INT_A9_M2A_3 3
17#define INT_A9_M2A_4 4
18#define INT_A9_M2A_5 5
19#define INT_A9_M2A_6 6
20#define INT_GP_TIMER_EXP 7
21#define INT_DEBUG_TIMER_EXP 8
22#define INT_UART1 9
23#define INT_UART2 10
24#define INT_UART3 11
25#define INT_UART1_RX 12
26#define INT_UART2_RX 13
27#define INT_UART3_RX 14
28#define INT_USB_OTG 15
29#define INT_MDDI_PRI 16
30#define INT_MDDI_EXT 17
31#define INT_MDDI_CLIENT 18
32#define INT_MDP 19
33#define INT_GRAPHICS 20
34#define INT_ADM_AARM 21
35#define INT_ADSP_A11 22
36#define INT_ADSP_A9_A11 23
37#define INT_SDC1_0 24
38#define INT_SDC1_1 25
39#define INT_SDC2_0 26
40#define INT_SDC2_1 27
41#define INT_KEYSENSE 28
42#define INT_TCHSCRN_SSBI 29
43#define INT_TCHSCRN1 30
44#define INT_TCHSCRN2 31
45
46#define INT_GPIO_GROUP1 (32 + 0)
47#define INT_GPIO_GROUP2 (32 + 1)
48#define INT_PWB_I2C (32 + 2)
49#define INT_SOFTRESET (32 + 3)
50#define INT_NAND_WR_ER_DONE (32 + 4)
51#define INT_NAND_OP_DONE (32 + 5)
52#define INT_PBUS_ARM11 (32 + 6)
53#define INT_AXI_MPU_SMI (32 + 7)
54#define INT_AXI_MPU_EBI1 (32 + 8)
55#define INT_AD_HSSD (32 + 9)
56#define INT_ARM11_PMU (32 + 10)
57#define INT_ARM11_DMA (32 + 11)
58#define INT_TSIF_IRQ (32 + 12)
59#define INT_UART1DM_IRQ (32 + 13)
60#define INT_UART1DM_RX (32 + 14)
61#define INT_USB_HS (32 + 15)
62#define INT_SDC3_0 (32 + 16)
63#define INT_SDC3_1 (32 + 17)
64#define INT_SDC4_0 (32 + 18)
65#define INT_SDC4_1 (32 + 19)
66#define INT_UART2DM_RX (32 + 20)
67#define INT_UART2DM_IRQ (32 + 21)
68
69/* 22-31 are reserved */
70
71#define NR_MSM_IRQS 64
72#define NR_GPIO_IRQS 122
73#define NR_BOARD_IRQS 64
74
75#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h
new file mode 100644
index 000000000000..67c5396514fe
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h
@@ -0,0 +1,170 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef __ASM_ARCH_MSM_IRQS_7X30_H
31#define __ASM_ARCH_MSM_IRQS_7X30_H
32
33/* MSM ACPU Interrupt Numbers */
34
35#define INT_DEBUG_TIMER_EXP 0
36#define INT_GPT0_TIMER_EXP 1
37#define INT_GPT1_TIMER_EXP 2
38#define INT_WDT0_ACCSCSSBARK 3
39#define INT_WDT1_ACCSCSSBARK 4
40#define INT_AVS_SVIC 5
41#define INT_AVS_SVIC_SW_DONE 6
42#define INT_SC_DBG_RX_FULL 7
43#define INT_SC_DBG_TX_EMPTY 8
44#define INT_ARM11_PM 9
45#define INT_AVS_REQ_DOWN 10
46#define INT_AVS_REQ_UP 11
47#define INT_SC_ACG 12
48/* SCSS_VICFIQSTS0[13:15] are RESERVED */
49#define INT_L2_SVICCPUIRPTREQ 16
50#define INT_L2_SVICDMANSIRPTREQ 17
51#define INT_L2_SVICDMASIRPTREQ 18
52#define INT_L2_SVICSLVIRPTREQ 19
53#define INT_AD5A_MPROC_APPS_0 20
54#define INT_AD5A_MPROC_APPS_1 21
55#define INT_A9_M2A_0 22
56#define INT_A9_M2A_1 23
57#define INT_A9_M2A_2 24
58#define INT_A9_M2A_3 25
59#define INT_A9_M2A_4 26
60#define INT_A9_M2A_5 27
61#define INT_A9_M2A_6 28
62#define INT_A9_M2A_7 29
63#define INT_A9_M2A_8 30
64#define INT_A9_M2A_9 31
65
66#define INT_AXI_EBI1_SC (32 + 0)
67#define INT_IMEM_ERR (32 + 1)
68#define INT_AXI_EBI0_SC (32 + 2)
69#define INT_PBUS_SC_IRQC (32 + 3)
70#define INT_PERPH_BUS_BPM (32 + 4)
71#define INT_CC_TEMP_SENSE (32 + 5)
72#define INT_UXMC_EBI0 (32 + 6)
73#define INT_UXMC_EBI1 (32 + 7)
74#define INT_EBI2_OP_DONE (32 + 8)
75#define INT_EBI2_WR_ER_DONE (32 + 9)
76#define INT_TCSR_SPSS_CE (32 + 10)
77#define INT_EMDH (32 + 11)
78#define INT_PMDH (32 + 12)
79#define INT_MDC (32 + 13)
80#define INT_MIDI_TO_SUPSS (32 + 14)
81#define INT_LPA_2 (32 + 15)
82#define INT_GPIO_GROUP1_SECURE (32 + 16)
83#define INT_GPIO_GROUP2_SECURE (32 + 17)
84#define INT_GPIO_GROUP1 (32 + 18)
85#define INT_GPIO_GROUP2 (32 + 19)
86#define INT_MPRPH_SOFTRESET (32 + 20)
87#define INT_PWB_I2C (32 + 21)
88#define INT_PWB_I2C_2 (32 + 22)
89#define INT_TSSC_SAMPLE (32 + 23)
90#define INT_TSSC_PENUP (32 + 24)
91#define INT_TCHSCRN_SSBI (32 + 25)
92#define INT_FM_RDS (32 + 26)
93#define INT_KEYSENSE (32 + 27)
94#define INT_USB_OTG_HS (32 + 28)
95#define INT_USB_OTG_HS2 (32 + 29)
96#define INT_USB_OTG_HS3 (32 + 30)
97#define INT_CSI (32 + 31)
98
99#define INT_SPI_OUTPUT (64 + 0)
100#define INT_SPI_INPUT (64 + 1)
101#define INT_SPI_ERROR (64 + 2)
102#define INT_UART1 (64 + 3)
103#define INT_UART1_RX (64 + 4)
104#define INT_UART2 (64 + 5)
105#define INT_UART2_RX (64 + 6)
106#define INT_UART3 (64 + 7)
107#define INT_UART3_RX (64 + 8)
108#define INT_UART1DM_IRQ (64 + 9)
109#define INT_UART1DM_RX (64 + 10)
110#define INT_UART2DM_IRQ (64 + 11)
111#define INT_UART2DM_RX (64 + 12)
112#define INT_TSIF (64 + 13)
113#define INT_ADM_SC1 (64 + 14)
114#define INT_ADM_SC2 (64 + 15)
115#define INT_MDP (64 + 16)
116#define INT_VPE (64 + 17)
117#define INT_GRP_2D (64 + 18)
118#define INT_GRP_3D (64 + 19)
119#define INT_ROTATOR (64 + 20)
120#define INT_MFC720 (64 + 21)
121#define INT_JPEG (64 + 22)
122#define INT_VFE (64 + 23)
123#define INT_TV_ENC (64 + 24)
124#define INT_PMIC_SSBI (64 + 25)
125#define INT_MPM_1 (64 + 26)
126#define INT_TCSR_SPSS_SAMPLE (64 + 27)
127#define INT_TCSR_SPSS_PENUP (64 + 28)
128#define INT_MPM_2 (64 + 29)
129#define INT_SDC1_0 (64 + 30)
130#define INT_SDC1_1 (64 + 31)
131
132#define INT_SDC3_0 (96 + 0)
133#define INT_SDC3_1 (96 + 1)
134#define INT_SDC2_0 (96 + 2)
135#define INT_SDC2_1 (96 + 3)
136#define INT_SDC4_0 (96 + 4)
137#define INT_SDC4_1 (96 + 5)
138#define INT_PWB_QUP_IN (96 + 6)
139#define INT_PWB_QUP_OUT (96 + 7)
140#define INT_PWB_QUP_ERR (96 + 8)
141#define INT_SCSS_WDT0_BITE (96 + 9)
142/* SCSS_VICFIQSTS3[10:31] are RESERVED */
143
144/* Retrofit universal macro names */
145#define INT_ADM_AARM INT_ADM_SC2
146#define INT_USB_HS INT_USB_OTG_HS
147#define INT_USB_OTG INT_USB_OTG_HS
148#define INT_TCHSCRN1 INT_TSSC_SAMPLE
149#define INT_TCHSCRN2 INT_TSSC_PENUP
150#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP
151#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0
152#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1
153#define INT_MDDI_EXT INT_EMDH
154#define INT_MDDI_PRI INT_PMDH
155#define INT_MDDI_CLIENT INT_MDC
156#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE
157#define INT_NAND_OP_DONE INT_EBI2_OP_DONE
158
159#define NR_MSM_IRQS 128
160#define NR_GPIO_IRQS 182
161#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
162#define NR_PMIC8058_GPIO_IRQS 40
163#define NR_PMIC8058_MPP_IRQS 12
164#define NR_PMIC8058_MISC_IRQS 8
165#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\
166 NR_PMIC8058_MPP_IRQS +\
167 NR_PMIC8058_MISC_IRQS)
168#define NR_BOARD_IRQS NR_PMIC8058_IRQS
169
170#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h
new file mode 100644
index 000000000000..de3d8fe24e4e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h
@@ -0,0 +1,105 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef __ASM_ARCH_MSM_IRQS_8XXX_H
31#define __ASM_ARCH_MSM_IRQS_8XXX_H
32
33/* MSM ACPU Interrupt Numbers */
34
35#define INT_A9_M2A_0 0
36#define INT_A9_M2A_1 1
37#define INT_A9_M2A_2 2
38#define INT_A9_M2A_3 3
39#define INT_A9_M2A_4 4
40#define INT_A9_M2A_5 5
41#define INT_A9_M2A_6 6
42#define INT_GP_TIMER_EXP 7
43#define INT_DEBUG_TIMER_EXP 8
44#define INT_SIRC_0 9
45#define INT_SDC3_0 10
46#define INT_SDC3_1 11
47#define INT_SDC4_0 12
48#define INT_SDC4_1 13
49#define INT_AD6_EXT_VFR 14
50#define INT_USB_OTG 15
51#define INT_MDDI_PRI 16
52#define INT_MDDI_EXT 17
53#define INT_MDDI_CLIENT 18
54#define INT_MDP 19
55#define INT_GRAPHICS 20
56#define INT_ADM_AARM 21
57#define INT_ADSP_A11 22
58#define INT_ADSP_A9_A11 23
59#define INT_SDC1_0 24
60#define INT_SDC1_1 25
61#define INT_SDC2_0 26
62#define INT_SDC2_1 27
63#define INT_KEYSENSE 28
64#define INT_TCHSCRN_SSBI 29
65#define INT_TCHSCRN1 30
66#define INT_TCHSCRN2 31
67
68#define INT_TCSR_MPRPH_SC1 (32 + 0)
69#define INT_USB_FS2 (32 + 1)
70#define INT_PWB_I2C (32 + 2)
71#define INT_SOFTRESET (32 + 3)
72#define INT_NAND_WR_ER_DONE (32 + 4)
73#define INT_NAND_OP_DONE (32 + 5)
74#define INT_TCSR_MPRPH_SC2 (32 + 6)
75#define INT_OP_PEN (32 + 7)
76#define INT_AD_HSSD (32 + 8)
77#define INT_ARM11_PM (32 + 9)
78#define INT_SDMA_NON_SECURE (32 + 10)
79#define INT_TSIF_IRQ (32 + 11)
80#define INT_UART1DM_IRQ (32 + 12)
81#define INT_UART1DM_RX (32 + 13)
82#define INT_SDMA_SECURE (32 + 14)
83#define INT_SI2S_SLAVE (32 + 15)
84#define INT_SC_I2CPU (32 + 16)
85#define INT_SC_DBG_RDTRFULL (32 + 17)
86#define INT_SC_DBG_WDTRFULL (32 + 18)
87#define INT_SCPLL_CTL_DONE (32 + 19)
88#define INT_UART2DM_IRQ (32 + 20)
89#define INT_UART2DM_RX (32 + 21)
90#define INT_VDC_MEC (32 + 22)
91#define INT_VDC_DB (32 + 23)
92#define INT_VDC_AXI (32 + 24)
93#define INT_VFE (32 + 25)
94#define INT_USB_HS (32 + 26)
95#define INT_AUDIO_OUT0 (32 + 27)
96#define INT_AUDIO_OUT1 (32 + 28)
97#define INT_CRYPTO (32 + 29)
98#define INT_AD6M_IDLE (32 + 30)
99#define INT_SIRC_1 (32 + 31)
100
101#define NR_GPIO_IRQS 165
102#define NR_MSM_IRQS 64
103#define NR_BOARD_IRQS 64
104
105#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 9dd4cf8a2693..164d355c96ea 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -1,6 +1,6 @@
1/* arch/arm/mach-msm/include/mach/irqs.h 1/*
2 *
3 * Copyright (C) 2007 Google, Inc. 2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com> 4 * Author: Brian Swetland <swetland@google.com>
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
@@ -17,74 +17,21 @@
17#ifndef __ASM_ARCH_MSM_IRQS_H 17#ifndef __ASM_ARCH_MSM_IRQS_H
18#define __ASM_ARCH_MSM_IRQS_H 18#define __ASM_ARCH_MSM_IRQS_H
19 19
20/* MSM ARM11 Interrupt Numbers */
21/* See 80-VE113-1 A, pp219-221 */
22
23#define INT_A9_M2A_0 0
24#define INT_A9_M2A_1 1
25#define INT_A9_M2A_2 2
26#define INT_A9_M2A_3 3
27#define INT_A9_M2A_4 4
28#define INT_A9_M2A_5 5
29#define INT_A9_M2A_6 6
30#define INT_GP_TIMER_EXP 7
31#define INT_DEBUG_TIMER_EXP 8
32#define INT_UART1 9
33#define INT_UART2 10
34#define INT_UART3 11
35#define INT_UART1_RX 12
36#define INT_UART2_RX 13
37#define INT_UART3_RX 14
38#define INT_USB_OTG 15
39#define INT_MDDI_PRI 16
40#define INT_MDDI_EXT 17
41#define INT_MDDI_CLIENT 18
42#define INT_MDP 19
43#define INT_GRAPHICS 20
44#define INT_ADM_AARM 21
45#define INT_ADSP_A11 22
46#define INT_ADSP_A9_A11 23
47#define INT_SDC1_0 24
48#define INT_SDC1_1 25
49#define INT_SDC2_0 26
50#define INT_SDC2_1 27
51#define INT_KEYSENSE 28
52#define INT_TCHSCRN_SSBI 29
53#define INT_TCHSCRN1 30
54#define INT_TCHSCRN2 31
55
56#define INT_GPIO_GROUP1 (32 + 0)
57#define INT_GPIO_GROUP2 (32 + 1)
58#define INT_PWB_I2C (32 + 2)
59#define INT_SOFTRESET (32 + 3)
60#define INT_NAND_WR_ER_DONE (32 + 4)
61#define INT_NAND_OP_DONE (32 + 5)
62#define INT_PBUS_ARM11 (32 + 6)
63#define INT_AXI_MPU_SMI (32 + 7)
64#define INT_AXI_MPU_EBI1 (32 + 8)
65#define INT_AD_HSSD (32 + 9)
66#define INT_ARM11_PMU (32 + 10)
67#define INT_ARM11_DMA (32 + 11)
68#define INT_TSIF_IRQ (32 + 12)
69#define INT_UART1DM_IRQ (32 + 13)
70#define INT_UART1DM_RX (32 + 14)
71#define INT_USB_HS (32 + 15)
72#define INT_SDC3_0 (32 + 16)
73#define INT_SDC3_1 (32 + 17)
74#define INT_SDC4_0 (32 + 18)
75#define INT_SDC4_1 (32 + 19)
76#define INT_UART2DM_RX (32 + 20)
77#define INT_UART2DM_IRQ (32 + 21)
78
79/* 22-31 are reserved */
80
81#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) 20#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31))
82 21
83#define NR_MSM_IRQS 64 22#if defined(CONFIG_ARCH_MSM7X30)
84#define NR_GPIO_IRQS 122 23#include "irqs-7x30.h"
85#define NR_BOARD_IRQS 64 24#elif defined(CONFIG_ARCH_QSD8X50)
86#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) 25#include "irqs-8x50.h"
26#include "sirc.h"
27#elif defined(CONFIG_ARCH_MSM_ARM11)
28#include "irqs-7x00.h"
29#else
30#error "Unknown architecture specification"
31#endif
87 32
33#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
88#define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n)) 34#define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
35#define MSM_INT_TO_REG(base, irq) (base + irq / 32)
89 36
90#endif 37#endif
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index f4698baec976..50c7847e6002 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -17,7 +17,15 @@
17#define __ASM_ARCH_MEMORY_H 17#define __ASM_ARCH_MEMORY_H
18 18
19/* physical offset of RAM */ 19/* physical offset of RAM */
20#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A)
21#define PHYS_OFFSET UL(0x00000000)
22#elif defined(CONFIG_ARCH_QSD8X50)
23#define PHYS_OFFSET UL(0x20000000)
24#elif defined(CONFIG_ARCH_MSM7X30)
25#define PHYS_OFFSET UL(0x00200000)
26#else
20#define PHYS_OFFSET UL(0x10000000) 27#define PHYS_OFFSET UL(0x10000000)
28#endif
21 29
22#endif 30#endif
23 31
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h
new file mode 100644
index 000000000000..1f4fc81b3d8f
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_fb.h
@@ -0,0 +1,147 @@
1/* arch/arm/mach-msm/include/mach/msm_fb.h
2 *
3 * Internal shared definitions for various MSM framebuffer parts.
4 *
5 * Copyright (C) 2007 Google Incorporated
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 _MSM_FB_H_
18#define _MSM_FB_H_
19
20#include <linux/device.h>
21
22struct mddi_info;
23
24struct msm_fb_data {
25 int xres; /* x resolution in pixels */
26 int yres; /* y resolution in pixels */
27 int width; /* disply width in mm */
28 int height; /* display height in mm */
29 unsigned output_format;
30};
31
32struct msmfb_callback {
33 void (*func)(struct msmfb_callback *);
34};
35
36enum {
37 MSM_MDDI_PMDH_INTERFACE,
38 MSM_MDDI_EMDH_INTERFACE,
39 MSM_EBI2_INTERFACE,
40};
41
42#define MSMFB_CAP_PARTIAL_UPDATES (1 << 0)
43
44struct msm_panel_data {
45 /* turns off the fb memory */
46 int (*suspend)(struct msm_panel_data *);
47 /* turns on the fb memory */
48 int (*resume)(struct msm_panel_data *);
49 /* turns off the panel */
50 int (*blank)(struct msm_panel_data *);
51 /* turns on the panel */
52 int (*unblank)(struct msm_panel_data *);
53 void (*wait_vsync)(struct msm_panel_data *);
54 void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *);
55 void (*clear_vsync)(struct msm_panel_data *);
56 /* from the enum above */
57 unsigned interface_type;
58 /* data to be passed to the fb driver */
59 struct msm_fb_data *fb_data;
60
61 /* capabilities supported by the panel */
62 uint32_t caps;
63};
64
65struct msm_mddi_client_data {
66 void (*suspend)(struct msm_mddi_client_data *);
67 void (*resume)(struct msm_mddi_client_data *);
68 void (*activate_link)(struct msm_mddi_client_data *);
69 void (*remote_write)(struct msm_mddi_client_data *, uint32_t val,
70 uint32_t reg);
71 uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg);
72 void (*auto_hibernate)(struct msm_mddi_client_data *, int);
73 /* custom data that needs to be passed from the board file to a
74 * particular client */
75 void *private_client_data;
76 struct resource *fb_resource;
77 /* from the list above */
78 unsigned interface_type;
79};
80
81struct msm_mddi_platform_data {
82 unsigned int clk_rate;
83 void (*power_client)(struct msm_mddi_client_data *, int on);
84
85 /* fixup the mfr name, product id */
86 void (*fixup)(uint16_t *mfr_name, uint16_t *product_id);
87
88 struct resource *fb_resource; /*optional*/
89 /* number of clients in the list that follows */
90 int num_clients;
91 /* array of client information of clients */
92 struct {
93 unsigned product_id; /* mfr id in top 16 bits, product id
94 * in lower 16 bits
95 */
96 char *name; /* the device name will be the platform
97 * device name registered for the client,
98 * it should match the name of the associated
99 * driver
100 */
101 unsigned id; /* id for mddi client device node, will also
102 * be used as device id of panel devices, if
103 * the client device will have multiple panels
104 * space must be left here for them
105 */
106 void *client_data; /* required private client data */
107 unsigned int clk_rate; /* optional: if the client requires a
108 * different mddi clk rate
109 */
110 } client_platform_data[];
111};
112
113struct mdp_blit_req;
114struct fb_info;
115struct mdp_device {
116 struct device dev;
117 void (*dma)(struct mdp_device *mpd, uint32_t addr,
118 uint32_t stride, uint32_t w, uint32_t h, uint32_t x,
119 uint32_t y, struct msmfb_callback *callback, int interface);
120 void (*dma_wait)(struct mdp_device *mdp);
121 int (*blit)(struct mdp_device *mdp, struct fb_info *fb,
122 struct mdp_blit_req *req);
123 void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id);
124};
125
126struct class_interface;
127int register_mdp_client(struct class_interface *class_intf);
128
129/**** private client data structs go below this line ***/
130
131struct msm_mddi_bridge_platform_data {
132 /* from board file */
133 int (*init)(struct msm_mddi_bridge_platform_data *,
134 struct msm_mddi_client_data *);
135 int (*uninit)(struct msm_mddi_bridge_platform_data *,
136 struct msm_mddi_client_data *);
137 /* passed to panel for use by the fb driver */
138 int (*blank)(struct msm_mddi_bridge_platform_data *,
139 struct msm_mddi_client_data *);
140 int (*unblank)(struct msm_mddi_bridge_platform_data *,
141 struct msm_mddi_client_data *);
142 struct msm_fb_data fb_data;
143};
144
145
146
147#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
new file mode 100644
index 000000000000..cfff0e74f128
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
@@ -0,0 +1,139 @@
1/* arch/arm/mach-msm/include/mach/msm_iomap.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
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 * The MSM peripherals are spread all over across 768MB of physical
17 * space, which makes just having a simple IO_ADDRESS macro to slide
18 * them into the right virtual location rough. Instead, we will
19 * provide a master phys->virt mapping for peripherals here.
20 *
21 */
22
23#ifndef __ASM_ARCH_MSM_IOMAP_7X00_H
24#define __ASM_ARCH_MSM_IOMAP_7X00_H
25
26#include <asm/sizes.h>
27
28/* Physical base address and size of peripherals.
29 * Ordered by the virtual base addresses they will be mapped at.
30 *
31 * MSM_VIC_BASE must be an value that can be loaded via a "mov"
32 * instruction, otherwise entry-macro.S will not compile.
33 *
34 * If you add or remove entries here, you'll want to edit the
35 * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
36 * changes.
37 *
38 */
39
40#ifdef __ASSEMBLY__
41#define IOMEM(x) x
42#else
43#define IOMEM(x) ((void __force __iomem *)(x))
44#endif
45
46#define MSM_VIC_BASE IOMEM(0xE0000000)
47#define MSM_VIC_PHYS 0xC0000000
48#define MSM_VIC_SIZE SZ_4K
49
50#define MSM_CSR_BASE IOMEM(0xE0001000)
51#define MSM_CSR_PHYS 0xC0100000
52#define MSM_CSR_SIZE SZ_4K
53
54#define MSM_GPT_PHYS MSM_CSR_PHYS
55#define MSM_GPT_BASE MSM_CSR_BASE
56#define MSM_GPT_SIZE SZ_4K
57
58#define MSM_DMOV_BASE IOMEM(0xE0002000)
59#define MSM_DMOV_PHYS 0xA9700000
60#define MSM_DMOV_SIZE SZ_4K
61
62#define MSM_GPIO1_BASE IOMEM(0xE0003000)
63#define MSM_GPIO1_PHYS 0xA9200000
64#define MSM_GPIO1_SIZE SZ_4K
65
66#define MSM_GPIO2_BASE IOMEM(0xE0004000)
67#define MSM_GPIO2_PHYS 0xA9300000
68#define MSM_GPIO2_SIZE SZ_4K
69
70#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
71#define MSM_CLK_CTL_PHYS 0xA8600000
72#define MSM_CLK_CTL_SIZE SZ_4K
73
74#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
75#define MSM_SHARED_RAM_PHYS 0x01F00000
76#define MSM_SHARED_RAM_SIZE SZ_1M
77
78#define MSM_UART1_PHYS 0xA9A00000
79#define MSM_UART1_SIZE SZ_4K
80
81#define MSM_UART2_PHYS 0xA9B00000
82#define MSM_UART2_SIZE SZ_4K
83
84#define MSM_UART3_PHYS 0xA9C00000
85#define MSM_UART3_SIZE SZ_4K
86
87#ifdef CONFIG_MSM_DEBUG_UART
88#define MSM_DEBUG_UART_BASE 0xE1000000
89#if CONFIG_MSM_DEBUG_UART == 1
90#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
91#elif CONFIG_MSM_DEBUG_UART == 2
92#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
93#elif CONFIG_MSM_DEBUG_UART == 3
94#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
95#endif
96#define MSM_DEBUG_UART_SIZE SZ_4K
97#endif
98
99#define MSM_SDC1_PHYS 0xA0400000
100#define MSM_SDC1_SIZE SZ_4K
101
102#define MSM_SDC2_PHYS 0xA0500000
103#define MSM_SDC2_SIZE SZ_4K
104
105#define MSM_SDC3_PHYS 0xA0600000
106#define MSM_SDC3_SIZE SZ_4K
107
108#define MSM_SDC4_PHYS 0xA0700000
109#define MSM_SDC4_SIZE SZ_4K
110
111#define MSM_I2C_PHYS 0xA9900000
112#define MSM_I2C_SIZE SZ_4K
113
114#define MSM_HSUSB_PHYS 0xA0800000
115#define MSM_HSUSB_SIZE SZ_4K
116
117#define MSM_PMDH_PHYS 0xAA600000
118#define MSM_PMDH_SIZE SZ_4K
119
120#define MSM_EMDH_PHYS 0xAA700000
121#define MSM_EMDH_SIZE SZ_4K
122
123#define MSM_MDP_PHYS 0xAA200000
124#define MSM_MDP_SIZE 0x000F0000
125
126#define MSM_MDC_PHYS 0xAA500000
127#define MSM_MDC_SIZE SZ_1M
128
129#define MSM_AD5_PHYS 0xAC000000
130#define MSM_AD5_SIZE (SZ_1M*13)
131
132
133#if defined(CONFIG_ARCH_MSM7X30)
134#define MSM_GCC_BASE IOMEM(0xF8009000)
135#define MSM_GCC_PHYS 0xC0182000
136#define MSM_GCC_SIZE SZ_4K
137#endif
138
139#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
new file mode 100644
index 000000000000..8a00c2defbc1
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -0,0 +1,122 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com>
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 * The MSM peripherals are spread all over across 768MB of physical
17 * space, which makes just having a simple IO_ADDRESS macro to slide
18 * them into the right virtual location rough. Instead, we will
19 * provide a master phys->virt mapping for peripherals here.
20 *
21 */
22
23#ifndef __ASM_ARCH_MSM_IOMAP_7X30_H
24#define __ASM_ARCH_MSM_IOMAP_7X30_H
25
26/* Physical base address and size of peripherals.
27 * Ordered by the virtual base addresses they will be mapped at.
28 *
29 * MSM_VIC_BASE must be an value that can be loaded via a "mov"
30 * instruction, otherwise entry-macro.S will not compile.
31 *
32 * If you add or remove entries here, you'll want to edit the
33 * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
34 * changes.
35 *
36 */
37
38#define MSM_VIC_BASE IOMEM(0xE0000000)
39#define MSM_VIC_PHYS 0xC0080000
40#define MSM_VIC_SIZE SZ_4K
41
42#define MSM_CSR_BASE IOMEM(0xE0001000)
43#define MSM_CSR_PHYS 0xC0100000
44#define MSM_CSR_SIZE SZ_4K
45
46#define MSM_TMR_PHYS MSM_CSR_PHYS
47#define MSM_TMR_BASE MSM_CSR_BASE
48#define MSM_TMR_SIZE SZ_4K
49
50#define MSM_GPT_BASE (MSM_TMR_BASE + 0x4)
51#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
52
53#define MSM_DMOV_BASE IOMEM(0xE0002000)
54#define MSM_DMOV_PHYS 0xAC400000
55#define MSM_DMOV_SIZE SZ_4K
56
57#define MSM_GPIO1_BASE IOMEM(0xE0003000)
58#define MSM_GPIO1_PHYS 0xAC001000
59#define MSM_GPIO1_SIZE SZ_4K
60
61#define MSM_GPIO2_BASE IOMEM(0xE0004000)
62#define MSM_GPIO2_PHYS 0xAC101000
63#define MSM_GPIO2_SIZE SZ_4K
64
65#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
66#define MSM_CLK_CTL_PHYS 0xAB800000
67#define MSM_CLK_CTL_SIZE SZ_4K
68
69#define MSM_CLK_CTL_SH2_BASE IOMEM(0xE0006000)
70#define MSM_CLK_CTL_SH2_PHYS 0xABA01000
71#define MSM_CLK_CTL_SH2_SIZE SZ_4K
72
73#define MSM_ACC_BASE IOMEM(0xE0007000)
74#define MSM_ACC_PHYS 0xC0101000
75#define MSM_ACC_SIZE SZ_4K
76
77#define MSM_SAW_BASE IOMEM(0xE0008000)
78#define MSM_SAW_PHYS 0xC0102000
79#define MSM_SAW_SIZE SZ_4K
80
81#define MSM_GCC_BASE IOMEM(0xE0009000)
82#define MSM_GCC_PHYS 0xC0182000
83#define MSM_GCC_SIZE SZ_4K
84
85#define MSM_TCSR_BASE IOMEM(0xE000A000)
86#define MSM_TCSR_PHYS 0xAB600000
87#define MSM_TCSR_SIZE SZ_4K
88
89#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
90#define MSM_SHARED_RAM_PHYS 0x00100000
91#define MSM_SHARED_RAM_SIZE SZ_1M
92
93#define MSM_UART1_PHYS 0xACA00000
94#define MSM_UART1_SIZE SZ_4K
95
96#define MSM_UART2_PHYS 0xACB00000
97#define MSM_UART2_SIZE SZ_4K
98
99#define MSM_UART3_PHYS 0xACC00000
100#define MSM_UART3_SIZE SZ_4K
101
102#ifdef CONFIG_MSM_DEBUG_UART
103#define MSM_DEBUG_UART_BASE 0xE1000000
104#if CONFIG_MSM_DEBUG_UART == 1
105#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
106#elif CONFIG_MSM_DEBUG_UART == 2
107#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
108#elif CONFIG_MSM_DEBUG_UART == 3
109#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
110#endif
111#define MSM_DEBUG_UART_SIZE SZ_4K
112#endif
113
114#define MSM_MDC_BASE IOMEM(0xE0200000)
115#define MSM_MDC_PHYS 0xAA500000
116#define MSM_MDC_SIZE SZ_1M
117
118#define MSM_AD5_BASE IOMEM(0xE0300000)
119#define MSM_AD5_PHYS 0xA7000000
120#define MSM_AD5_SIZE (SZ_1M*13)
121
122#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
new file mode 100644
index 000000000000..acc819eb76e5
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -0,0 +1,147 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com>
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 * The MSM peripherals are spread all over across 768MB of physical
17 * space, which makes just having a simple IO_ADDRESS macro to slide
18 * them into the right virtual location rough. Instead, we will
19 * provide a master phys->virt mapping for peripherals here.
20 *
21 */
22
23#ifndef __ASM_ARCH_MSM_IOMAP_8X50_H
24#define __ASM_ARCH_MSM_IOMAP_8X50_H
25
26/* Physical base address and size of peripherals.
27 * Ordered by the virtual base addresses they will be mapped at.
28 *
29 * MSM_VIC_BASE must be an value that can be loaded via a "mov"
30 * instruction, otherwise entry-macro.S will not compile.
31 *
32 * If you add or remove entries here, you'll want to edit the
33 * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
34 * changes.
35 *
36 */
37
38#define MSM_VIC_BASE IOMEM(0xE0000000)
39#define MSM_VIC_PHYS 0xAC000000
40#define MSM_VIC_SIZE SZ_4K
41
42#define MSM_CSR_BASE IOMEM(0xE0001000)
43#define MSM_CSR_PHYS 0xAC100000
44#define MSM_CSR_SIZE SZ_4K
45
46#define MSM_TMR_PHYS MSM_CSR_PHYS
47#define MSM_TMR_BASE MSM_CSR_BASE
48#define MSM_TMR_SIZE SZ_4K
49
50#define MSM_GPT_BASE MSM_TMR_BASE
51#define MSM_DGT_BASE (MSM_TMR_BASE + 0x10)
52
53#define MSM_DMOV_BASE IOMEM(0xE0002000)
54#define MSM_DMOV_PHYS 0xA9700000
55#define MSM_DMOV_SIZE SZ_4K
56
57#define MSM_GPIO1_BASE IOMEM(0xE0003000)
58#define MSM_GPIO1_PHYS 0xA9000000
59#define MSM_GPIO1_SIZE SZ_4K
60
61#define MSM_GPIO2_BASE IOMEM(0xE0004000)
62#define MSM_GPIO2_PHYS 0xA9100000
63#define MSM_GPIO2_SIZE SZ_4K
64
65#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
66#define MSM_CLK_CTL_PHYS 0xA8600000
67#define MSM_CLK_CTL_SIZE SZ_4K
68
69#define MSM_SIRC_BASE IOMEM(0xE1006000)
70#define MSM_SIRC_PHYS 0xAC200000
71#define MSM_SIRC_SIZE SZ_4K
72
73#define MSM_SCPLL_BASE IOMEM(0xE1007000)
74#define MSM_SCPLL_PHYS 0xA8800000
75#define MSM_SCPLL_SIZE SZ_4K
76
77#ifdef CONFIG_MSM_SOC_REV_A
78#define MSM_SMI_BASE 0xE0000000
79#else
80#define MSM_SMI_BASE 0x00000000
81#endif
82
83#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
84#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
85#define MSM_SHARED_RAM_SIZE SZ_1M
86
87#define MSM_UART1_PHYS 0xA9A00000
88#define MSM_UART1_SIZE SZ_4K
89
90#define MSM_UART2_PHYS 0xA9B00000
91#define MSM_UART2_SIZE SZ_4K
92
93#define MSM_UART3_PHYS 0xA9C00000
94#define MSM_UART3_SIZE SZ_4K
95
96#ifdef CONFIG_MSM_DEBUG_UART
97#define MSM_DEBUG_UART_BASE 0xE1000000
98#if CONFIG_MSM_DEBUG_UART == 1
99#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
100#elif CONFIG_MSM_DEBUG_UART == 2
101#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
102#elif CONFIG_MSM_DEBUG_UART == 3
103#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
104#endif
105#define MSM_DEBUG_UART_SIZE SZ_4K
106#endif
107
108#define MSM_MDC_BASE IOMEM(0xE0200000)
109#define MSM_MDC_PHYS 0xAA500000
110#define MSM_MDC_SIZE SZ_1M
111
112#define MSM_AD5_BASE IOMEM(0xE0300000)
113#define MSM_AD5_PHYS 0xAC000000
114#define MSM_AD5_SIZE (SZ_1M*13)
115
116
117#define MSM_I2C_SIZE SZ_4K
118#define MSM_I2C_PHYS 0xA9900000
119
120#define MSM_HSUSB_PHYS 0xA0800000
121#define MSM_HSUSB_SIZE SZ_1K
122
123#define MSM_NAND_PHYS 0xA0A00000
124
125
126#define MSM_TSIF_PHYS (0xa0100000)
127#define MSM_TSIF_SIZE (0x200)
128
129#define MSM_TSSC_PHYS 0xAA300000
130
131#define MSM_UART1DM_PHYS 0xA0200000
132#define MSM_UART2DM_PHYS 0xA0900000
133
134
135#define MSM_SDC1_PHYS 0xA0400000
136#define MSM_SDC1_SIZE SZ_4K
137
138#define MSM_SDC2_PHYS 0xA0500000
139#define MSM_SDC2_SIZE SZ_4K
140
141#define MSM_SDC3_PHYS 0xA0600000
142#define MSM_SDC3_SIZE SZ_4K
143
144#define MSM_SDC4_PHYS 0xA0700000
145#define MSM_SDC4_SIZE SZ_4K
146
147#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 9dae1a98c77a..e6b1821cc4ea 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -1,6 +1,6 @@
1/* arch/arm/mach-msm/include/mach/msm_iomap.h 1/*
2 *
3 * Copyright (C) 2007 Google, Inc. 2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com> 4 * Author: Brian Swetland <swetland@google.com>
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
@@ -43,91 +43,12 @@
43#define IOMEM(x) ((void __force __iomem *)(x)) 43#define IOMEM(x) ((void __force __iomem *)(x))
44#endif 44#endif
45 45
46#define MSM_VIC_BASE IOMEM(0xE0000000) 46#if defined(CONFIG_ARCH_MSM7X30)
47#define MSM_VIC_PHYS 0xC0000000 47#include "msm_iomap-7x30.h"
48#define MSM_VIC_SIZE SZ_4K 48#elif defined(CONFIG_ARCH_QSD8X50)
49 49#include "msm_iomap-8x50.h"
50#define MSM_CSR_BASE IOMEM(0xE0001000) 50#else
51#define MSM_CSR_PHYS 0xC0100000 51#include "msm_iomap-7x00.h"
52#define MSM_CSR_SIZE SZ_4K
53
54#define MSM_GPT_PHYS MSM_CSR_PHYS
55#define MSM_GPT_BASE MSM_CSR_BASE
56#define MSM_GPT_SIZE SZ_4K
57
58#define MSM_DMOV_BASE IOMEM(0xE0002000)
59#define MSM_DMOV_PHYS 0xA9700000
60#define MSM_DMOV_SIZE SZ_4K
61
62#define MSM_GPIO1_BASE IOMEM(0xE0003000)
63#define MSM_GPIO1_PHYS 0xA9200000
64#define MSM_GPIO1_SIZE SZ_4K
65
66#define MSM_GPIO2_BASE IOMEM(0xE0004000)
67#define MSM_GPIO2_PHYS 0xA9300000
68#define MSM_GPIO2_SIZE SZ_4K
69
70#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
71#define MSM_CLK_CTL_PHYS 0xA8600000
72#define MSM_CLK_CTL_SIZE SZ_4K
73
74#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
75#define MSM_SHARED_RAM_PHYS 0x01F00000
76#define MSM_SHARED_RAM_SIZE SZ_1M
77
78#define MSM_UART1_PHYS 0xA9A00000
79#define MSM_UART1_SIZE SZ_4K
80
81#define MSM_UART2_PHYS 0xA9B00000
82#define MSM_UART2_SIZE SZ_4K
83
84#define MSM_UART3_PHYS 0xA9C00000
85#define MSM_UART3_SIZE SZ_4K
86
87#ifdef CONFIG_MSM_DEBUG_UART
88#define MSM_DEBUG_UART_BASE 0xE1000000
89#if CONFIG_MSM_DEBUG_UART == 1
90#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
91#elif CONFIG_MSM_DEBUG_UART == 2
92#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
93#elif CONFIG_MSM_DEBUG_UART == 3
94#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
95#endif
96#define MSM_DEBUG_UART_SIZE SZ_4K
97#endif 52#endif
98 53
99#define MSM_SDC1_PHYS 0xA0400000
100#define MSM_SDC1_SIZE SZ_4K
101
102#define MSM_SDC2_PHYS 0xA0500000
103#define MSM_SDC2_SIZE SZ_4K
104
105#define MSM_SDC3_PHYS 0xA0600000
106#define MSM_SDC3_SIZE SZ_4K
107
108#define MSM_SDC4_PHYS 0xA0700000
109#define MSM_SDC4_SIZE SZ_4K
110
111#define MSM_I2C_PHYS 0xA9900000
112#define MSM_I2C_SIZE SZ_4K
113
114#define MSM_HSUSB_PHYS 0xA0800000
115#define MSM_HSUSB_SIZE SZ_4K
116
117#define MSM_PMDH_PHYS 0xAA600000
118#define MSM_PMDH_SIZE SZ_4K
119
120#define MSM_EMDH_PHYS 0xAA700000
121#define MSM_EMDH_SIZE SZ_4K
122
123#define MSM_MDP_PHYS 0xAA200000
124#define MSM_MDP_SIZE 0x000F0000
125
126#define MSM_MDC_PHYS 0xAA500000
127#define MSM_MDC_SIZE SZ_1M
128
129#define MSM_AD5_PHYS 0xAC000000
130#define MSM_AD5_SIZE (SZ_1M*13)
131
132
133#endif 54#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
new file mode 100644
index 000000000000..029463ec8756
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -0,0 +1,109 @@
1/* linux/include/asm-arm/arch-msm/msm_smd.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
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 __ASM_ARCH_MSM_SMD_H
18#define __ASM_ARCH_MSM_SMD_H
19
20typedef struct smd_channel smd_channel_t;
21
22extern int (*msm_check_for_modem_crash)(void);
23
24/* warning: notify() may be called before open returns */
25int smd_open(const char *name, smd_channel_t **ch, void *priv,
26 void (*notify)(void *priv, unsigned event));
27
28#define SMD_EVENT_DATA 1
29#define SMD_EVENT_OPEN 2
30#define SMD_EVENT_CLOSE 3
31
32int smd_close(smd_channel_t *ch);
33
34/* passing a null pointer for data reads and discards */
35int smd_read(smd_channel_t *ch, void *data, int len);
36
37/* Write to stream channels may do a partial write and return
38** the length actually written.
39** Write to packet channels will never do a partial write --
40** it will return the requested length written or an error.
41*/
42int smd_write(smd_channel_t *ch, const void *data, int len);
43int smd_write_atomic(smd_channel_t *ch, const void *data, int len);
44
45int smd_write_avail(smd_channel_t *ch);
46int smd_read_avail(smd_channel_t *ch);
47
48/* Returns the total size of the current packet being read.
49** Returns 0 if no packets available or a stream channel.
50*/
51int smd_cur_packet_size(smd_channel_t *ch);
52
53/* used for tty unthrottling and the like -- causes the notify()
54** callback to be called from the same lock context as is used
55** when it is called from channel updates
56*/
57void smd_kick(smd_channel_t *ch);
58
59
60#if 0
61/* these are interruptable waits which will block you until the specified
62** number of bytes are readable or writable.
63*/
64int smd_wait_until_readable(smd_channel_t *ch, int bytes);
65int smd_wait_until_writable(smd_channel_t *ch, int bytes);
66#endif
67
68typedef enum {
69 SMD_PORT_DS = 0,
70 SMD_PORT_DIAG,
71 SMD_PORT_RPC_CALL,
72 SMD_PORT_RPC_REPLY,
73 SMD_PORT_BT,
74 SMD_PORT_CONTROL,
75 SMD_PORT_MEMCPY_SPARE1,
76 SMD_PORT_DATA1,
77 SMD_PORT_DATA2,
78 SMD_PORT_DATA3,
79 SMD_PORT_DATA4,
80 SMD_PORT_DATA5,
81 SMD_PORT_DATA6,
82 SMD_PORT_DATA7,
83 SMD_PORT_DATA8,
84 SMD_PORT_DATA9,
85 SMD_PORT_DATA10,
86 SMD_PORT_DATA11,
87 SMD_PORT_DATA12,
88 SMD_PORT_DATA13,
89 SMD_PORT_DATA14,
90 SMD_PORT_DATA15,
91 SMD_PORT_DATA16,
92 SMD_PORT_DATA17,
93 SMD_PORT_DATA18,
94 SMD_PORT_DATA19,
95 SMD_PORT_DATA20,
96 SMD_PORT_GPS_NMEA,
97 SMD_PORT_BRIDGE_1,
98 SMD_PORT_BRIDGE_2,
99 SMD_PORT_BRIDGE_3,
100 SMD_PORT_BRIDGE_4,
101 SMD_PORT_BRIDGE_5,
102 SMD_PORT_LOOPBACK,
103 SMD_PORT_CS_APPS_MODEM,
104 SMD_PORT_CS_APPS_DSP,
105 SMD_PORT_CS_MODEM_DSP,
106 SMD_NUM_PORTS,
107} smd_port_id_type;
108
109#endif
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h
new file mode 100644
index 000000000000..7281337ee28d
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/sirc.h
@@ -0,0 +1,115 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef __ASM_ARCH_MSM_SIRC_H
31#define __ASM_ARCH_MSM_SIRC_H
32
33struct sirc_regs_t {
34 void *int_enable;
35 void *int_enable_clear;
36 void *int_enable_set;
37 void *int_type;
38 void *int_polarity;
39 void *int_clear;
40};
41
42struct sirc_cascade_regs {
43 void *int_status;
44 unsigned int cascade_irq;
45};
46
47void msm_init_sirc(void);
48void msm_sirc_enter_sleep(void);
49void msm_sirc_exit_sleep(void);
50
51#if defined(CONFIG_ARCH_MSM_SCORPION)
52
53#include <mach/msm_iomap.h>
54
55/*
56 * Secondary interrupt controller interrupts
57 */
58
59#define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS)
60
61#define INT_UART1 (FIRST_SIRC_IRQ + 0)
62#define INT_UART2 (FIRST_SIRC_IRQ + 1)
63#define INT_UART3 (FIRST_SIRC_IRQ + 2)
64#define INT_UART1_RX (FIRST_SIRC_IRQ + 3)
65#define INT_UART2_RX (FIRST_SIRC_IRQ + 4)
66#define INT_UART3_RX (FIRST_SIRC_IRQ + 5)
67#define INT_SPI_INPUT (FIRST_SIRC_IRQ + 6)
68#define INT_SPI_OUTPUT (FIRST_SIRC_IRQ + 7)
69#define INT_SPI_ERROR (FIRST_SIRC_IRQ + 8)
70#define INT_GPIO_GROUP1 (FIRST_SIRC_IRQ + 9)
71#define INT_GPIO_GROUP2 (FIRST_SIRC_IRQ + 10)
72#define INT_GPIO_GROUP1_SECURE (FIRST_SIRC_IRQ + 11)
73#define INT_GPIO_GROUP2_SECURE (FIRST_SIRC_IRQ + 12)
74#define INT_AVS_SVIC (FIRST_SIRC_IRQ + 13)
75#define INT_AVS_REQ_UP (FIRST_SIRC_IRQ + 14)
76#define INT_AVS_REQ_DOWN (FIRST_SIRC_IRQ + 15)
77#define INT_PBUS_ERR (FIRST_SIRC_IRQ + 16)
78#define INT_AXI_ERR (FIRST_SIRC_IRQ + 17)
79#define INT_SMI_ERR (FIRST_SIRC_IRQ + 18)
80#define INT_EBI1_ERR (FIRST_SIRC_IRQ + 19)
81#define INT_IMEM_ERR (FIRST_SIRC_IRQ + 20)
82#define INT_TEMP_SENSOR (FIRST_SIRC_IRQ + 21)
83#define INT_TV_ENC (FIRST_SIRC_IRQ + 22)
84#define INT_GRP2D (FIRST_SIRC_IRQ + 23)
85#define INT_GSBI_QUP (FIRST_SIRC_IRQ + 24)
86#define INT_SC_ACG (FIRST_SIRC_IRQ + 25)
87#define INT_WDT0 (FIRST_SIRC_IRQ + 26)
88#define INT_WDT1 (FIRST_SIRC_IRQ + 27)
89
90#if defined(CONFIG_MSM_SOC_REV_A)
91#define NR_SIRC_IRQS 28
92#define SIRC_MASK 0x0FFFFFFF
93#else
94#define NR_SIRC_IRQS 23
95#define SIRC_MASK 0x007FFFFF
96#endif
97
98#define LAST_SIRC_IRQ (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1)
99
100#define SPSS_SIRC_INT_SELECT (MSM_SIRC_BASE + 0x00)
101#define SPSS_SIRC_INT_ENABLE (MSM_SIRC_BASE + 0x04)
102#define SPSS_SIRC_INT_ENABLE_CLEAR (MSM_SIRC_BASE + 0x08)
103#define SPSS_SIRC_INT_ENABLE_SET (MSM_SIRC_BASE + 0x0C)
104#define SPSS_SIRC_INT_TYPE (MSM_SIRC_BASE + 0x10)
105#define SPSS_SIRC_INT_POLARITY (MSM_SIRC_BASE + 0x14)
106#define SPSS_SIRC_SECURITY (MSM_SIRC_BASE + 0x18)
107#define SPSS_SIRC_IRQ_STATUS (MSM_SIRC_BASE + 0x1C)
108#define SPSS_SIRC_IRQ1_STATUS (MSM_SIRC_BASE + 0x20)
109#define SPSS_SIRC_RAW_STATUS (MSM_SIRC_BASE + 0x24)
110#define SPSS_SIRC_INT_CLEAR (MSM_SIRC_BASE + 0x28)
111#define SPSS_SIRC_SOFT_INT (MSM_SIRC_BASE + 0x2C)
112
113#endif
114
115#endif
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h
index 574ccc493daf..d2e83f42ba16 100644
--- a/arch/arm/mach-msm/include/mach/system.h
+++ b/arch/arm/mach-msm/include/mach/system.h
@@ -21,3 +21,8 @@ static inline void arch_reset(char mode, const char *cmd)
21{ 21{
22 for (;;) ; /* depends on IPC w/ other core */ 22 for (;;) ; /* depends on IPC w/ other core */
23} 23}
24
25/* low level hardware reset hook -- for example, hitting the
26 * PSHOLD line on the PMIC to hard reset the system
27 */
28extern void (*msm_hw_reset_hook)(void);
diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h
index 9f9e25cb718e..6626e7864e28 100644
--- a/arch/arm/mach-msm/include/mach/vreg.h
+++ b/arch/arm/mach-msm/include/mach/vreg.h
@@ -23,7 +23,7 @@ struct vreg *vreg_get(struct device *dev, const char *id);
23void vreg_put(struct vreg *vreg); 23void vreg_put(struct vreg *vreg);
24 24
25int vreg_enable(struct vreg *vreg); 25int vreg_enable(struct vreg *vreg);
26void vreg_disable(struct vreg *vreg); 26int vreg_disable(struct vreg *vreg);
27int vreg_set_level(struct vreg *vreg, unsigned mv); 27int vreg_set_level(struct vreg *vreg, unsigned mv);
28 28
29#endif 29#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 05f96b780aa6..1c05060b5f3b 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -1,8 +1,9 @@
1/* arch/arm/mach-msm/io.c 1/* arch/arm/mach-msm/io.c
2 * 2 *
3 * MSM7K io support 3 * MSM7K, QSD io support
4 * 4 *
5 * Copyright (C) 2007 Google, Inc. 5 * Copyright (C) 2007 Google, Inc.
6 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
6 * Author: Brian Swetland <swetland@google.com> 7 * Author: Brian Swetland <swetland@google.com>
7 * 8 *
8 * This software is licensed under the terms of the GNU General Public 9 * This software is licensed under the terms of the GNU General Public
@@ -34,6 +35,8 @@
34 .type = MT_DEVICE_NONSHARED, \ 35 .type = MT_DEVICE_NONSHARED, \
35 } 36 }
36 37
38#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27) \
39 || defined(CONFIG_ARCH_MSM7X25)
37static struct map_desc msm_io_desc[] __initdata = { 40static struct map_desc msm_io_desc[] __initdata = {
38 MSM_DEVICE(VIC), 41 MSM_DEVICE(VIC),
39 MSM_DEVICE(CSR), 42 MSM_DEVICE(CSR),
@@ -45,9 +48,12 @@ static struct map_desc msm_io_desc[] __initdata = {
45#ifdef CONFIG_MSM_DEBUG_UART 48#ifdef CONFIG_MSM_DEBUG_UART
46 MSM_DEVICE(DEBUG_UART), 49 MSM_DEVICE(DEBUG_UART),
47#endif 50#endif
51#ifdef CONFIG_ARCH_MSM7X30
52 MSM_DEVICE(GCC),
53#endif
48 { 54 {
49 .virtual = (unsigned long) MSM_SHARED_RAM_BASE, 55 .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
50 .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), 56 .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
51 .length = MSM_SHARED_RAM_SIZE, 57 .length = MSM_SHARED_RAM_SIZE,
52 .type = MT_DEVICE, 58 .type = MT_DEVICE,
53 }, 59 },
@@ -60,9 +66,72 @@ void __init msm_map_common_io(void)
60 * pages are peripheral interface or not. 66 * pages are peripheral interface or not.
61 */ 67 */
62 asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0)); 68 asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
63
64 iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc)); 69 iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc));
65} 70}
71#endif
72
73#ifdef CONFIG_ARCH_QSD8X50
74static struct map_desc qsd8x50_io_desc[] __initdata = {
75 MSM_DEVICE(VIC),
76 MSM_DEVICE(CSR),
77 MSM_DEVICE(TMR),
78 MSM_DEVICE(DMOV),
79 MSM_DEVICE(GPIO1),
80 MSM_DEVICE(GPIO2),
81 MSM_DEVICE(CLK_CTL),
82 MSM_DEVICE(SIRC),
83 MSM_DEVICE(SCPLL),
84 MSM_DEVICE(AD5),
85 MSM_DEVICE(MDC),
86#ifdef CONFIG_MSM_DEBUG_UART
87 MSM_DEVICE(DEBUG_UART),
88#endif
89 {
90 .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
91 .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
92 .length = MSM_SHARED_RAM_SIZE,
93 .type = MT_DEVICE,
94 },
95};
96
97void __init msm_map_qsd8x50_io(void)
98{
99 iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc));
100}
101#endif /* CONFIG_ARCH_QSD8X50 */
102
103#ifdef CONFIG_ARCH_MSM7X30
104static struct map_desc msm7x30_io_desc[] __initdata = {
105 MSM_DEVICE(VIC),
106 MSM_DEVICE(CSR),
107 MSM_DEVICE(TMR),
108 MSM_DEVICE(DMOV),
109 MSM_DEVICE(GPIO1),
110 MSM_DEVICE(GPIO2),
111 MSM_DEVICE(CLK_CTL),
112 MSM_DEVICE(CLK_CTL_SH2),
113 MSM_DEVICE(AD5),
114 MSM_DEVICE(MDC),
115 MSM_DEVICE(ACC),
116 MSM_DEVICE(SAW),
117 MSM_DEVICE(GCC),
118 MSM_DEVICE(TCSR),
119#ifdef CONFIG_MSM_DEBUG_UART
120 MSM_DEVICE(DEBUG_UART),
121#endif
122 {
123 .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
124 .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
125 .length = MSM_SHARED_RAM_SIZE,
126 .type = MT_DEVICE,
127 },
128};
129
130void __init msm_map_msm7x30_io(void)
131{
132 iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc));
133}
134#endif /* CONFIG_ARCH_MSM7X30 */
66 135
67void __iomem * 136void __iomem *
68__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) 137__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
new file mode 100644
index 000000000000..99f2c3473033
--- /dev/null
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -0,0 +1,365 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
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
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/sched.h>
19#include <linux/interrupt.h>
20#include <linux/ptrace.h>
21#include <linux/timer.h>
22#include <linux/irq.h>
23#include <linux/io.h>
24
25#include <asm/cacheflush.h>
26
27#include <mach/hardware.h>
28
29#include <mach/msm_iomap.h>
30
31#include "smd_private.h"
32
33enum {
34 IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0,
35 IRQ_DEBUG_SLEEP_INT = 1U << 1,
36 IRQ_DEBUG_SLEEP_ABORT = 1U << 2,
37 IRQ_DEBUG_SLEEP = 1U << 3,
38 IRQ_DEBUG_SLEEP_REQUEST = 1U << 4,
39};
40static int msm_irq_debug_mask;
41module_param_named(debug_mask, msm_irq_debug_mask, int,
42 S_IRUGO | S_IWUSR | S_IWGRP);
43
44#define VIC_REG(off) (MSM_VIC_BASE + (off))
45#define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4)
46#define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3)
47
48#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
49#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
50#define VIC_INT_SELECT2 VIC_REG(0x0008) /* 1: FIQ, 0: IRQ */
51#define VIC_INT_SELECT3 VIC_REG(0x000C) /* 1: FIQ, 0: IRQ */
52#define VIC_INT_EN0 VIC_REG(0x0010)
53#define VIC_INT_EN1 VIC_REG(0x0014)
54#define VIC_INT_EN2 VIC_REG(0x0018)
55#define VIC_INT_EN3 VIC_REG(0x001C)
56#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
57#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
58#define VIC_INT_ENCLEAR2 VIC_REG(0x0028)
59#define VIC_INT_ENCLEAR3 VIC_REG(0x002C)
60#define VIC_INT_ENSET0 VIC_REG(0x0030)
61#define VIC_INT_ENSET1 VIC_REG(0x0034)
62#define VIC_INT_ENSET2 VIC_REG(0x0038)
63#define VIC_INT_ENSET3 VIC_REG(0x003C)
64#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
65#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
66#define VIC_INT_TYPE2 VIC_REG(0x0048) /* 1: EDGE, 0: LEVEL */
67#define VIC_INT_TYPE3 VIC_REG(0x004C) /* 1: EDGE, 0: LEVEL */
68#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
69#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
70#define VIC_INT_POLARITY2 VIC_REG(0x0058) /* 1: NEG, 0: POS */
71#define VIC_INT_POLARITY3 VIC_REG(0x005C) /* 1: NEG, 0: POS */
72#define VIC_NO_PEND_VAL VIC_REG(0x0060)
73
74#if defined(CONFIG_ARCH_MSM_SCORPION)
75#define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064)
76#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */
77#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE SC VIC */
78#else
79#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */
80#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */
81#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */
82#endif
83
84#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
85#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
86#define VIC_IRQ_STATUS2 VIC_REG(0x0088)
87#define VIC_IRQ_STATUS3 VIC_REG(0x008C)
88#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
89#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
90#define VIC_FIQ_STATUS2 VIC_REG(0x0098)
91#define VIC_FIQ_STATUS3 VIC_REG(0x009C)
92#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
93#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
94#define VIC_RAW_STATUS2 VIC_REG(0x00A8)
95#define VIC_RAW_STATUS3 VIC_REG(0x00AC)
96#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
97#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
98#define VIC_INT_CLEAR2 VIC_REG(0x00B8)
99#define VIC_INT_CLEAR3 VIC_REG(0x00BC)
100#define VIC_SOFTINT0 VIC_REG(0x00C0)
101#define VIC_SOFTINT1 VIC_REG(0x00C4)
102#define VIC_SOFTINT2 VIC_REG(0x00C8)
103#define VIC_SOFTINT3 VIC_REG(0x00CC)
104#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
105#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
106#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
107
108#if defined(CONFIG_ARCH_MSM_SCORPION)
109#define VIC_FIQ_VEC_RD VIC_REG(0x00DC)
110#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0)
111#define VIC_FIQ_VEC_WR VIC_REG(0x00E4)
112#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8)
113#define VIC_IRQ_IN_STACK VIC_REG(0x00EC)
114#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0)
115#define VIC_FIQ_IN_STACK VIC_REG(0x00F4)
116#define VIC_TEST_BUS_SEL VIC_REG(0x00F8)
117#define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC)
118#else
119#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0)
120#define VIC_IRQ_IN_STACK VIC_REG(0x00E4)
121#define VIC_TEST_BUS_SEL VIC_REG(0x00E8)
122#endif
123
124#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
125#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4))
126
127#if defined(CONFIG_ARCH_MSM7X30)
128#define VIC_NUM_REGS 4
129#else
130#define VIC_NUM_REGS 2
131#endif
132
133#if VIC_NUM_REGS == 2
134#define DPRINT_REGS(base_reg, format, ...) \
135 printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \
136 readl(base_reg ## 0), readl(base_reg ## 1))
137#define DPRINT_ARRAY(array, format, ...) \
138 printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \
139 array[0], array[1])
140#elif VIC_NUM_REGS == 4
141#define DPRINT_REGS(base_reg, format, ...) \
142 printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \
143 readl(base_reg ## 0), readl(base_reg ## 1), \
144 readl(base_reg ## 2), readl(base_reg ## 3))
145#define DPRINT_ARRAY(array, format, ...) \
146 printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \
147 array[0], array[1], \
148 array[2], array[3])
149#else
150#error "VIC_NUM_REGS set to illegal value"
151#endif
152
153static uint32_t msm_irq_smsm_wake_enable[2];
154static struct {
155 uint32_t int_en[2];
156 uint32_t int_type;
157 uint32_t int_polarity;
158 uint32_t int_select;
159} msm_irq_shadow_reg[VIC_NUM_REGS];
160static uint32_t msm_irq_idle_disable[VIC_NUM_REGS];
161
162#define SMSM_FAKE_IRQ (0xff)
163static uint8_t msm_irq_to_smsm[NR_IRQS] = {
164 [INT_MDDI_EXT] = 1,
165 [INT_MDDI_PRI] = 2,
166 [INT_MDDI_CLIENT] = 3,
167 [INT_USB_OTG] = 4,
168
169 [INT_PWB_I2C] = 5,
170 [INT_SDC1_0] = 6,
171 [INT_SDC1_1] = 7,
172 [INT_SDC2_0] = 8,
173
174 [INT_SDC2_1] = 9,
175 [INT_ADSP_A9_A11] = 10,
176 [INT_UART1] = 11,
177 [INT_UART2] = 12,
178
179 [INT_UART3] = 13,
180 [INT_UART1_RX] = 14,
181 [INT_UART2_RX] = 15,
182 [INT_UART3_RX] = 16,
183
184 [INT_UART1DM_IRQ] = 17,
185 [INT_UART1DM_RX] = 18,
186 [INT_KEYSENSE] = 19,
187#if !defined(CONFIG_ARCH_MSM7X30)
188 [INT_AD_HSSD] = 20,
189#endif
190
191 [INT_NAND_WR_ER_DONE] = 21,
192 [INT_NAND_OP_DONE] = 22,
193 [INT_TCHSCRN1] = 23,
194 [INT_TCHSCRN2] = 24,
195
196 [INT_TCHSCRN_SSBI] = 25,
197 [INT_USB_HS] = 26,
198 [INT_UART2DM_RX] = 27,
199 [INT_UART2DM_IRQ] = 28,
200
201 [INT_SDC4_1] = 29,
202 [INT_SDC4_0] = 30,
203 [INT_SDC3_1] = 31,
204 [INT_SDC3_0] = 32,
205
206 /* fake wakeup interrupts */
207 [INT_GPIO_GROUP1] = SMSM_FAKE_IRQ,
208 [INT_GPIO_GROUP2] = SMSM_FAKE_IRQ,
209 [INT_A9_M2A_0] = SMSM_FAKE_IRQ,
210 [INT_A9_M2A_1] = SMSM_FAKE_IRQ,
211 [INT_A9_M2A_5] = SMSM_FAKE_IRQ,
212 [INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ,
213 [INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ,
214 [INT_ADSP_A11] = SMSM_FAKE_IRQ,
215#ifdef CONFIG_ARCH_QSD8X50
216 [INT_SIRC_0] = SMSM_FAKE_IRQ,
217 [INT_SIRC_1] = SMSM_FAKE_IRQ,
218#endif
219};
220
221static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val)
222{
223 int i;
224
225 for (i = 0; i < VIC_NUM_REGS; i++)
226 writel(val, base + (i * 4));
227}
228
229static void msm_irq_ack(unsigned int irq)
230{
231 void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, irq);
232 irq = 1 << (irq & 31);
233 writel(irq, reg);
234}
235
236static void msm_irq_mask(unsigned int irq)
237{
238 void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, irq);
239 unsigned index = VIC_INT_TO_REG_INDEX(irq);
240 uint32_t mask = 1UL << (irq & 31);
241 int smsm_irq = msm_irq_to_smsm[irq];
242
243 msm_irq_shadow_reg[index].int_en[0] &= ~mask;
244 writel(mask, reg);
245 if (smsm_irq == 0)
246 msm_irq_idle_disable[index] &= ~mask;
247 else {
248 mask = 1UL << (smsm_irq - 1);
249 msm_irq_smsm_wake_enable[0] &= ~mask;
250 }
251}
252
253static void msm_irq_unmask(unsigned int irq)
254{
255 void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, irq);
256 unsigned index = VIC_INT_TO_REG_INDEX(irq);
257 uint32_t mask = 1UL << (irq & 31);
258 int smsm_irq = msm_irq_to_smsm[irq];
259
260 msm_irq_shadow_reg[index].int_en[0] |= mask;
261 writel(mask, reg);
262
263 if (smsm_irq == 0)
264 msm_irq_idle_disable[index] |= mask;
265 else {
266 mask = 1UL << (smsm_irq - 1);
267 msm_irq_smsm_wake_enable[0] |= mask;
268 }
269}
270
271static int msm_irq_set_wake(unsigned int irq, unsigned int on)
272{
273 unsigned index = VIC_INT_TO_REG_INDEX(irq);
274 uint32_t mask = 1UL << (irq & 31);
275 int smsm_irq = msm_irq_to_smsm[irq];
276
277 if (smsm_irq == 0) {
278 printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", irq);
279 return -EINVAL;
280 }
281 if (on)
282 msm_irq_shadow_reg[index].int_en[1] |= mask;
283 else
284 msm_irq_shadow_reg[index].int_en[1] &= ~mask;
285
286 if (smsm_irq == SMSM_FAKE_IRQ)
287 return 0;
288
289 mask = 1UL << (smsm_irq - 1);
290 if (on)
291 msm_irq_smsm_wake_enable[1] |= mask;
292 else
293 msm_irq_smsm_wake_enable[1] &= ~mask;
294 return 0;
295}
296
297static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
298{
299 void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, irq);
300 void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, irq);
301 unsigned index = VIC_INT_TO_REG_INDEX(irq);
302 int b = 1 << (irq & 31);
303 uint32_t polarity;
304 uint32_t type;
305
306 polarity = msm_irq_shadow_reg[index].int_polarity;
307 if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
308 polarity |= b;
309 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
310 polarity &= ~b;
311 writel(polarity, preg);
312 msm_irq_shadow_reg[index].int_polarity = polarity;
313
314 type = msm_irq_shadow_reg[index].int_type;
315 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
316 type |= b;
317 irq_desc[irq].handle_irq = handle_edge_irq;
318 }
319 if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
320 type &= ~b;
321 irq_desc[irq].handle_irq = handle_level_irq;
322 }
323 writel(type, treg);
324 msm_irq_shadow_reg[index].int_type = type;
325 return 0;
326}
327
328static struct irq_chip msm_irq_chip = {
329 .name = "msm",
330 .disable = msm_irq_mask,
331 .ack = msm_irq_ack,
332 .mask = msm_irq_mask,
333 .unmask = msm_irq_unmask,
334 .set_wake = msm_irq_set_wake,
335 .set_type = msm_irq_set_type,
336};
337
338void __init msm_init_irq(void)
339{
340 unsigned n;
341
342 /* select level interrupts */
343 msm_irq_write_all_regs(VIC_INT_TYPE0, 0);
344
345 /* select highlevel interrupts */
346 msm_irq_write_all_regs(VIC_INT_POLARITY0, 0);
347
348 /* select IRQ for all INTs */
349 msm_irq_write_all_regs(VIC_INT_SELECT0, 0);
350
351 /* disable all INTs */
352 msm_irq_write_all_regs(VIC_INT_EN0, 0);
353
354 /* don't use vic */
355 writel(0, VIC_CONFIG);
356
357 /* enable interrupt controller */
358 writel(3, VIC_INT_MASTEREN);
359
360 for (n = 0; n < NR_MSM_IRQS; n++) {
361 set_irq_chip(n, &msm_irq_chip);
362 set_irq_handler(n, handle_level_irq);
363 set_irq_flags(n, IRQF_VALID);
364 }
365}
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
index 69ca0dd79bdf..6c8d5f8caef3 100644
--- a/arch/arm/mach-msm/irq.c
+++ b/arch/arm/mach-msm/irq.c
@@ -101,11 +101,11 @@ static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
101 101
102 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { 102 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
103 writel(readl(treg) | b, treg); 103 writel(readl(treg) | b, treg);
104 set_irq_handler(irq, handle_edge_irq); 104 irq_desc[irq].handle_irq = handle_edge_irq;
105 } 105 }
106 if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { 106 if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
107 writel(readl(treg) & (~b), treg); 107 writel(readl(treg) & (~b), treg);
108 set_irq_handler(irq, handle_level_irq); 108 irq_desc[irq].handle_irq = handle_level_irq;
109 } 109 }
110 return 0; 110 return 0;
111} 111}
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c
new file mode 100644
index 000000000000..b64ba5a98686
--- /dev/null
+++ b/arch/arm/mach-msm/last_radio_log.c
@@ -0,0 +1,82 @@
1/* arch/arm/mach-msm/last_radio_log.c
2 *
3 * Extract the log from a modem crash though SMEM
4 *
5 * Copyright (C) 2007 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/module.h>
20#include <linux/fs.h>
21#include <linux/proc_fs.h>
22#include <linux/uaccess.h>
23
24#include "smd_private.h"
25
26static void *radio_log_base;
27static size_t radio_log_size;
28
29extern void *smem_item(unsigned id, unsigned *size);
30
31static ssize_t last_radio_log_read(struct file *file, char __user *buf,
32 size_t len, loff_t *offset)
33{
34 loff_t pos = *offset;
35 ssize_t count;
36
37 if (pos >= radio_log_size)
38 return 0;
39
40 count = min(len, (size_t)(radio_log_size - pos));
41 if (copy_to_user(buf, radio_log_base + pos, count)) {
42 pr_err("%s: copy to user failed\n", __func__);
43 return -EFAULT;
44 }
45
46 *offset += count;
47 return count;
48}
49
50static struct file_operations last_radio_log_fops = {
51 .read = last_radio_log_read
52};
53
54void msm_init_last_radio_log(struct module *owner)
55{
56 struct proc_dir_entry *entry;
57
58 if (last_radio_log_fops.owner) {
59 pr_err("%s: already claimed\n", __func__);
60 return;
61 }
62
63 radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size);
64 if (!radio_log_base) {
65 pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__);
66 return;
67 }
68
69 entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL);
70 if (!entry) {
71 pr_err("%s: could not create proc entry for radio log\n",
72 __func__);
73 return;
74 }
75
76 pr_err("%s: last radio log is %d bytes long\n", __func__,
77 radio_log_size);
78 last_radio_log_fops.owner = owner;
79 entry->proc_fops = &last_radio_log_fops;
80 entry->size = radio_log_size;
81}
82EXPORT_SYMBOL(msm_init_last_radio_log);
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
index 915ee704ed3c..67e701c7f183 100644
--- a/arch/arm/mach-msm/proc_comm.c
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -23,11 +23,18 @@
23 23
24#include "proc_comm.h" 24#include "proc_comm.h"
25 25
26#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) 26static inline void msm_a2m_int(uint32_t irq)
27{
28#if defined(CONFIG_ARCH_MSM7X30)
29 writel(1 << irq, MSM_GCC_BASE + 0x8);
30#else
31 writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
32#endif
33}
27 34
28static inline void notify_other_proc_comm(void) 35static inline void notify_other_proc_comm(void)
29{ 36{
30 writel(1, MSM_A2M_INT(6)); 37 msm_a2m_int(6);
31} 38}
32 39
33#define APP_COMMAND 0x00 40#define APP_COMMAND 0x00
@@ -107,4 +114,17 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
107 return ret; 114 return ret;
108} 115}
109 116
110 117/*
118 * We need to wait for the ARM9 to at least partially boot
119 * up before we can continue. Since the ARM9 does resource
120 * allocation, if we dont' wait we could end up crashing or in
121 * and unknown state. This function should be called early to
122 * wait on the ARM9.
123 */
124void __init proc_comm_boot_wait(void)
125{
126 void __iomem *base = MSM_SHARED_RAM_BASE;
127
128 proc_comm_wait_for(base + MDM_STATUS, PCOM_READY);
129
130}
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h
index 834760f25692..12da4cacd4a8 100644
--- a/arch/arm/mach-msm/proc_comm.h
+++ b/arch/arm/mach-msm/proc_comm.h
@@ -16,6 +16,8 @@
16#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_ 16#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
17#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_ 17#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
18 18
19#include <linux/init.h>
20
19enum { 21enum {
20 PCOM_CMD_IDLE = 0x0, 22 PCOM_CMD_IDLE = 0x0,
21 PCOM_CMD_DONE, 23 PCOM_CMD_DONE,
@@ -62,19 +64,104 @@ enum {
62 PCOM_RESET_CHIP_IMM, 64 PCOM_RESET_CHIP_IMM,
63 PCOM_PM_VID_EN, 65 PCOM_PM_VID_EN,
64 PCOM_VREG_PULLDOWN, 66 PCOM_VREG_PULLDOWN,
67 PCOM_GET_MODEM_VERSION,
68 PCOM_CLK_REGIME_SEC_RESET,
69 PCOM_CLK_REGIME_SEC_RESET_ASSERT,
70 PCOM_CLK_REGIME_SEC_RESET_DEASSERT,
71 PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP,
72 PCOM_CLK_REGIME_SEC_ENABLE,
73 PCOM_CLK_REGIME_SEC_DISABLE,
74 PCOM_CLK_REGIME_SEC_IS_ON,
75 PCOM_CLK_REGIME_SEC_SEL_CLK_INV,
76 PCOM_CLK_REGIME_SEC_SEL_CLK_SRC,
77 PCOM_CLK_REGIME_SEC_SEL_CLK_DIV,
78 PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE,
79 PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE,
80 PCOM_CLK_REGIME_SEC_SEL_SPEED,
81 PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP,
82 PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP,
83 PCOM_CLK_REGIME_SEC_USB_XTAL_ON,
84 PCOM_CLK_REGIME_SEC_USB_XTAL_OFF,
85 PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE,
86 PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK,
87 PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ,
88 PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ,
89 PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ,
90 PCOM_CLK_REGIME_SEC_SEL_VFE_SRC,
91 PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK,
92 PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK,
93 PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF,
94 PCOM_CLK_REGIME_SEC_VFE_RAIL_ON,
95 PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF,
96 PCOM_CLK_REGIME_SEC_GRP_RAIL_ON,
97 PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF,
98 PCOM_CLK_REGIME_SEC_VDC_RAIL_ON,
99 PCOM_CLK_REGIME_SEC_LCD_CTRL,
100 PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE,
101 PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE,
102 PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP,
103 PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER,
104 PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP,
105 PCOM_GPIO_CONFIG,
106 PCOM_GPIO_CONFIGURE_GROUP,
107 PCOM_GPIO_TLMM_SET_PORT,
108 PCOM_GPIO_TLMM_CONFIG_EX,
109 PCOM_SET_FTM_BOOT_COUNT,
110 PCOM_RESERVED0,
111 PCOM_RESERVED1,
112 PCOM_CUSTOMER_CMD1,
113 PCOM_CUSTOMER_CMD2,
114 PCOM_CUSTOMER_CMD3,
115 PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE,
116 PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE,
117 PCOM_CLK_REGIME_SEC_RAIL_DISABLE,
118 PCOM_CLK_REGIME_SEC_RAIL_ENABLE,
119 PCOM_CLK_REGIME_SEC_RAIL_CONTROL,
120 PCOM_SET_SW_WATCHDOG_STATE,
121 PCOM_PM_MPP_CONFIG_DIGITAL_INPUT,
122 PCOM_PM_MPP_CONFIG_I_SINK,
123 PCOM_RESERVED_101,
124 PCOM_MSM_HSUSB_PHY_RESET,
125 PCOM_GET_BATT_MV_LEVEL,
126 PCOM_CHG_USB_IS_PC_CONNECTED,
127 PCOM_CHG_USB_IS_CHARGER_CONNECTED,
128 PCOM_CHG_USB_IS_DISCONNECTED,
129 PCOM_CHG_USB_IS_AVAILABLE,
130 PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ,
131 PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY,
132 PCOM_CLKCTL_RPC_RESET_ASSERT,
133 PCOM_CLKCTL_RPC_RESET_DEASSERT,
134 PCOM_CLKCTL_RPC_RAIL_ON,
135 PCOM_CLKCTL_RPC_RAIL_OFF,
136 PCOM_CLKCTL_RPC_RAIL_ENABLE,
137 PCOM_CLKCTL_RPC_RAIL_DISABLE,
138 PCOM_CLKCTL_RPC_RAIL_CONTROL,
139 PCOM_CLKCTL_RPC_MIN_MSMC1,
65 PCOM_NUM_CMDS, 140 PCOM_NUM_CMDS,
66}; 141};
67 142
68enum { 143enum {
69 PCOM_INVALID_STATUS = 0x0, 144 PCOM_INVALID_STATUS = 0x0,
70 PCOM_READY, 145 PCOM_READY,
71 PCOM_CMD_RUNNING, 146 PCOM_CMD_RUNNING,
72 PCOM_CMD_SUCCESS, 147 PCOM_CMD_SUCCESS,
73 PCOM_CMD_FAIL, 148 PCOM_CMD_FAIL,
149 PCOM_CMD_FAIL_FALSE_RETURNED,
150 PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER,
151 PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT,
152 PCOM_CMD_FAIL_CMD_UNREGISTERED,
153 PCOM_CMD_FAIL_CMD_LOCKED,
154 PCOM_CMD_FAIL_SERVER_NOT_YET_READY,
155 PCOM_CMD_FAIL_BAD_DESTINATION,
156 PCOM_CMD_FAIL_SERVER_RESET,
157 PCOM_CMD_FAIL_SMSM_NOT_INIT,
158 PCOM_CMD_FAIL_PROC_COMM_BUSY,
159 PCOM_CMD_FAIL_PROC_COMM_NOT_INIT,
160
74}; 161};
75 162
76/* List of VREGs that support the Pull Down Resistor setting. */ 163/* List of VREGs that support the Pull Down Resistor setting. */
77enum { 164enum vreg_pdown_id {
78 PM_VREG_PDOWN_MSMA_ID, 165 PM_VREG_PDOWN_MSMA_ID,
79 PM_VREG_PDOWN_MSMP_ID, 166 PM_VREG_PDOWN_MSMP_ID,
80 PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */ 167 PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
@@ -131,6 +218,11 @@ enum {
131 PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID 218 PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
132}; 219};
133 220
221enum {
222 PCOM_CLKRGM_APPS_RESET_USB_PHY = 34,
223 PCOM_CLKRGM_APPS_RESET_USBH = 37,
224};
225
134/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */ 226/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
135 227
136#define GPIO_ENABLE 0 228#define GPIO_ENABLE 0
@@ -161,5 +253,6 @@ enum {
161 (((drvstr) & 0xF) << 17)) 253 (((drvstr) & 0xF) << 17))
162 254
163int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2); 255int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
256void __init proc_comm_boot_wait(void);
164 257
165#endif 258#endif
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
new file mode 100644
index 000000000000..b0794524ba6e
--- /dev/null
+++ b/arch/arm/mach-msm/sirc.c
@@ -0,0 +1,177 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 */
18
19#include <linux/io.h>
20#include <linux/irq.h>
21#include <linux/interrupt.h>
22#include <asm/irq.h>
23
24static unsigned int int_enable;
25static unsigned int wake_enable;
26
27static struct sirc_regs_t sirc_regs = {
28 .int_enable = SPSS_SIRC_INT_ENABLE,
29 .int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR,
30 .int_enable_set = SPSS_SIRC_INT_ENABLE_SET,
31 .int_type = SPSS_SIRC_INT_TYPE,
32 .int_polarity = SPSS_SIRC_INT_POLARITY,
33 .int_clear = SPSS_SIRC_INT_CLEAR,
34};
35
36static struct sirc_cascade_regs sirc_reg_table[] = {
37 {
38 .int_status = SPSS_SIRC_IRQ_STATUS,
39 .cascade_irq = INT_SIRC_0,
40 }
41};
42
43static unsigned int save_type;
44static unsigned int save_polarity;
45
46/* Mask off the given interrupt. Keep the int_enable mask in sync with
47 the enable reg, so it can be restored after power collapse. */
48static void sirc_irq_mask(unsigned int irq)
49{
50 unsigned int mask;
51
52
53 mask = 1 << (irq - FIRST_SIRC_IRQ);
54 writel(mask, sirc_regs.int_enable_clear);
55 int_enable &= ~mask;
56 return;
57}
58
59/* Unmask the given interrupt. Keep the int_enable mask in sync with
60 the enable reg, so it can be restored after power collapse. */
61static void sirc_irq_unmask(unsigned int irq)
62{
63 unsigned int mask;
64
65 mask = 1 << (irq - FIRST_SIRC_IRQ);
66 writel(mask, sirc_regs.int_enable_set);
67 int_enable |= mask;
68 return;
69}
70
71static void sirc_irq_ack(unsigned int irq)
72{
73 unsigned int mask;
74
75 mask = 1 << (irq - FIRST_SIRC_IRQ);
76 writel(mask, sirc_regs.int_clear);
77 return;
78}
79
80static int sirc_irq_set_wake(unsigned int irq, unsigned int on)
81{
82 unsigned int mask;
83
84 /* Used to set the interrupt enable mask during power collapse. */
85 mask = 1 << (irq - FIRST_SIRC_IRQ);
86 if (on)
87 wake_enable |= mask;
88 else
89 wake_enable &= ~mask;
90
91 return 0;
92}
93
94static int sirc_irq_set_type(unsigned int irq, unsigned int flow_type)
95{
96 unsigned int mask;
97 unsigned int val;
98
99 mask = 1 << (irq - FIRST_SIRC_IRQ);
100 val = readl(sirc_regs.int_polarity);
101
102 if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING))
103 val |= mask;
104 else
105 val &= ~mask;
106
107 writel(val, sirc_regs.int_polarity);
108
109 val = readl(sirc_regs.int_type);
110 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
111 val |= mask;
112 irq_desc[irq].handle_irq = handle_edge_irq;
113 } else {
114 val &= ~mask;
115 irq_desc[irq].handle_irq = handle_level_irq;
116 }
117
118 writel(val, sirc_regs.int_type);
119
120 return 0;
121}
122
123/* Finds the pending interrupt on the passed cascade irq and redrives it */
124static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc)
125{
126 unsigned int reg = 0;
127 unsigned int sirq;
128 unsigned int status;
129
130 while ((reg < ARRAY_SIZE(sirc_reg_table)) &&
131 (sirc_reg_table[reg].cascade_irq != irq))
132 reg++;
133
134 status = readl(sirc_reg_table[reg].int_status);
135 status &= SIRC_MASK;
136 if (status == 0)
137 return;
138
139 for (sirq = 0;
140 (sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0);
141 sirq++)
142 ;
143 generic_handle_irq(sirq+FIRST_SIRC_IRQ);
144
145 desc->chip->ack(irq);
146}
147
148static struct irq_chip sirc_irq_chip = {
149 .name = "sirc",
150 .ack = sirc_irq_ack,
151 .mask = sirc_irq_mask,
152 .unmask = sirc_irq_unmask,
153 .set_wake = sirc_irq_set_wake,
154 .set_type = sirc_irq_set_type,
155};
156
157void __init msm_init_sirc(void)
158{
159 int i;
160
161 int_enable = 0;
162 wake_enable = 0;
163
164 for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) {
165 set_irq_chip(i, &sirc_irq_chip);
166 set_irq_handler(i, handle_edge_irq);
167 set_irq_flags(i, IRQF_VALID);
168 }
169
170 for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
171 set_irq_chained_handler(sirc_reg_table[i].cascade_irq,
172 sirc_irq_handler);
173 set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
174 }
175 return;
176}
177
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
new file mode 100644
index 000000000000..cf11d414b425
--- /dev/null
+++ b/arch/arm/mach-msm/smd.c
@@ -0,0 +1,1046 @@
1/* arch/arm/mach-msm/smd.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
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/platform_device.h>
18#include <linux/module.h>
19#include <linux/fs.h>
20#include <linux/cdev.h>
21#include <linux/device.h>
22#include <linux/wait.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/list.h>
26#include <linux/slab.h>
27#include <linux/debugfs.h>
28#include <linux/delay.h>
29
30#include <mach/msm_smd.h>
31#include <mach/system.h>
32
33#include "smd_private.h"
34#include "proc_comm.h"
35
36#if defined(CONFIG_ARCH_QSD8X50)
37#define CONFIG_QDSP6 1
38#endif
39
40void (*msm_hw_reset_hook)(void);
41
42#define MODULE_NAME "msm_smd"
43
44enum {
45 MSM_SMD_DEBUG = 1U << 0,
46 MSM_SMSM_DEBUG = 1U << 0,
47};
48
49static int msm_smd_debug_mask;
50
51struct shared_info {
52 int ready;
53 unsigned state;
54};
55
56static unsigned dummy_state[SMSM_STATE_COUNT];
57
58static struct shared_info smd_info = {
59 .state = (unsigned) &dummy_state,
60};
61
62module_param_named(debug_mask, msm_smd_debug_mask,
63 int, S_IRUGO | S_IWUSR | S_IWGRP);
64
65static unsigned last_heap_free = 0xffffffff;
66
67static inline void notify_other_smsm(void)
68{
69 msm_a2m_int(5);
70#ifdef CONFIG_QDSP6
71 msm_a2m_int(8);
72#endif
73}
74
75static inline void notify_modem_smd(void)
76{
77 msm_a2m_int(0);
78}
79
80static inline void notify_dsp_smd(void)
81{
82 msm_a2m_int(8);
83}
84
85static void smd_diag(void)
86{
87 char *x;
88
89 x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
90 if (x != 0) {
91 x[SZ_DIAG_ERR_MSG - 1] = 0;
92 pr_info("smem: DIAG '%s'\n", x);
93 }
94}
95
96/* call when SMSM_RESET flag is set in the A9's smsm_state */
97static void handle_modem_crash(void)
98{
99 pr_err("ARM9 has CRASHED\n");
100 smd_diag();
101
102 /* hard reboot if possible */
103 if (msm_hw_reset_hook)
104 msm_hw_reset_hook();
105
106 /* in this case the modem or watchdog should reboot us */
107 for (;;)
108 ;
109}
110
111uint32_t raw_smsm_get_state(enum smsm_state_item item)
112{
113 return readl(smd_info.state + item * 4);
114}
115
116static int check_for_modem_crash(void)
117{
118 if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
119 handle_modem_crash();
120 return -1;
121 }
122 return 0;
123}
124
125/* the spinlock is used to synchronize between the
126 * irq handler and code that mutates the channel
127 * list or fiddles with channel state
128 */
129DEFINE_SPINLOCK(smd_lock);
130DEFINE_SPINLOCK(smem_lock);
131
132/* the mutex is used during open() and close()
133 * operations to avoid races while creating or
134 * destroying smd_channel structures
135 */
136static DEFINE_MUTEX(smd_creation_mutex);
137
138static int smd_initialized;
139
140LIST_HEAD(smd_ch_closed_list);
141LIST_HEAD(smd_ch_list_modem);
142LIST_HEAD(smd_ch_list_dsp);
143
144static unsigned char smd_ch_allocated[64];
145static struct work_struct probe_work;
146
147/* how many bytes are available for reading */
148static int smd_stream_read_avail(struct smd_channel *ch)
149{
150 return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
151}
152
153/* how many bytes we are free to write */
154static int smd_stream_write_avail(struct smd_channel *ch)
155{
156 return ch->fifo_mask -
157 ((ch->send->head - ch->send->tail) & ch->fifo_mask);
158}
159
160static int smd_packet_read_avail(struct smd_channel *ch)
161{
162 if (ch->current_packet) {
163 int n = smd_stream_read_avail(ch);
164 if (n > ch->current_packet)
165 n = ch->current_packet;
166 return n;
167 } else {
168 return 0;
169 }
170}
171
172static int smd_packet_write_avail(struct smd_channel *ch)
173{
174 int n = smd_stream_write_avail(ch);
175 return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
176}
177
178static int ch_is_open(struct smd_channel *ch)
179{
180 return (ch->recv->state == SMD_SS_OPENED) &&
181 (ch->send->state == SMD_SS_OPENED);
182}
183
184/* provide a pointer and length to readable data in the fifo */
185static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
186{
187 unsigned head = ch->recv->head;
188 unsigned tail = ch->recv->tail;
189 *ptr = (void *) (ch->recv_data + tail);
190
191 if (tail <= head)
192 return head - tail;
193 else
194 return ch->fifo_size - tail;
195}
196
197/* advance the fifo read pointer after data from ch_read_buffer is consumed */
198static void ch_read_done(struct smd_channel *ch, unsigned count)
199{
200 BUG_ON(count > smd_stream_read_avail(ch));
201 ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
202 ch->send->fTAIL = 1;
203}
204
205/* basic read interface to ch_read_{buffer,done} used
206 * by smd_*_read() and update_packet_state()
207 * will read-and-discard if the _data pointer is null
208 */
209static int ch_read(struct smd_channel *ch, void *_data, int len)
210{
211 void *ptr;
212 unsigned n;
213 unsigned char *data = _data;
214 int orig_len = len;
215
216 while (len > 0) {
217 n = ch_read_buffer(ch, &ptr);
218 if (n == 0)
219 break;
220
221 if (n > len)
222 n = len;
223 if (_data)
224 memcpy(data, ptr, n);
225
226 data += n;
227 len -= n;
228 ch_read_done(ch, n);
229 }
230
231 return orig_len - len;
232}
233
234static void update_stream_state(struct smd_channel *ch)
235{
236 /* streams have no special state requiring updating */
237}
238
239static void update_packet_state(struct smd_channel *ch)
240{
241 unsigned hdr[5];
242 int r;
243
244 /* can't do anything if we're in the middle of a packet */
245 if (ch->current_packet != 0)
246 return;
247
248 /* don't bother unless we can get the full header */
249 if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
250 return;
251
252 r = ch_read(ch, hdr, SMD_HEADER_SIZE);
253 BUG_ON(r != SMD_HEADER_SIZE);
254
255 ch->current_packet = hdr[0];
256}
257
258/* provide a pointer and length to next free space in the fifo */
259static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
260{
261 unsigned head = ch->send->head;
262 unsigned tail = ch->send->tail;
263 *ptr = (void *) (ch->send_data + head);
264
265 if (head < tail) {
266 return tail - head - 1;
267 } else {
268 if (tail == 0)
269 return ch->fifo_size - head - 1;
270 else
271 return ch->fifo_size - head;
272 }
273}
274
275/* advace the fifo write pointer after freespace
276 * from ch_write_buffer is filled
277 */
278static void ch_write_done(struct smd_channel *ch, unsigned count)
279{
280 BUG_ON(count > smd_stream_write_avail(ch));
281 ch->send->head = (ch->send->head + count) & ch->fifo_mask;
282 ch->send->fHEAD = 1;
283}
284
285static void ch_set_state(struct smd_channel *ch, unsigned n)
286{
287 if (n == SMD_SS_OPENED) {
288 ch->send->fDSR = 1;
289 ch->send->fCTS = 1;
290 ch->send->fCD = 1;
291 } else {
292 ch->send->fDSR = 0;
293 ch->send->fCTS = 0;
294 ch->send->fCD = 0;
295 }
296 ch->send->state = n;
297 ch->send->fSTATE = 1;
298 ch->notify_other_cpu();
299}
300
301static void do_smd_probe(void)
302{
303 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
304 if (shared->heap_info.free_offset != last_heap_free) {
305 last_heap_free = shared->heap_info.free_offset;
306 schedule_work(&probe_work);
307 }
308}
309
310static void smd_state_change(struct smd_channel *ch,
311 unsigned last, unsigned next)
312{
313 ch->last_state = next;
314
315 pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next);
316
317 switch (next) {
318 case SMD_SS_OPENING:
319 ch->recv->tail = 0;
320 case SMD_SS_OPENED:
321 if (ch->send->state != SMD_SS_OPENED)
322 ch_set_state(ch, SMD_SS_OPENED);
323 ch->notify(ch->priv, SMD_EVENT_OPEN);
324 break;
325 case SMD_SS_FLUSHING:
326 case SMD_SS_RESET:
327 /* we should force them to close? */
328 default:
329 ch->notify(ch->priv, SMD_EVENT_CLOSE);
330 }
331}
332
333static void handle_smd_irq(struct list_head *list, void (*notify)(void))
334{
335 unsigned long flags;
336 struct smd_channel *ch;
337 int do_notify = 0;
338 unsigned ch_flags;
339 unsigned tmp;
340
341 spin_lock_irqsave(&smd_lock, flags);
342 list_for_each_entry(ch, list, ch_list) {
343 ch_flags = 0;
344 if (ch_is_open(ch)) {
345 if (ch->recv->fHEAD) {
346 ch->recv->fHEAD = 0;
347 ch_flags |= 1;
348 do_notify |= 1;
349 }
350 if (ch->recv->fTAIL) {
351 ch->recv->fTAIL = 0;
352 ch_flags |= 2;
353 do_notify |= 1;
354 }
355 if (ch->recv->fSTATE) {
356 ch->recv->fSTATE = 0;
357 ch_flags |= 4;
358 do_notify |= 1;
359 }
360 }
361 tmp = ch->recv->state;
362 if (tmp != ch->last_state)
363 smd_state_change(ch, ch->last_state, tmp);
364 if (ch_flags) {
365 ch->update_state(ch);
366 ch->notify(ch->priv, SMD_EVENT_DATA);
367 }
368 }
369 if (do_notify)
370 notify();
371 spin_unlock_irqrestore(&smd_lock, flags);
372 do_smd_probe();
373}
374
375static irqreturn_t smd_modem_irq_handler(int irq, void *data)
376{
377 handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
378 return IRQ_HANDLED;
379}
380
381#if defined(CONFIG_QDSP6)
382static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
383{
384 handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
385 return IRQ_HANDLED;
386}
387#endif
388
389static void smd_fake_irq_handler(unsigned long arg)
390{
391 handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
392 handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
393}
394
395static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
396
397static inline int smd_need_int(struct smd_channel *ch)
398{
399 if (ch_is_open(ch)) {
400 if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
401 return 1;
402 if (ch->recv->state != ch->last_state)
403 return 1;
404 }
405 return 0;
406}
407
408void smd_sleep_exit(void)
409{
410 unsigned long flags;
411 struct smd_channel *ch;
412 int need_int = 0;
413
414 spin_lock_irqsave(&smd_lock, flags);
415 list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
416 if (smd_need_int(ch)) {
417 need_int = 1;
418 break;
419 }
420 }
421 list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
422 if (smd_need_int(ch)) {
423 need_int = 1;
424 break;
425 }
426 }
427 spin_unlock_irqrestore(&smd_lock, flags);
428 do_smd_probe();
429
430 if (need_int) {
431 if (msm_smd_debug_mask & MSM_SMD_DEBUG)
432 pr_info("smd_sleep_exit need interrupt\n");
433 tasklet_schedule(&smd_fake_irq_tasklet);
434 }
435}
436
437
438void smd_kick(smd_channel_t *ch)
439{
440 unsigned long flags;
441 unsigned tmp;
442
443 spin_lock_irqsave(&smd_lock, flags);
444 ch->update_state(ch);
445 tmp = ch->recv->state;
446 if (tmp != ch->last_state) {
447 ch->last_state = tmp;
448 if (tmp == SMD_SS_OPENED)
449 ch->notify(ch->priv, SMD_EVENT_OPEN);
450 else
451 ch->notify(ch->priv, SMD_EVENT_CLOSE);
452 }
453 ch->notify(ch->priv, SMD_EVENT_DATA);
454 ch->notify_other_cpu();
455 spin_unlock_irqrestore(&smd_lock, flags);
456}
457
458static int smd_is_packet(int chn, unsigned type)
459{
460 type &= SMD_KIND_MASK;
461 if (type == SMD_KIND_PACKET)
462 return 1;
463 if (type == SMD_KIND_STREAM)
464 return 0;
465
466 /* older AMSS reports SMD_KIND_UNKNOWN always */
467 if ((chn > 4) || (chn == 1))
468 return 1;
469 else
470 return 0;
471}
472
473static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
474{
475 void *ptr;
476 const unsigned char *buf = _data;
477 unsigned xfer;
478 int orig_len = len;
479
480 if (len < 0)
481 return -EINVAL;
482
483 while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
484 if (!ch_is_open(ch))
485 break;
486 if (xfer > len)
487 xfer = len;
488 memcpy(ptr, buf, xfer);
489 ch_write_done(ch, xfer);
490 len -= xfer;
491 buf += xfer;
492 if (len == 0)
493 break;
494 }
495
496 ch->notify_other_cpu();
497
498 return orig_len - len;
499}
500
501static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
502{
503 unsigned hdr[5];
504
505 if (len < 0)
506 return -EINVAL;
507
508 if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
509 return -ENOMEM;
510
511 hdr[0] = len;
512 hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
513
514 smd_stream_write(ch, hdr, sizeof(hdr));
515 smd_stream_write(ch, _data, len);
516
517 return len;
518}
519
520static int smd_stream_read(smd_channel_t *ch, void *data, int len)
521{
522 int r;
523
524 if (len < 0)
525 return -EINVAL;
526
527 r = ch_read(ch, data, len);
528 if (r > 0)
529 ch->notify_other_cpu();
530
531 return r;
532}
533
534static int smd_packet_read(smd_channel_t *ch, void *data, int len)
535{
536 unsigned long flags;
537 int r;
538
539 if (len < 0)
540 return -EINVAL;
541
542 if (len > ch->current_packet)
543 len = ch->current_packet;
544
545 r = ch_read(ch, data, len);
546 if (r > 0)
547 ch->notify_other_cpu();
548
549 spin_lock_irqsave(&smd_lock, flags);
550 ch->current_packet -= r;
551 update_packet_state(ch);
552 spin_unlock_irqrestore(&smd_lock, flags);
553
554 return r;
555}
556
557static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
558{
559 struct smd_channel *ch;
560
561 ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
562 if (ch == 0) {
563 pr_err("smd_alloc_channel() out of memory\n");
564 return -1;
565 }
566 ch->n = cid;
567
568 if (_smd_alloc_channel(ch)) {
569 kfree(ch);
570 return -1;
571 }
572
573 ch->fifo_mask = ch->fifo_size - 1;
574 ch->type = type;
575
576 if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
577 ch->notify_other_cpu = notify_modem_smd;
578 else
579 ch->notify_other_cpu = notify_dsp_smd;
580
581 if (smd_is_packet(cid, type)) {
582 ch->read = smd_packet_read;
583 ch->write = smd_packet_write;
584 ch->read_avail = smd_packet_read_avail;
585 ch->write_avail = smd_packet_write_avail;
586 ch->update_state = update_packet_state;
587 } else {
588 ch->read = smd_stream_read;
589 ch->write = smd_stream_write;
590 ch->read_avail = smd_stream_read_avail;
591 ch->write_avail = smd_stream_write_avail;
592 ch->update_state = update_stream_state;
593 }
594
595 if ((type & 0xff) == 0)
596 memcpy(ch->name, "SMD_", 4);
597 else
598 memcpy(ch->name, "DSP_", 4);
599 memcpy(ch->name + 4, name, 20);
600 ch->name[23] = 0;
601 ch->pdev.name = ch->name;
602 ch->pdev.id = -1;
603
604 pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
605 ch->n, ch->fifo_size, ch->name);
606
607 mutex_lock(&smd_creation_mutex);
608 list_add(&ch->ch_list, &smd_ch_closed_list);
609 mutex_unlock(&smd_creation_mutex);
610
611 platform_device_register(&ch->pdev);
612 return 0;
613}
614
615static void smd_channel_probe_worker(struct work_struct *work)
616{
617 struct smd_alloc_elm *shared;
618 unsigned ctype;
619 unsigned type;
620 unsigned n;
621
622 shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
623 if (!shared) {
624 pr_err("smd: cannot find allocation table\n");
625 return;
626 }
627 for (n = 0; n < 64; n++) {
628 if (smd_ch_allocated[n])
629 continue;
630 if (!shared[n].ref_count)
631 continue;
632 if (!shared[n].name[0])
633 continue;
634 ctype = shared[n].ctype;
635 type = ctype & SMD_TYPE_MASK;
636
637 /* DAL channels are stream but neither the modem,
638 * nor the DSP correctly indicate this. Fixup manually.
639 */
640 if (!memcmp(shared[n].name, "DAL", 3))
641 ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
642
643 type = shared[n].ctype & SMD_TYPE_MASK;
644 if ((type == SMD_TYPE_APPS_MODEM) ||
645 (type == SMD_TYPE_APPS_DSP))
646 if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
647 smd_ch_allocated[n] = 1;
648 }
649}
650
651static void do_nothing_notify(void *priv, unsigned flags)
652{
653}
654
655struct smd_channel *smd_get_channel(const char *name)
656{
657 struct smd_channel *ch;
658
659 mutex_lock(&smd_creation_mutex);
660 list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
661 if (!strcmp(name, ch->name)) {
662 list_del(&ch->ch_list);
663 mutex_unlock(&smd_creation_mutex);
664 return ch;
665 }
666 }
667 mutex_unlock(&smd_creation_mutex);
668
669 return NULL;
670}
671
672int smd_open(const char *name, smd_channel_t **_ch,
673 void *priv, void (*notify)(void *, unsigned))
674{
675 struct smd_channel *ch;
676 unsigned long flags;
677
678 if (smd_initialized == 0) {
679 pr_info("smd_open() before smd_init()\n");
680 return -ENODEV;
681 }
682
683 ch = smd_get_channel(name);
684 if (!ch)
685 return -ENODEV;
686
687 if (notify == 0)
688 notify = do_nothing_notify;
689
690 ch->notify = notify;
691 ch->current_packet = 0;
692 ch->last_state = SMD_SS_CLOSED;
693 ch->priv = priv;
694
695 *_ch = ch;
696
697 spin_lock_irqsave(&smd_lock, flags);
698
699 if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
700 list_add(&ch->ch_list, &smd_ch_list_modem);
701 else
702 list_add(&ch->ch_list, &smd_ch_list_dsp);
703
704 /* If the remote side is CLOSING, we need to get it to
705 * move to OPENING (which we'll do by moving from CLOSED to
706 * OPENING) and then get it to move from OPENING to
707 * OPENED (by doing the same state change ourselves).
708 *
709 * Otherwise, it should be OPENING and we can move directly
710 * to OPENED so that it will follow.
711 */
712 if (ch->recv->state == SMD_SS_CLOSING) {
713 ch->send->head = 0;
714 ch_set_state(ch, SMD_SS_OPENING);
715 } else {
716 ch_set_state(ch, SMD_SS_OPENED);
717 }
718 spin_unlock_irqrestore(&smd_lock, flags);
719 smd_kick(ch);
720
721 return 0;
722}
723
724int smd_close(smd_channel_t *ch)
725{
726 unsigned long flags;
727
728 pr_info("smd_close(%p)\n", ch);
729
730 if (ch == 0)
731 return -1;
732
733 spin_lock_irqsave(&smd_lock, flags);
734 ch->notify = do_nothing_notify;
735 list_del(&ch->ch_list);
736 ch_set_state(ch, SMD_SS_CLOSED);
737 spin_unlock_irqrestore(&smd_lock, flags);
738
739 mutex_lock(&smd_creation_mutex);
740 list_add(&ch->ch_list, &smd_ch_closed_list);
741 mutex_unlock(&smd_creation_mutex);
742
743 return 0;
744}
745
746int smd_read(smd_channel_t *ch, void *data, int len)
747{
748 return ch->read(ch, data, len);
749}
750
751int smd_write(smd_channel_t *ch, const void *data, int len)
752{
753 return ch->write(ch, data, len);
754}
755
756int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
757{
758 unsigned long flags;
759 int res;
760 spin_lock_irqsave(&smd_lock, flags);
761 res = ch->write(ch, data, len);
762 spin_unlock_irqrestore(&smd_lock, flags);
763 return res;
764}
765
766int smd_read_avail(smd_channel_t *ch)
767{
768 return ch->read_avail(ch);
769}
770
771int smd_write_avail(smd_channel_t *ch)
772{
773 return ch->write_avail(ch);
774}
775
776int smd_wait_until_readable(smd_channel_t *ch, int bytes)
777{
778 return -1;
779}
780
781int smd_wait_until_writable(smd_channel_t *ch, int bytes)
782{
783 return -1;
784}
785
786int smd_cur_packet_size(smd_channel_t *ch)
787{
788 return ch->current_packet;
789}
790
791
792/* ------------------------------------------------------------------------- */
793
794void *smem_alloc(unsigned id, unsigned size)
795{
796 return smem_find(id, size);
797}
798
799void *smem_item(unsigned id, unsigned *size)
800{
801 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
802 struct smem_heap_entry *toc = shared->heap_toc;
803
804 if (id >= SMEM_NUM_ITEMS)
805 return 0;
806
807 if (toc[id].allocated) {
808 *size = toc[id].size;
809 return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
810 } else {
811 *size = 0;
812 }
813
814 return 0;
815}
816
817void *smem_find(unsigned id, unsigned size_in)
818{
819 unsigned size;
820 void *ptr;
821
822 ptr = smem_item(id, &size);
823 if (!ptr)
824 return 0;
825
826 size_in = ALIGN(size_in, 8);
827 if (size_in != size) {
828 pr_err("smem_find(%d, %d): wrong size %d\n",
829 id, size_in, size);
830 return 0;
831 }
832
833 return ptr;
834}
835
836static irqreturn_t smsm_irq_handler(int irq, void *data)
837{
838 unsigned long flags;
839 unsigned apps, modm;
840
841 spin_lock_irqsave(&smem_lock, flags);
842
843 apps = raw_smsm_get_state(SMSM_STATE_APPS);
844 modm = raw_smsm_get_state(SMSM_STATE_MODEM);
845
846 if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
847 pr_info("<SM %08x %08x>\n", apps, modm);
848 if (modm & SMSM_RESET)
849 handle_modem_crash();
850
851 do_smd_probe();
852
853 spin_unlock_irqrestore(&smem_lock, flags);
854 return IRQ_HANDLED;
855}
856
857int smsm_change_state(enum smsm_state_item item,
858 uint32_t clear_mask, uint32_t set_mask)
859{
860 unsigned long addr = smd_info.state + item * 4;
861 unsigned long flags;
862 unsigned state;
863
864 if (!smd_info.ready)
865 return -EIO;
866
867 spin_lock_irqsave(&smem_lock, flags);
868
869 if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
870 handle_modem_crash();
871
872 state = (readl(addr) & ~clear_mask) | set_mask;
873 writel(state, addr);
874
875 if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
876 pr_info("smsm_change_state %d %x\n", item, state);
877 notify_other_smsm();
878
879 spin_unlock_irqrestore(&smem_lock, flags);
880
881 return 0;
882}
883
884uint32_t smsm_get_state(enum smsm_state_item item)
885{
886 unsigned long flags;
887 uint32_t rv;
888
889 spin_lock_irqsave(&smem_lock, flags);
890
891 rv = readl(smd_info.state + item * 4);
892
893 if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
894 handle_modem_crash();
895
896 spin_unlock_irqrestore(&smem_lock, flags);
897
898 return rv;
899}
900
901#ifdef CONFIG_ARCH_MSM_SCORPION
902
903int smsm_set_sleep_duration(uint32_t delay)
904{
905 struct msm_dem_slave_data *ptr;
906
907 ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
908 if (ptr == NULL) {
909 pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
910 return -EIO;
911 }
912 if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
913 pr_info("smsm_set_sleep_duration %d -> %d\n",
914 ptr->sleep_time, delay);
915 ptr->sleep_time = delay;
916 return 0;
917}
918
919#else
920
921int smsm_set_sleep_duration(uint32_t delay)
922{
923 uint32_t *ptr;
924
925 ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
926 if (ptr == NULL) {
927 pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
928 return -EIO;
929 }
930 if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
931 pr_info("smsm_set_sleep_duration %d -> %d\n",
932 *ptr, delay);
933 *ptr = delay;
934 return 0;
935}
936
937#endif
938
939int smd_core_init(void)
940{
941 int r;
942 pr_info("smd_core_init()\n");
943
944 /* wait for essential items to be initialized */
945 for (;;) {
946 unsigned size;
947 void *state;
948 state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
949 if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
950 smd_info.state = (unsigned)state;
951 break;
952 }
953 }
954
955 smd_info.ready = 1;
956
957 r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
958 IRQF_TRIGGER_RISING, "smd_dev", 0);
959 if (r < 0)
960 return r;
961 r = enable_irq_wake(INT_A9_M2A_0);
962 if (r < 0)
963 pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
964
965 r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
966 IRQF_TRIGGER_RISING, "smsm_dev", 0);
967 if (r < 0) {
968 free_irq(INT_A9_M2A_0, 0);
969 return r;
970 }
971 r = enable_irq_wake(INT_A9_M2A_5);
972 if (r < 0)
973 pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
974
975#if defined(CONFIG_QDSP6)
976 r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
977 IRQF_TRIGGER_RISING, "smd_dsp", 0);
978 if (r < 0) {
979 free_irq(INT_A9_M2A_0, 0);
980 free_irq(INT_A9_M2A_5, 0);
981 return r;
982 }
983#endif
984
985 /* check for any SMD channels that may already exist */
986 do_smd_probe();
987
988 /* indicate that we're up and running */
989 smsm_change_state(SMSM_STATE_APPS,
990 ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
991#ifdef CONFIG_ARCH_MSM_SCORPION
992 smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
993#endif
994
995 pr_info("smd_core_init() done\n");
996
997 return 0;
998}
999
1000static int __init msm_smd_probe(struct platform_device *pdev)
1001{
1002 pr_info("smd_init()\n");
1003
1004 /*
1005 * If we haven't waited for the ARM9 to boot up till now,
1006 * then we need to wait here. Otherwise this should just
1007 * return immediately.
1008 */
1009 proc_comm_boot_wait();
1010
1011 INIT_WORK(&probe_work, smd_channel_probe_worker);
1012
1013 if (smd_core_init()) {
1014 pr_err("smd_core_init() failed\n");
1015 return -1;
1016 }
1017
1018 do_smd_probe();
1019
1020 msm_check_for_modem_crash = check_for_modem_crash;
1021
1022 msm_init_last_radio_log(THIS_MODULE);
1023
1024 smd_initialized = 1;
1025
1026 return 0;
1027}
1028
1029static struct platform_driver msm_smd_driver = {
1030 .probe = msm_smd_probe,
1031 .driver = {
1032 .name = MODULE_NAME,
1033 .owner = THIS_MODULE,
1034 },
1035};
1036
1037static int __init msm_smd_init(void)
1038{
1039 return platform_driver_register(&msm_smd_driver);
1040}
1041
1042module_init(msm_smd_init);
1043
1044MODULE_DESCRIPTION("MSM Shared Memory Core");
1045MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
1046MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
new file mode 100644
index 000000000000..3b2dd717b788
--- /dev/null
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -0,0 +1,315 @@
1/* arch/arm/mach-msm/smd_debug.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
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/debugfs.h>
18#include <linux/list.h>
19
20#include <mach/msm_iomap.h>
21
22#include "smd_private.h"
23
24#if defined(CONFIG_DEBUG_FS)
25
26static char *chstate(unsigned n)
27{
28 switch (n) {
29 case SMD_SS_CLOSED:
30 return "CLOSED";
31 case SMD_SS_OPENING:
32 return "OPENING";
33 case SMD_SS_OPENED:
34 return "OPENED";
35 case SMD_SS_FLUSHING:
36 return "FLUSHING";
37 case SMD_SS_CLOSING:
38 return "CLOSING";
39 case SMD_SS_RESET:
40 return "RESET";
41 case SMD_SS_RESET_OPENING:
42 return "ROPENING";
43 default:
44 return "UNKNOWN";
45 }
46}
47
48
49static int dump_ch(char *buf, int max, struct smd_channel *ch)
50{
51 volatile struct smd_half_channel *s = ch->send;
52 volatile struct smd_half_channel *r = ch->recv;
53
54 return scnprintf(
55 buf, max,
56 "ch%02d:"
57 " %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
58 " %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n,
59 chstate(s->state), s->tail, s->head,
60 s->fDSR ? 'D' : 'd',
61 s->fCTS ? 'C' : 'c',
62 s->fCD ? 'C' : 'c',
63 s->fRI ? 'I' : 'i',
64 s->fHEAD ? 'W' : 'w',
65 s->fTAIL ? 'R' : 'r',
66 s->fSTATE ? 'S' : 's',
67 chstate(r->state), r->tail, r->head,
68 r->fDSR ? 'D' : 'd',
69 r->fCTS ? 'R' : 'r',
70 r->fCD ? 'C' : 'c',
71 r->fRI ? 'I' : 'i',
72 r->fHEAD ? 'W' : 'w',
73 r->fTAIL ? 'R' : 'r',
74 r->fSTATE ? 'S' : 's',
75 ch->name
76 );
77}
78
79static int debug_read_stat(char *buf, int max)
80{
81 char *msg;
82 int i = 0;
83
84 msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
85
86 if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
87 i += scnprintf(buf + i, max - i,
88 "smsm: ARM9 HAS CRASHED\n");
89
90 i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
91 raw_smsm_get_state(SMSM_STATE_MODEM),
92 raw_smsm_get_state(SMSM_STATE_APPS));
93#ifdef CONFIG_ARCH_MSM_SCORPION
94 i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x "
95 "qdsp6: %08x power: %08x time: %08x\n",
96 raw_smsm_get_state(SMSM_STATE_APPS_DEM),
97 raw_smsm_get_state(SMSM_STATE_MODEM_DEM),
98 raw_smsm_get_state(SMSM_STATE_QDSP6_DEM),
99 raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM),
100 raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM));
101#endif
102 if (msg) {
103 msg[SZ_DIAG_ERR_MSG - 1] = 0;
104 i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
105 }
106 return i;
107}
108
109static int debug_read_mem(char *buf, int max)
110{
111 unsigned n;
112 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
113 struct smem_heap_entry *toc = shared->heap_toc;
114 int i = 0;
115
116 i += scnprintf(buf + i, max - i,
117 "heap: init=%d free=%d remain=%d\n",
118 shared->heap_info.initialized,
119 shared->heap_info.free_offset,
120 shared->heap_info.heap_remaining);
121
122 for (n = 0; n < SMEM_NUM_ITEMS; n++) {
123 if (toc[n].allocated == 0)
124 continue;
125 i += scnprintf(buf + i, max - i,
126 "%04d: offset %08x size %08x\n",
127 n, toc[n].offset, toc[n].size);
128 }
129 return i;
130}
131
132static int debug_read_ch(char *buf, int max)
133{
134 struct smd_channel *ch;
135 unsigned long flags;
136 int i = 0;
137
138 spin_lock_irqsave(&smd_lock, flags);
139 list_for_each_entry(ch, &smd_ch_list_dsp, ch_list)
140 i += dump_ch(buf + i, max - i, ch);
141 list_for_each_entry(ch, &smd_ch_list_modem, ch_list)
142 i += dump_ch(buf + i, max - i, ch);
143 list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
144 i += dump_ch(buf + i, max - i, ch);
145 spin_unlock_irqrestore(&smd_lock, flags);
146
147 return i;
148}
149
150static int debug_read_version(char *buf, int max)
151{
152 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
153 unsigned version = shared->version[VERSION_MODEM];
154 return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
155}
156
157static int debug_read_build_id(char *buf, int max)
158{
159 unsigned size;
160 void *data;
161
162 data = smem_item(SMEM_HW_SW_BUILD_ID, &size);
163 if (!data)
164 return 0;
165
166 if (size >= max)
167 size = max;
168 memcpy(buf, data, size);
169
170 return size;
171}
172
173static int debug_read_alloc_tbl(char *buf, int max)
174{
175 struct smd_alloc_elm *shared;
176 int n, i = 0;
177
178 shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
179
180 for (n = 0; n < 64; n++) {
181 if (shared[n].ref_count == 0)
182 continue;
183 i += scnprintf(buf + i, max - i,
184 "%03d: %-20s cid=%02d type=%03d "
185 "kind=%02d ref_count=%d\n",
186 n, shared[n].name, shared[n].cid,
187 shared[n].ctype & 0xff,
188 (shared[n].ctype >> 8) & 0xf,
189 shared[n].ref_count);
190 }
191
192 return i;
193}
194
195#define DEBUG_BUFMAX 4096
196static char debug_buffer[DEBUG_BUFMAX];
197
198static ssize_t debug_read(struct file *file, char __user *buf,
199 size_t count, loff_t *ppos)
200{
201 int (*fill)(char *buf, int max) = file->private_data;
202 int bsize = fill(debug_buffer, DEBUG_BUFMAX);
203 return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
204}
205
206static int debug_open(struct inode *inode, struct file *file)
207{
208 file->private_data = inode->i_private;
209 return 0;
210}
211
212static const struct file_operations debug_ops = {
213 .read = debug_read,
214 .open = debug_open,
215};
216
217static void debug_create(const char *name, mode_t mode,
218 struct dentry *dent,
219 int (*fill)(char *buf, int max))
220{
221 debugfs_create_file(name, mode, dent, fill, &debug_ops);
222}
223
224static int smd_debugfs_init(void)
225{
226 struct dentry *dent;
227
228 dent = debugfs_create_dir("smd", 0);
229 if (IS_ERR(dent))
230 return 1;
231
232 debug_create("ch", 0444, dent, debug_read_ch);
233 debug_create("stat", 0444, dent, debug_read_stat);
234 debug_create("mem", 0444, dent, debug_read_mem);
235 debug_create("version", 0444, dent, debug_read_version);
236 debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
237 debug_create("build", 0444, dent, debug_read_build_id);
238
239 return 0;
240}
241
242late_initcall(smd_debugfs_init);
243#endif
244
245
246#define MAX_NUM_SLEEP_CLIENTS 64
247#define MAX_SLEEP_NAME_LEN 8
248
249#define NUM_GPIO_INT_REGISTERS 6
250#define GPIO_SMEM_NUM_GROUPS 2
251#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
252
253struct tramp_gpio_save {
254 unsigned int enable;
255 unsigned int detect;
256 unsigned int polarity;
257};
258
259struct tramp_gpio_smem {
260 uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
261 uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
262 uint32_t enabled[NUM_GPIO_INT_REGISTERS];
263 uint32_t detection[NUM_GPIO_INT_REGISTERS];
264 uint32_t polarity[NUM_GPIO_INT_REGISTERS];
265};
266
267
268void smsm_print_sleep_info(void)
269{
270 unsigned long flags;
271 uint32_t *ptr;
272 struct tramp_gpio_smem *gpio;
273 struct smsm_interrupt_info *int_info;
274
275
276 spin_lock_irqsave(&smem_lock, flags);
277
278 ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
279 if (ptr)
280 pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
281
282 ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
283 if (ptr)
284 pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
285
286 ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
287 if (ptr)
288 pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
289
290#ifndef CONFIG_ARCH_MSM_SCORPION
291 int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
292 if (int_info)
293 pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
294 int_info->interrupt_mask,
295 int_info->pending_interrupts,
296 int_info->wakeup_reason);
297
298 gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
299 if (gpio) {
300 int i;
301 for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
302 pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
303 i, gpio->enabled[i], gpio->detection[i],
304 gpio->polarity[i]);
305
306 for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
307 pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
308 i, gpio->num_fired[i], gpio->fired[i][0],
309 gpio->fired[i][1]);
310 }
311#else
312#endif
313 spin_unlock_irqrestore(&smem_lock, flags);
314}
315
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
new file mode 100644
index 000000000000..727bfe68aa9b
--- /dev/null
+++ b/arch/arm/mach-msm/smd_private.h
@@ -0,0 +1,403 @@
1/* arch/arm/mach-msm/smd_private.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007 QUALCOMM Incorporated
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 _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
17#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
18
19#include <linux/platform_device.h>
20#include <linux/spinlock.h>
21#include <linux/list.h>
22#include <linux/io.h>
23
24#include <mach/msm_iomap.h>
25
26struct smem_heap_info {
27 unsigned initialized;
28 unsigned free_offset;
29 unsigned heap_remaining;
30 unsigned reserved;
31};
32
33struct smem_heap_entry {
34 unsigned allocated;
35 unsigned offset;
36 unsigned size;
37 unsigned reserved;
38};
39
40struct smem_proc_comm {
41 unsigned command;
42 unsigned status;
43 unsigned data1;
44 unsigned data2;
45};
46
47#define PC_APPS 0
48#define PC_MODEM 1
49
50#define VERSION_SMD 0
51#define VERSION_QDSP6 4
52#define VERSION_APPS_SBL 6
53#define VERSION_MODEM_SBL 7
54#define VERSION_APPS 8
55#define VERSION_MODEM 9
56
57struct smem_shared {
58 struct smem_proc_comm proc_comm[4];
59 unsigned version[32];
60 struct smem_heap_info heap_info;
61 struct smem_heap_entry heap_toc[512];
62};
63
64#define SMSM_V1_SIZE (sizeof(unsigned) * 8)
65#define SMSM_V2_SIZE (sizeof(unsigned) * 4)
66
67#ifdef CONFIG_MSM_SMD_PKG3
68struct smsm_interrupt_info {
69 uint32_t interrupt_mask;
70 uint32_t pending_interrupts;
71 uint32_t wakeup_reason;
72};
73#else
74#define DEM_MAX_PORT_NAME_LEN (20)
75struct msm_dem_slave_data {
76 uint32_t sleep_time;
77 uint32_t interrupt_mask;
78 uint32_t resources_used;
79 uint32_t reserved1;
80
81 uint32_t wakeup_reason;
82 uint32_t pending_interrupts;
83 uint32_t rpc_prog;
84 uint32_t rpc_proc;
85 char smd_port_name[DEM_MAX_PORT_NAME_LEN];
86 uint32_t reserved2;
87};
88#endif
89
90#define SZ_DIAG_ERR_MSG 0xC8
91#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
92#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
93#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE
94#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL
95
96#define SMSM_INIT 0x00000001
97#define SMSM_SMDINIT 0x00000008
98#define SMSM_RPCINIT 0x00000020
99#define SMSM_RESET 0x00000040
100#define SMSM_RSA 0x00000080
101#define SMSM_RUN 0x00000100
102#define SMSM_PWRC 0x00000200
103#define SMSM_TIMEWAIT 0x00000400
104#define SMSM_TIMEINIT 0x00000800
105#define SMSM_PWRC_EARLY_EXIT 0x00001000
106#define SMSM_WFPI 0x00002000
107#define SMSM_SLEEP 0x00004000
108#define SMSM_SLEEPEXIT 0x00008000
109#define SMSM_APPS_REBOOT 0x00020000
110#define SMSM_SYSTEM_POWER_DOWN 0x00040000
111#define SMSM_SYSTEM_REBOOT 0x00080000
112#define SMSM_SYSTEM_DOWNLOAD 0x00100000
113#define SMSM_PWRC_SUSPEND 0x00200000
114#define SMSM_APPS_SHUTDOWN 0x00400000
115#define SMSM_SMD_LOOPBACK 0x00800000
116#define SMSM_RUN_QUIET 0x01000000
117#define SMSM_MODEM_WAIT 0x02000000
118#define SMSM_MODEM_BREAK 0x04000000
119#define SMSM_MODEM_CONTINUE 0x08000000
120#define SMSM_UNKNOWN 0x80000000
121
122#define SMSM_WKUP_REASON_RPC 0x00000001
123#define SMSM_WKUP_REASON_INT 0x00000002
124#define SMSM_WKUP_REASON_GPIO 0x00000004
125#define SMSM_WKUP_REASON_TIMER 0x00000008
126#define SMSM_WKUP_REASON_ALARM 0x00000010
127#define SMSM_WKUP_REASON_RESET 0x00000020
128
129#ifdef CONFIG_ARCH_MSM7X00A
130enum smsm_state_item {
131 SMSM_STATE_APPS = 1,
132 SMSM_STATE_MODEM = 3,
133 SMSM_STATE_COUNT,
134};
135#else
136enum smsm_state_item {
137 SMSM_STATE_APPS,
138 SMSM_STATE_MODEM,
139 SMSM_STATE_HEXAGON,
140 SMSM_STATE_APPS_DEM,
141 SMSM_STATE_MODEM_DEM,
142 SMSM_STATE_QDSP6_DEM,
143 SMSM_STATE_POWER_MASTER_DEM,
144 SMSM_STATE_TIME_MASTER_DEM,
145 SMSM_STATE_COUNT,
146};
147#endif
148
149void *smem_alloc(unsigned id, unsigned size);
150int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask);
151uint32_t smsm_get_state(enum smsm_state_item item);
152int smsm_set_sleep_duration(uint32_t delay);
153void smsm_print_sleep_info(void);
154
155#define SMEM_NUM_SMD_CHANNELS 64
156
157typedef enum {
158 /* fixed items */
159 SMEM_PROC_COMM = 0,
160 SMEM_HEAP_INFO,
161 SMEM_ALLOCATION_TABLE,
162 SMEM_VERSION_INFO,
163 SMEM_HW_RESET_DETECT,
164 SMEM_AARM_WARM_BOOT,
165 SMEM_DIAG_ERR_MESSAGE,
166 SMEM_SPINLOCK_ARRAY,
167 SMEM_MEMORY_BARRIER_LOCATION,
168
169 /* dynamic items */
170 SMEM_AARM_PARTITION_TABLE,
171 SMEM_AARM_BAD_BLOCK_TABLE,
172 SMEM_RESERVE_BAD_BLOCKS,
173 SMEM_WM_UUID,
174 SMEM_CHANNEL_ALLOC_TBL,
175 SMEM_SMD_BASE_ID,
176 SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
177 SMEM_SMEM_LOG_EVENTS,
178 SMEM_SMEM_STATIC_LOG_IDX,
179 SMEM_SMEM_STATIC_LOG_EVENTS,
180 SMEM_SMEM_SLOW_CLOCK_SYNC,
181 SMEM_SMEM_SLOW_CLOCK_VALUE,
182 SMEM_BIO_LED_BUF,
183 SMEM_SMSM_SHARED_STATE,
184 SMEM_SMSM_INT_INFO,
185 SMEM_SMSM_SLEEP_DELAY,
186 SMEM_SMSM_LIMIT_SLEEP,
187 SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
188 SMEM_KEYPAD_KEYS_PRESSED,
189 SMEM_KEYPAD_STATE_UPDATED,
190 SMEM_KEYPAD_STATE_IDX,
191 SMEM_GPIO_INT,
192 SMEM_MDDI_LCD_IDX,
193 SMEM_MDDI_HOST_DRIVER_STATE,
194 SMEM_MDDI_LCD_DISP_STATE,
195 SMEM_LCD_CUR_PANEL,
196 SMEM_MARM_BOOT_SEGMENT_INFO,
197 SMEM_AARM_BOOT_SEGMENT_INFO,
198 SMEM_SLEEP_STATIC,
199 SMEM_SCORPION_FREQUENCY,
200 SMEM_SMD_PROFILES,
201 SMEM_TSSC_BUSY,
202 SMEM_HS_SUSPEND_FILTER_INFO,
203 SMEM_BATT_INFO,
204 SMEM_APPS_BOOT_MODE,
205 SMEM_VERSION_FIRST,
206 SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
207 SMEM_OSS_RRCASN1_BUF1,
208 SMEM_OSS_RRCASN1_BUF2,
209 SMEM_ID_VENDOR0,
210 SMEM_ID_VENDOR1,
211 SMEM_ID_VENDOR2,
212 SMEM_HW_SW_BUILD_ID,
213 SMEM_SMD_BLOCK_PORT_BASE_ID,
214 SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS,
215 SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS,
216 SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS,
217 SMEM_SCLK_CONVERSION,
218 SMEM_SMD_SMSM_INTR_MUX,
219 SMEM_SMSM_CPU_INTR_MASK,
220 SMEM_APPS_DEM_SLAVE_DATA,
221 SMEM_QDSP6_DEM_SLAVE_DATA,
222 SMEM_CLKREGIM_BSP,
223 SMEM_CLKREGIM_SOURCES,
224 SMEM_SMD_FIFO_BASE_ID,
225 SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS,
226 SMEM_POWER_ON_STATUS_INFO,
227 SMEM_DAL_AREA,
228 SMEM_SMEM_LOG_POWER_IDX,
229 SMEM_SMEM_LOG_POWER_WRAP,
230 SMEM_SMEM_LOG_POWER_EVENTS,
231 SMEM_ERR_CRASH_LOG,
232 SMEM_ERR_F3_TRACE_LOG,
233 SMEM_NUM_ITEMS,
234} smem_mem_type;
235
236
237#define SMD_SS_CLOSED 0x00000000
238#define SMD_SS_OPENING 0x00000001
239#define SMD_SS_OPENED 0x00000002
240#define SMD_SS_FLUSHING 0x00000003
241#define SMD_SS_CLOSING 0x00000004
242#define SMD_SS_RESET 0x00000005
243#define SMD_SS_RESET_OPENING 0x00000006
244
245#define SMD_BUF_SIZE 8192
246#define SMD_CHANNELS 64
247
248#define SMD_HEADER_SIZE 20
249
250struct smd_alloc_elm {
251 char name[20];
252 uint32_t cid;
253 uint32_t ctype;
254 uint32_t ref_count;
255};
256
257struct smd_half_channel {
258 unsigned state;
259 unsigned char fDSR;
260 unsigned char fCTS;
261 unsigned char fCD;
262 unsigned char fRI;
263 unsigned char fHEAD;
264 unsigned char fTAIL;
265 unsigned char fSTATE;
266 unsigned char fUNUSED;
267 unsigned tail;
268 unsigned head;
269} __attribute__(( aligned(4), packed ));
270
271/* Only used on SMD package v3 on msm7201a */
272struct smd_shared_v1 {
273 struct smd_half_channel ch0;
274 unsigned char data0[SMD_BUF_SIZE];
275 struct smd_half_channel ch1;
276 unsigned char data1[SMD_BUF_SIZE];
277};
278
279/* Used on SMD package v4 */
280struct smd_shared_v2 {
281 struct smd_half_channel ch0;
282 struct smd_half_channel ch1;
283};
284
285struct smd_channel {
286 volatile struct smd_half_channel *send;
287 volatile struct smd_half_channel *recv;
288 unsigned char *send_data;
289 unsigned char *recv_data;
290
291 unsigned fifo_mask;
292 unsigned fifo_size;
293 unsigned current_packet;
294 unsigned n;
295
296 struct list_head ch_list;
297
298 void *priv;
299 void (*notify)(void *priv, unsigned flags);
300
301 int (*read)(struct smd_channel *ch, void *data, int len);
302 int (*write)(struct smd_channel *ch, const void *data, int len);
303 int (*read_avail)(struct smd_channel *ch);
304 int (*write_avail)(struct smd_channel *ch);
305
306 void (*update_state)(struct smd_channel *ch);
307 unsigned last_state;
308 void (*notify_other_cpu)(void);
309 unsigned type;
310
311 char name[32];
312 struct platform_device pdev;
313};
314
315#define SMD_TYPE_MASK 0x0FF
316#define SMD_TYPE_APPS_MODEM 0x000
317#define SMD_TYPE_APPS_DSP 0x001
318#define SMD_TYPE_MODEM_DSP 0x002
319
320#define SMD_KIND_MASK 0xF00
321#define SMD_KIND_UNKNOWN 0x000
322#define SMD_KIND_STREAM 0x100
323#define SMD_KIND_PACKET 0x200
324
325extern struct list_head smd_ch_closed_list;
326extern struct list_head smd_ch_list_modem;
327extern struct list_head smd_ch_list_dsp;
328
329extern spinlock_t smd_lock;
330extern spinlock_t smem_lock;
331
332void *smem_find(unsigned id, unsigned size);
333void *smem_item(unsigned id, unsigned *size);
334uint32_t raw_smsm_get_state(enum smsm_state_item item);
335
336extern void msm_init_last_radio_log(struct module *);
337
338#ifdef CONFIG_MSM_SMD_PKG3
339/*
340 * This allocator assumes an SMD Package v3 which only exists on
341 * MSM7x00 SoC's.
342 */
343static inline int _smd_alloc_channel(struct smd_channel *ch)
344{
345 struct smd_shared_v1 *shared1;
346
347 shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
348 if (!shared1) {
349 pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
350 return -1;
351 }
352 ch->send = &shared1->ch0;
353 ch->recv = &shared1->ch1;
354 ch->send_data = shared1->data0;
355 ch->recv_data = shared1->data1;
356 ch->fifo_size = SMD_BUF_SIZE;
357 return 0;
358}
359#else
360/*
361 * This allocator assumes an SMD Package v4, the most common
362 * and the default.
363 */
364static inline int _smd_alloc_channel(struct smd_channel *ch)
365{
366 struct smd_shared_v2 *shared2;
367 void *buffer;
368 unsigned buffer_sz;
369
370 shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2));
371 buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz);
372
373 if (!buffer)
374 return -1;
375
376 /* buffer must be a power-of-two size */
377 if (buffer_sz & (buffer_sz - 1))
378 return -1;
379
380 buffer_sz /= 2;
381 ch->send = &shared2->ch0;
382 ch->recv = &shared2->ch1;
383 ch->send_data = buffer;
384 ch->recv_data = buffer + buffer_sz;
385 ch->fifo_size = buffer_sz;
386 return 0;
387}
388#endif /* CONFIG_MSM_SMD_PKG3 */
389
390#if defined(CONFIG_ARCH_MSM7X30)
391static inline void msm_a2m_int(uint32_t irq)
392{
393 writel(1 << irq, MSM_GCC_BASE + 0x8);
394}
395#else
396static inline void msm_a2m_int(uint32_t irq)
397{
398 writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
399}
400#endif /* CONFIG_ARCH_MSM7X30 */
401
402
403#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 4855b8ca5101..dec5ca622d7d 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -25,7 +25,9 @@
25#include <asm/mach/time.h> 25#include <asm/mach/time.h>
26#include <mach/msm_iomap.h> 26#include <mach/msm_iomap.h>
27 27
28#ifndef MSM_DGT_BASE
28#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10) 29#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
30#endif
29#define MSM_DGT_SHIFT (5) 31#define MSM_DGT_SHIFT (5)
30 32
31#define TIMER_MATCH_VAL 0x0000 33#define TIMER_MATCH_VAL 0x0000
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
index fcb0b9f25684..a9103bc6615f 100644
--- a/arch/arm/mach-msm/vreg.c
+++ b/arch/arm/mach-msm/vreg.c
@@ -1,6 +1,7 @@
1/* arch/arm/mach-msm/vreg.c 1/* arch/arm/mach-msm/vreg.c
2 * 2 *
3 * Copyright (C) 2008 Google, Inc. 3 * Copyright (C) 2008 Google, Inc.
4 * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com> 5 * Author: Brian Swetland <swetland@google.com>
5 * 6 *
6 * This software is licensed under the terms of the GNU General Public 7 * This software is licensed under the terms of the GNU General Public
@@ -18,6 +19,7 @@
18#include <linux/device.h> 19#include <linux/device.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/debugfs.h> 21#include <linux/debugfs.h>
22#include <linux/string.h>
21#include <mach/vreg.h> 23#include <mach/vreg.h>
22 24
23#include "proc_comm.h" 25#include "proc_comm.h"
@@ -25,42 +27,62 @@
25struct vreg { 27struct vreg {
26 const char *name; 28 const char *name;
27 unsigned id; 29 unsigned id;
30 int status;
31 unsigned refcnt;
28}; 32};
29 33
30#define VREG(_name, _id) { .name = _name, .id = _id, } 34#define VREG(_name, _id, _status, _refcnt) \
35 { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
31 36
32static struct vreg vregs[] = { 37static struct vreg vregs[] = {
33 VREG("msma", 0), 38 VREG("msma", 0, 0, 0),
34 VREG("msmp", 1), 39 VREG("msmp", 1, 0, 0),
35 VREG("msme1", 2), 40 VREG("msme1", 2, 0, 0),
36 VREG("msmc1", 3), 41 VREG("msmc1", 3, 0, 0),
37 VREG("msmc2", 4), 42 VREG("msmc2", 4, 0, 0),
38 VREG("gp3", 5), 43 VREG("gp3", 5, 0, 0),
39 VREG("msme2", 6), 44 VREG("msme2", 6, 0, 0),
40 VREG("gp4", 7), 45 VREG("gp4", 7, 0, 0),
41 VREG("gp1", 8), 46 VREG("gp1", 8, 0, 0),
42 VREG("tcxo", 9), 47 VREG("tcxo", 9, 0, 0),
43 VREG("pa", 10), 48 VREG("pa", 10, 0, 0),
44 VREG("rftx", 11), 49 VREG("rftx", 11, 0, 0),
45 VREG("rfrx1", 12), 50 VREG("rfrx1", 12, 0, 0),
46 VREG("rfrx2", 13), 51 VREG("rfrx2", 13, 0, 0),
47 VREG("synt", 14), 52 VREG("synt", 14, 0, 0),
48 VREG("wlan", 15), 53 VREG("wlan", 15, 0, 0),
49 VREG("usb", 16), 54 VREG("usb", 16, 0, 0),
50 VREG("boost", 17), 55 VREG("boost", 17, 0, 0),
51 VREG("mmc", 18), 56 VREG("mmc", 18, 0, 0),
52 VREG("ruim", 19), 57 VREG("ruim", 19, 0, 0),
53 VREG("msmc0", 20), 58 VREG("msmc0", 20, 0, 0),
54 VREG("gp2", 21), 59 VREG("gp2", 21, 0, 0),
55 VREG("gp5", 22), 60 VREG("gp5", 22, 0, 0),
56 VREG("gp6", 23), 61 VREG("gp6", 23, 0, 0),
57 VREG("rf", 24), 62 VREG("rf", 24, 0, 0),
58 VREG("rf_vco", 26), 63 VREG("rf_vco", 26, 0, 0),
59 VREG("mpll", 27), 64 VREG("mpll", 27, 0, 0),
60 VREG("s2", 28), 65 VREG("s2", 28, 0, 0),
61 VREG("s3", 29), 66 VREG("s3", 29, 0, 0),
62 VREG("rfubm", 30), 67 VREG("rfubm", 30, 0, 0),
63 VREG("ncp", 31), 68 VREG("ncp", 31, 0, 0),
69 VREG("gp7", 32, 0, 0),
70 VREG("gp8", 33, 0, 0),
71 VREG("gp9", 34, 0, 0),
72 VREG("gp10", 35, 0, 0),
73 VREG("gp11", 36, 0, 0),
74 VREG("gp12", 37, 0, 0),
75 VREG("gp13", 38, 0, 0),
76 VREG("gp14", 39, 0, 0),
77 VREG("gp15", 40, 0, 0),
78 VREG("gp16", 41, 0, 0),
79 VREG("gp17", 42, 0, 0),
80 VREG("s4", 43, 0, 0),
81 VREG("usb2", 44, 0, 0),
82 VREG("wlan2", 45, 0, 0),
83 VREG("xo_out", 46, 0, 0),
84 VREG("lvsw0", 47, 0, 0),
85 VREG("lvsw1", 48, 0, 0),
64}; 86};
65 87
66struct vreg *vreg_get(struct device *dev, const char *id) 88struct vreg *vreg_get(struct device *dev, const char *id)
@@ -70,7 +92,7 @@ struct vreg *vreg_get(struct device *dev, const char *id)
70 if (!strcmp(vregs[n].name, id)) 92 if (!strcmp(vregs[n].name, id))
71 return vregs + n; 93 return vregs + n;
72 } 94 }
73 return 0; 95 return ERR_PTR(-ENOENT);
74} 96}
75 97
76void vreg_put(struct vreg *vreg) 98void vreg_put(struct vreg *vreg)
@@ -81,20 +103,39 @@ int vreg_enable(struct vreg *vreg)
81{ 103{
82 unsigned id = vreg->id; 104 unsigned id = vreg->id;
83 unsigned enable = 1; 105 unsigned enable = 1;
84 return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); 106
107 if (vreg->refcnt == 0)
108 vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
109
110 if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
111 vreg->refcnt++;
112
113 return vreg->status;
85} 114}
86 115
87void vreg_disable(struct vreg *vreg) 116int vreg_disable(struct vreg *vreg)
88{ 117{
89 unsigned id = vreg->id; 118 unsigned id = vreg->id;
90 unsigned enable = 0; 119 unsigned enable = 0;
91 msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); 120
121 if (!vreg->refcnt)
122 return 0;
123
124 if (vreg->refcnt == 1)
125 vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
126
127 if (!vreg->status)
128 vreg->refcnt--;
129
130 return vreg->status;
92} 131}
93 132
94int vreg_set_level(struct vreg *vreg, unsigned mv) 133int vreg_set_level(struct vreg *vreg, unsigned mv)
95{ 134{
96 unsigned id = vreg->id; 135 unsigned id = vreg->id;
97 return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); 136
137 vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
138 return vreg->status;
98} 139}
99 140
100#if defined(CONFIG_DEBUG_FS) 141#if defined(CONFIG_DEBUG_FS)
@@ -118,24 +159,59 @@ static int vreg_debug_set(void *data, u64 val)
118 159
119static int vreg_debug_get(void *data, u64 *val) 160static int vreg_debug_get(void *data, u64 *val)
120{ 161{
121 return -ENOSYS; 162 struct vreg *vreg = data;
163
164 if (!vreg->status)
165 *val = 0;
166 else
167 *val = 1;
168
169 return 0;
170}
171
172static int vreg_debug_count_set(void *data, u64 val)
173{
174 struct vreg *vreg = data;
175 if (val > UINT_MAX)
176 val = UINT_MAX;
177 vreg->refcnt = val;
178 return 0;
179}
180
181static int vreg_debug_count_get(void *data, u64 *val)
182{
183 struct vreg *vreg = data;
184
185 *val = vreg->refcnt;
186
187 return 0;
122} 188}
123 189
124DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n"); 190DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
191DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
192 vreg_debug_count_set, "%llu\n");
125 193
126static int __init vreg_debug_init(void) 194static int __init vreg_debug_init(void)
127{ 195{
128 struct dentry *dent; 196 struct dentry *dent;
129 int n; 197 int n;
198 char name[32];
199 const char *refcnt_name = "_refcnt";
130 200
131 dent = debugfs_create_dir("vreg", 0); 201 dent = debugfs_create_dir("vreg", 0);
132 if (IS_ERR(dent)) 202 if (IS_ERR(dent))
133 return 0; 203 return 0;
134 204
135 for (n = 0; n < ARRAY_SIZE(vregs); n++) 205 for (n = 0; n < ARRAY_SIZE(vregs); n++) {
136 (void) debugfs_create_file(vregs[n].name, 0644, 206 (void) debugfs_create_file(vregs[n].name, 0644,
137 dent, vregs + n, &vreg_fops); 207 dent, vregs + n, &vreg_fops);
138 208
209 strlcpy(name, vregs[n].name, sizeof(name));
210 strlcat(name, refcnt_name, sizeof(name));
211 (void) debugfs_create_file(name, 0644,
212 dent, vregs + n, &vreg_count_fops);
213 }
214
139 return 0; 215 return 0;
140} 216}
141 217