aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2008-09-09 12:36:50 -0400
committerBrian Swetland <swetland@google.com>2008-10-22 05:39:32 -0400
commitb8a16e1fdfe9caed734df0e157ad74ae2b13e3bd (patch)
treebce53911b0eb587d067dcbda6ea47b9cc0b0536f /arch/arm
parent1637de0c9b4dbac0f185e94b2b8cd2c2db78700d (diff)
[ARM] msm: add proc_comm support, necessary for clock and power control
The proc_comm protocol is the lowest level protocol available for communicating with the modem core. It provides access to clock and power control, among other things, and is safe for use from atomic contexts, unlike the higher level SMD and RPC transports. Signed-off-by: Brian Swetland <swetland@google.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-msm/Makefile1
-rw-r--r--arch/arm/mach-msm/proc_comm.c110
-rw-r--r--arch/arm/mach-msm/proc_comm.h165
3 files changed, 276 insertions, 0 deletions
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index d12f23655850..ae96ffff494d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,4 +1,5 @@
1obj-y += io.o idle.o irq.o timer.o dma.o 1obj-y += io.o idle.o irq.o timer.o dma.o
2obj-y += proc_comm.o
2 3
3# Common code for board init 4# Common code for board init
4obj-y += common.o 5obj-y += common.o
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
new file mode 100644
index 000000000000..915ee704ed3c
--- /dev/null
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -0,0 +1,110 @@
1/* arch/arm/mach-msm/proc_comm.c
2 *
3 * Copyright (C) 2007-2008 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/delay.h>
18#include <linux/errno.h>
19#include <linux/io.h>
20#include <linux/spinlock.h>
21#include <mach/msm_iomap.h>
22#include <mach/system.h>
23
24#include "proc_comm.h"
25
26#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
27
28static inline void notify_other_proc_comm(void)
29{
30 writel(1, MSM_A2M_INT(6));
31}
32
33#define APP_COMMAND 0x00
34#define APP_STATUS 0x04
35#define APP_DATA1 0x08
36#define APP_DATA2 0x0C
37
38#define MDM_COMMAND 0x10
39#define MDM_STATUS 0x14
40#define MDM_DATA1 0x18
41#define MDM_DATA2 0x1C
42
43static DEFINE_SPINLOCK(proc_comm_lock);
44
45/* The higher level SMD support will install this to
46 * provide a way to check for and handle modem restart.
47 */
48int (*msm_check_for_modem_crash)(void);
49
50/* Poll for a state change, checking for possible
51 * modem crashes along the way (so we don't wait
52 * forever while the ARM9 is blowing up).
53 *
54 * Return an error in the event of a modem crash and
55 * restart so the msm_proc_comm() routine can restart
56 * the operation from the beginning.
57 */
58static int proc_comm_wait_for(void __iomem *addr, unsigned value)
59{
60 for (;;) {
61 if (readl(addr) == value)
62 return 0;
63
64 if (msm_check_for_modem_crash)
65 if (msm_check_for_modem_crash())
66 return -EAGAIN;
67 }
68}
69
70int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
71{
72 void __iomem *base = MSM_SHARED_RAM_BASE;
73 unsigned long flags;
74 int ret;
75
76 spin_lock_irqsave(&proc_comm_lock, flags);
77
78 for (;;) {
79 if (proc_comm_wait_for(base + MDM_STATUS, PCOM_READY))
80 continue;
81
82 writel(cmd, base + APP_COMMAND);
83 writel(data1 ? *data1 : 0, base + APP_DATA1);
84 writel(data2 ? *data2 : 0, base + APP_DATA2);
85
86 notify_other_proc_comm();
87
88 if (proc_comm_wait_for(base + APP_COMMAND, PCOM_CMD_DONE))
89 continue;
90
91 if (readl(base + APP_STATUS) != PCOM_CMD_FAIL) {
92 if (data1)
93 *data1 = readl(base + APP_DATA1);
94 if (data2)
95 *data2 = readl(base + APP_DATA2);
96 ret = 0;
97 } else {
98 ret = -EIO;
99 }
100 break;
101 }
102
103 writel(PCOM_CMD_IDLE, base + APP_COMMAND);
104
105 spin_unlock_irqrestore(&proc_comm_lock, flags);
106
107 return ret;
108}
109
110
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h
new file mode 100644
index 000000000000..834760f25692
--- /dev/null
+++ b/arch/arm/mach-msm/proc_comm.h
@@ -0,0 +1,165 @@
1/* arch/arm/mach-msm/proc_comm.h
2 *
3 * Copyright (c) 2007 QUALCOMM Incorporated
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#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
17#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
18
19enum {
20 PCOM_CMD_IDLE = 0x0,
21 PCOM_CMD_DONE,
22 PCOM_RESET_APPS,
23 PCOM_RESET_CHIP,
24 PCOM_CONFIG_NAND_MPU,
25 PCOM_CONFIG_USB_CLKS,
26 PCOM_GET_POWER_ON_STATUS,
27 PCOM_GET_WAKE_UP_STATUS,
28 PCOM_GET_BATT_LEVEL,
29 PCOM_CHG_IS_CHARGING,
30 PCOM_POWER_DOWN,
31 PCOM_USB_PIN_CONFIG,
32 PCOM_USB_PIN_SEL,
33 PCOM_SET_RTC_ALARM,
34 PCOM_NV_READ,
35 PCOM_NV_WRITE,
36 PCOM_GET_UUID_HIGH,
37 PCOM_GET_UUID_LOW,
38 PCOM_GET_HW_ENTROPY,
39 PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
40 PCOM_CLKCTL_RPC_ENABLE,
41 PCOM_CLKCTL_RPC_DISABLE,
42 PCOM_CLKCTL_RPC_RESET,
43 PCOM_CLKCTL_RPC_SET_FLAGS,
44 PCOM_CLKCTL_RPC_SET_RATE,
45 PCOM_CLKCTL_RPC_MIN_RATE,
46 PCOM_CLKCTL_RPC_MAX_RATE,
47 PCOM_CLKCTL_RPC_RATE,
48 PCOM_CLKCTL_RPC_PLL_REQUEST,
49 PCOM_CLKCTL_RPC_ENABLED,
50 PCOM_VREG_SWITCH,
51 PCOM_VREG_SET_LEVEL,
52 PCOM_GPIO_TLMM_CONFIG_GROUP,
53 PCOM_GPIO_TLMM_UNCONFIG_GROUP,
54 PCOM_NV_WRITE_BYTES_4_7,
55 PCOM_CONFIG_DISP,
56 PCOM_GET_FTM_BOOT_COUNT,
57 PCOM_RPC_GPIO_TLMM_CONFIG_EX,
58 PCOM_PM_MPP_CONFIG,
59 PCOM_GPIO_IN,
60 PCOM_GPIO_OUT,
61 PCOM_RESET_MODEM,
62 PCOM_RESET_CHIP_IMM,
63 PCOM_PM_VID_EN,
64 PCOM_VREG_PULLDOWN,
65 PCOM_NUM_CMDS,
66};
67
68enum {
69 PCOM_INVALID_STATUS = 0x0,
70 PCOM_READY,
71 PCOM_CMD_RUNNING,
72 PCOM_CMD_SUCCESS,
73 PCOM_CMD_FAIL,
74};
75
76/* List of VREGs that support the Pull Down Resistor setting. */
77enum {
78 PM_VREG_PDOWN_MSMA_ID,
79 PM_VREG_PDOWN_MSMP_ID,
80 PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
81 PM_VREG_PDOWN_MSMC1_ID, /* Not supported in PM6620 */
82 PM_VREG_PDOWN_MSMC2_ID, /* Supported in PM7500 only */
83 PM_VREG_PDOWN_GP3_ID, /* Supported in PM7500 only */
84 PM_VREG_PDOWN_MSME2_ID, /* Supported in PM7500 and Panoramix only */
85 PM_VREG_PDOWN_GP4_ID, /* Supported in PM7500 only */
86 PM_VREG_PDOWN_GP1_ID, /* Supported in PM7500 only */
87 PM_VREG_PDOWN_TCXO_ID,
88 PM_VREG_PDOWN_PA_ID,
89 PM_VREG_PDOWN_RFTX_ID,
90 PM_VREG_PDOWN_RFRX1_ID,
91 PM_VREG_PDOWN_RFRX2_ID,
92 PM_VREG_PDOWN_SYNT_ID,
93 PM_VREG_PDOWN_WLAN_ID,
94 PM_VREG_PDOWN_USB_ID,
95 PM_VREG_PDOWN_MMC_ID,
96 PM_VREG_PDOWN_RUIM_ID,
97 PM_VREG_PDOWN_MSMC0_ID, /* Supported in PM6610 only */
98 PM_VREG_PDOWN_GP2_ID, /* Supported in PM7500 only */
99 PM_VREG_PDOWN_GP5_ID, /* Supported in PM7500 only */
100 PM_VREG_PDOWN_GP6_ID, /* Supported in PM7500 only */
101 PM_VREG_PDOWN_RF_ID,
102 PM_VREG_PDOWN_RF_VCO_ID,
103 PM_VREG_PDOWN_MPLL_ID,
104 PM_VREG_PDOWN_S2_ID,
105 PM_VREG_PDOWN_S3_ID,
106 PM_VREG_PDOWN_RFUBM_ID,
107
108 /* new for HAN */
109 PM_VREG_PDOWN_RF1_ID,
110 PM_VREG_PDOWN_RF2_ID,
111 PM_VREG_PDOWN_RFA_ID,
112 PM_VREG_PDOWN_CDC2_ID,
113 PM_VREG_PDOWN_RFTX2_ID,
114 PM_VREG_PDOWN_USIM_ID,
115 PM_VREG_PDOWN_USB2P6_ID,
116 PM_VREG_PDOWN_USB3P3_ID,
117 PM_VREG_PDOWN_INVALID_ID,
118
119 /* backward compatible enums only */
120 PM_VREG_PDOWN_CAM_ID = PM_VREG_PDOWN_GP1_ID,
121 PM_VREG_PDOWN_MDDI_ID = PM_VREG_PDOWN_GP2_ID,
122 PM_VREG_PDOWN_RUIM2_ID = PM_VREG_PDOWN_GP3_ID,
123 PM_VREG_PDOWN_AUX_ID = PM_VREG_PDOWN_GP4_ID,
124 PM_VREG_PDOWN_AUX2_ID = PM_VREG_PDOWN_GP5_ID,
125 PM_VREG_PDOWN_BT_ID = PM_VREG_PDOWN_GP6_ID,
126
127 PM_VREG_PDOWN_MSME_ID = PM_VREG_PDOWN_MSME1_ID,
128 PM_VREG_PDOWN_MSMC_ID = PM_VREG_PDOWN_MSMC1_ID,
129 PM_VREG_PDOWN_RFA1_ID = PM_VREG_PDOWN_RFRX2_ID,
130 PM_VREG_PDOWN_RFA2_ID = PM_VREG_PDOWN_RFTX2_ID,
131 PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
132};
133
134/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
135
136#define GPIO_ENABLE 0
137#define GPIO_DISABLE 1
138
139#define GPIO_INPUT 0
140#define GPIO_OUTPUT 1
141
142#define GPIO_NO_PULL 0
143#define GPIO_PULL_DOWN 1
144#define GPIO_KEEPER 2
145#define GPIO_PULL_UP 3
146
147#define GPIO_2MA 0
148#define GPIO_4MA 1
149#define GPIO_6MA 2
150#define GPIO_8MA 3
151#define GPIO_10MA 4
152#define GPIO_12MA 5
153#define GPIO_14MA 6
154#define GPIO_16MA 7
155
156#define PCOM_GPIO_CFG(gpio, func, dir, pull, drvstr) \
157 ((((gpio) & 0x3FF) << 4) | \
158 ((func) & 0xf) | \
159 (((dir) & 0x1) << 14) | \
160 (((pull) & 0x3) << 15) | \
161 (((drvstr) & 0xF) << 17))
162
163int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
164
165#endif