1 /*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <boot/boot.h>
30 #include <msm7k/shared.h>
31
get_version(char * s,unsigned id)32 static void get_version(char *s, unsigned id)
33 {
34 unsigned *ver = (unsigned*) MSM7K_VERSION;
35 unsigned n = ver[id];
36
37 snprintf(s, 32, "%d.%d", n >> 16, n & 0xffff);
38 }
39
get_version_modem(char * s)40 void get_version_modem(char *s)
41 {
42 get_version(s, VERSION_MODEM);
43 }
44
get_version_modem_sbl(char * s)45 void get_version_modem_sbl(char *s)
46 {
47 get_version(s, VERSION_MODEM_SBL);
48 }
49
50 #define MSM_CSR_BASE 0xC0100000
51
52 #define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
53
notify_other_proc_comm(void)54 static inline void notify_other_proc_comm(void)
55 {
56 writel(1, MSM_A2M_INT(6));
57 }
58
59 #define APP_COMMAND (MSM7K_SHARED_PHYS + 0x00)
60 #define APP_STATUS (MSM7K_SHARED_PHYS + 0x04)
61 #define APP_DATA1 (MSM7K_SHARED_PHYS + 0x08)
62 #define APP_DATA2 (MSM7K_SHARED_PHYS + 0x0C)
63
64 #define MDM_COMMAND (MSM7K_SHARED_PHYS + 0x10)
65 #define MDM_STATUS (MSM7K_SHARED_PHYS + 0x14)
66 #define MDM_DATA1 (MSM7K_SHARED_PHYS + 0x18)
67 #define MDM_DATA2 (MSM7K_SHARED_PHYS + 0x1C)
68
69
70 enum
71 {
72 PCOM_CMD_IDLE = 0x0,
73 PCOM_CMD_DONE,
74 PCOM_RESET_APPS,
75 PCOM_RESET_CHIP,
76 PCOM_CONFIG_NAND_MPU,
77 PCOM_CONFIG_USB_CLKS,
78 PCOM_GET_POWER_ON_STATUS,
79 PCOM_GET_WAKE_UP_STATUS,
80 PCOM_GET_BATT_LEVEL,
81 PCOM_CHG_IS_CHARGING,
82 PCOM_POWER_DOWN,
83 PCOM_USB_PIN_CONFIG,
84 PCOM_USB_PIN_SEL,
85 PCOM_SET_RTC_ALARM,
86 PCOM_NV_READ,
87 PCOM_NV_WRITE,
88 PCOM_GET_UUID_HIGH,
89 PCOM_GET_UUID_LOW,
90 PCOM_GET_HW_ENTROPY,
91 PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
92 PCOM_CLKCTL_RPC_ENABLE,
93 PCOM_CLKCTL_RPC_DISABLE,
94 PCOM_CLKCTL_RPC_RESET,
95 PCOM_CLKCTL_RPC_SET_FLAGS,
96 PCOM_CLKCTL_RPC_SET_RATE,
97 PCOM_CLKCTL_RPC_MIN_RATE,
98 PCOM_CLKCTL_RPC_MAX_RATE,
99 PCOM_CLKCTL_RPC_RATE,
100 PCOM_CLKCTL_RPC_PLL_REQUEST,
101 PCOM_CLKCTL_RPC_ENABLED,
102 PCOM_VREG_SWITCH,
103 PCOM_VREG_SET_LEVEL,
104 PCOM_GPIO_TLMM_CONFIG_GROUP,
105 PCOM_GPIO_TLMM_UNCONFIG_GROUP,
106 PCOM_NV_READ_HIGH_BITS,
107 PCOM_NV_WRITE_HIGH_BITS,
108 PCOM_NUM_CMDS,
109 };
110
111 enum
112 {
113 PCOM_INVALID_STATUS = 0x0,
114 PCOM_READY,
115 PCOM_CMD_RUNNING,
116 PCOM_CMD_SUCCESS,
117 PCOM_CMD_FAIL,
118 };
119
msm_proc_comm(unsigned cmd,unsigned * data1,unsigned * data2)120 int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
121 {
122 int ret = -1;
123
124 while (readl(MDM_STATUS) != PCOM_READY) {
125 /* XXX check for A9 reset */
126 }
127
128 writel(cmd, APP_COMMAND);
129 if (data1)
130 writel(*data1, APP_DATA1);
131 if (data2)
132 writel(*data2, APP_DATA2);
133
134 notify_other_proc_comm();
135 while (readl(APP_COMMAND) != PCOM_CMD_DONE) {
136 /* XXX check for A9 reset */
137 }
138
139 if (readl(APP_STATUS) != PCOM_CMD_FAIL) {
140 if (data1)
141 *data1 = readl(APP_DATA1);
142 if (data2)
143 *data2 = readl(APP_DATA2);
144 ret = 0;
145 }
146
147 return ret;
148 }
149
clock_enable(unsigned id)150 int clock_enable(unsigned id)
151 {
152 return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0);
153 }
154
clock_disable(unsigned id)155 int clock_disable(unsigned id)
156 {
157 return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0);
158 }
159
clock_set_rate(unsigned id,unsigned rate)160 int clock_set_rate(unsigned id, unsigned rate)
161 {
162 return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
163 }
164
clock_get_rate(unsigned id)165 int clock_get_rate(unsigned id)
166 {
167 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0)) {
168 return -1;
169 } else {
170 return (int) id;
171 }
172 }
173
reboot(void)174 void reboot(void)
175 {
176 msm_proc_comm(PCOM_RESET_CHIP, 0, 0);
177 for (;;) ;
178 }
179
vreg_enable(unsigned id)180 int vreg_enable(unsigned id)
181 {
182 unsigned n = 1;
183 return msm_proc_comm(PCOM_VREG_SWITCH, &id, &n);
184 }
185
vreg_disable(unsigned id)186 int vreg_disable(unsigned id)
187 {
188 unsigned n = 0;
189 return msm_proc_comm(PCOM_VREG_SWITCH, &id, &n);
190 }
191
vreg_set_level(unsigned id,unsigned level)192 int vreg_set_level(unsigned id, unsigned level)
193 {
194 return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &level);
195 }
196
197
198