blob: 0c32acc8a1f2031150d3311f1a403947a8ce9bb1 [file] [log] [blame]
Shashank Mittal23b8f422010-04-16 19:27:21 -07001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
Ajay Dudanid04110c2011-01-17 23:55:07 -08004 * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
Shashank Mittal23b8f422010-04-16 19:27:21 -07005 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google, Inc. nor the names of its contributors
16 * may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <debug.h>
34#include <dev/keys.h>
35#include <dev/gpio_keypad.h>
36#include <lib/ptable.h>
37#include <dev/flash.h>
38#include <smem.h>
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070039#include <platform/iomap.h>
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -080040#include <platform/gpio_hw.h>
Ajay Dudanid04110c2011-01-17 23:55:07 -080041#include <baseband.h>
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070042#include <reg.h>
Shashank Mittal23b8f422010-04-16 19:27:21 -070043
Shashank Mittal86b21482010-11-15 10:37:34 -080044#define LINUX_MACHTYPE_8660_SURF 2755
45#define LINUX_MACHTYPE_8660_FFA 3017
46#define LINUX_MACHTYPE_8660_FLUID 3124
Ajay Dudani8b3262a2011-01-17 13:55:30 -080047#define LINUX_MACHTYPE_8660_QT 3298
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080048#define LINUX_MACHTYPE_8660_CHARM_SURF 3181
49#define LINUX_MACHTYPE_8660_CHARM_FFA 3199
Shashank Mittal23b8f422010-04-16 19:27:21 -070050
51void keypad_init(void);
52
53static int emmc_boot = -1; /* set to uninitialized */
54int target_is_emmc_boot(void);
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070055void debug_led_write(char);
56char debug_led_read();
Shashank Mittalc69512e2010-09-22 16:40:48 -070057uint32_t platform_id_read (void);
Shashank Mittal23b8f422010-04-16 19:27:21 -070058
59void target_init(void)
60{
61
62 dprintf(INFO, "target_init()\n");
63
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070064 setup_fpga();
Subbaraman Narayanamurthy50d936f2010-09-08 17:09:00 -070065
66 /* Setting Debug LEDs ON */
67 debug_led_write(0xFF);
Chandan Uddarajubedca152010-06-02 23:05:15 -070068#if (!ENABLE_NANDWRITE)
69 keys_init();
70 keypad_init();
71#endif
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070072 if(mmc_boot_main(MMC_SLOT,MSM_SDC1_BASE))
Shashank Mittal23b8f422010-04-16 19:27:21 -070073 {
74 dprintf(CRITICAL, "mmc init failed!");
75 ASSERT(0);
76 }
77}
78
79unsigned board_machtype(void)
80{
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080081 struct smem_board_info_v5 board_info_v5;
Shashank Mittal2249a072011-02-14 19:24:17 -080082 struct smem_board_info_v6 board_info_v6;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080083 unsigned int board_info_len = 0;
84 unsigned smem_status = 0;
85 unsigned format = 0;
86 unsigned id = 0;
87 unsigned hw_platform = 0;
88 unsigned fused_chip = 0;
Ajay Dudani295f38b2011-02-25 15:28:07 -080089 unsigned platform_subtype = 0;
Subbaraman Narayanamurthy8f0b0452011-03-11 18:30:10 -080090 static unsigned mach_id = -1;
Shashank Mittalc69512e2010-09-22 16:40:48 -070091
Subbaraman Narayanamurthy8f0b0452011-03-11 18:30:10 -080092 if(mach_id != -1)
93 return mach_id;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080094 /* Detect external msm if this is a "fusion" */
95 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
96 &format, sizeof(format), 0);
97 if(!smem_status)
98 {
Shashank Mittal2249a072011-02-14 19:24:17 -080099 if (format == 5)
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800100 {
101 board_info_len = sizeof(board_info_v5);
102
103 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
104 &board_info_v5, board_info_len);
105 if(!smem_status)
106 {
107 fused_chip = board_info_v5.fused_chip;
Shashank Mittal2249a072011-02-14 19:24:17 -0800108 id = board_info_v5.board_info_v3.hw_platform;
109 }
110 }
111 else if (format == 6)
112 {
113 board_info_len = sizeof(board_info_v6);
114
115 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
116 &board_info_v6, board_info_len);
117 if(!smem_status)
118 {
119 fused_chip = board_info_v6.fused_chip;
120 id = board_info_v6.board_info_v3.hw_platform;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800121 platform_subtype = board_info_v6.platform_subtype;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800122 }
123 }
124 }
125
126 /* Detect SURF v/s FFA v/s Fluid */
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800127 switch(id)
128 {
129 case 0x1:
130 hw_platform = HW_PLATFORM_SURF;
131 break;
132 case 0x2:
133 hw_platform = HW_PLATFORM_FFA;
134 break;
135 case 0x3:
136 hw_platform = HW_PLATFORM_FLUID;
137 break;
Ajay Dudani8b3262a2011-01-17 13:55:30 -0800138 case 0x6:
139 hw_platform = HW_PLATFORM_QT;
140 break;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800141 default:
142 /* Writing to Debug LED register and reading back to auto detect
143 SURF and FFA. If we read back, it is SURF */
144 debug_led_write(0xA5);
145
146 if((debug_led_read() & 0xFF) == 0xA5)
147 {
148 debug_led_write(0);
149 hw_platform = HW_PLATFORM_SURF;
150 }
151 else
152 hw_platform = HW_PLATFORM_FFA;
153 };
154
Ajay Dudani295f38b2011-02-25 15:28:07 -0800155 /* Use platform_subtype or fused_chip information to determine machine id */
156 if (format >= 6)
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800157 {
Ajay Dudani295f38b2011-02-25 15:28:07 -0800158 switch(platform_subtype)
159 {
160 case HW_PLATFORM_SUBTYPE_CSFB:
161 case HW_PLATFORM_SUBTYPE_SVLTE2A:
162 if (hw_platform == HW_PLATFORM_SURF)
163 mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
164 else if (hw_platform == HW_PLATFORM_FFA)
165 mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
166 break;
167 default:
168 if (hw_platform == HW_PLATFORM_SURF)
169 mach_id = LINUX_MACHTYPE_8660_SURF;
170 else if (hw_platform == HW_PLATFORM_FFA)
171 mach_id = LINUX_MACHTYPE_8660_FFA;
172 else if (hw_platform == HW_PLATFORM_FLUID)
173 mach_id = LINUX_MACHTYPE_8660_FLUID;
174 else if (hw_platform == HW_PLATFORM_QT)
175 mach_id = LINUX_MACHTYPE_8660_QT;
176 }
177 }
178 else if (format == 5)
179 {
180 switch(fused_chip)
181 {
182 case UNKNOWN:
183 if (hw_platform == HW_PLATFORM_SURF)
184 mach_id = LINUX_MACHTYPE_8660_SURF;
185 else if (hw_platform == HW_PLATFORM_FFA)
186 mach_id = LINUX_MACHTYPE_8660_FFA;
187 else if (hw_platform == HW_PLATFORM_FLUID)
188 mach_id = LINUX_MACHTYPE_8660_FLUID;
189 else if (hw_platform == HW_PLATFORM_QT)
190 mach_id = LINUX_MACHTYPE_8660_QT;
191 break;
192
193 case MDM9200:
194 case MDM9600:
195 if (hw_platform == HW_PLATFORM_SURF)
196 mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
197 else if (hw_platform == HW_PLATFORM_FFA)
198 mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
199 break;
200
201 default:
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800202 mach_id = LINUX_MACHTYPE_8660_FFA;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800203 }
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800204 }
205
206 return mach_id;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700207}
208
209void reboot_device(unsigned reboot_reason)
210{
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700211 /* Reset WDG0 counter */
212 writel(1,MSM_WDT0_RST);
213 /* Disable WDG0 */
214 writel(0,MSM_WDT0_EN);
215 /* Set WDG0 bark time */
216 writel(0x31F3,MSM_WDT0_BT);
217 /* Enable WDG0 */
218 writel(3,MSM_WDT0_EN);
219 dmb();
220 /* Enable WDG output */
Subbaraman Narayanamurthy346bdcb2011-02-24 12:02:58 -0800221 secure_writel(3,MSM_TCSR_BASE + TCSR_WDOG_CFG);
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700222 mdelay(10000);
223 dprintf (CRITICAL, "Rebooting failed\n");
Shashank Mittal23b8f422010-04-16 19:27:21 -0700224 return;
225}
226
227unsigned check_reboot_mode(void)
228{
Ajay Dudani77421292010-10-27 19:34:06 -0700229 unsigned restart_reason = 0;
Ajay Dudani9496f9a2011-02-17 10:45:39 -0800230 void *restart_reason_addr = 0x2A05F65C;
Ajay Dudani77421292010-10-27 19:34:06 -0700231
232 /* Read reboot reason and scrub it */
233 restart_reason = readl(restart_reason_addr);
234 writel(0x00, restart_reason_addr);
235
236 return restart_reason;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700237}
238
239void target_battery_charging_enable(unsigned enable, unsigned disconnect)
240{
241}
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -0700242
243void setup_fpga()
244{
245 writel(0x147, GPIO_CFG133_ADDR);
246 writel(0x144, GPIO_CFG135_ADDR);
247 writel(0x144, GPIO_CFG136_ADDR);
248 writel(0x144, GPIO_CFG137_ADDR);
249 writel(0x144, GPIO_CFG138_ADDR);
250 writel(0x144, GPIO_CFG139_ADDR);
251 writel(0x144, GPIO_CFG140_ADDR);
252 writel(0x144, GPIO_CFG141_ADDR);
253 writel(0x144, GPIO_CFG142_ADDR);
254 writel(0x144, GPIO_CFG143_ADDR);
255 writel(0x144, GPIO_CFG144_ADDR);
256 writel(0x144, GPIO_CFG145_ADDR);
257 writel(0x144, GPIO_CFG146_ADDR);
258 writel(0x144, GPIO_CFG147_ADDR);
259 writel(0x144, GPIO_CFG148_ADDR);
260 writel(0x144, GPIO_CFG149_ADDR);
261 writel(0x144, GPIO_CFG150_ADDR);
262 writel(0x147, GPIO_CFG151_ADDR);
263 writel(0x147, GPIO_CFG152_ADDR);
264 writel(0x147, GPIO_CFG153_ADDR);
265 writel(0x3, GPIO_CFG154_ADDR);
266 writel(0x147, GPIO_CFG155_ADDR);
267 writel(0x147, GPIO_CFG156_ADDR);
268 writel(0x147, GPIO_CFG157_ADDR);
269 writel(0x3, GPIO_CFG158_ADDR);
270
271 writel(0x00000B31, EBI2_CHIP_SELECT_CFG0);
272 writel(0xA3030020, EBI2_XMEM_CS3_CFG1);
273}
274
275void debug_led_write(char val)
276{
277 writeb(val,SURF_DEBUG_LED_ADDR);
278}
279
280char debug_led_read()
281{
282 return readb(SURF_DEBUG_LED_ADDR);
283}
Ajay Dudanid04110c2011-01-17 23:55:07 -0800284
285unsigned target_baseband()
286{
287 struct smem_board_info_v5 board_info_v5;
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800288 struct smem_board_info_v6 board_info_v6;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800289 unsigned int board_info_len = 0;
290 unsigned smem_status = 0;
291 unsigned format = 0;
292 unsigned baseband = BASEBAND_MSM;
293
294 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
295 &format, sizeof(format), 0);
296 if(!smem_status)
297 {
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800298 if (format == 5)
Ajay Dudanid04110c2011-01-17 23:55:07 -0800299 {
300 board_info_len = sizeof(board_info_v5);
301
302 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
303 &board_info_v5, board_info_len);
304 if(!smem_status)
305 {
306 /* Check for LTE fused targets or APQ. Default to MSM */
307 if (board_info_v5.fused_chip == MDM9200)
308 baseband = BASEBAND_CSFB;
309 else if (board_info_v5.fused_chip == MDM9600)
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800310 baseband = BASEBAND_SVLTE2A;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800311 else if (board_info_v5.board_info_v3.msm_id == APQ8060)
312 baseband = BASEBAND_APQ;
313 else
314 baseband = BASEBAND_MSM;
315 }
316 }
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800317 else if (format >= 6)
318 {
319 board_info_len = sizeof(board_info_v6);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800320
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800321 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
322 &board_info_v6, board_info_len);
323 if(!smem_status)
324 {
325 /* Check for LTE fused targets or APQ. Default to MSM */
326 if (board_info_v6.platform_subtype == HW_PLATFORM_SUBTYPE_CSFB)
327 baseband = BASEBAND_CSFB;
328 else if (board_info_v6.platform_subtype == HW_PLATFORM_SUBTYPE_SVLTE2A)
329 baseband = BASEBAND_SVLTE2A;
330 else if (board_info_v6.board_info_v3.msm_id == APQ8060)
331 baseband = BASEBAND_APQ;
332 else
333 baseband = BASEBAND_MSM;
334 }
335 }
336 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800337 return baseband;
338}
Ajay Dudani59606432011-01-24 18:23:38 -0800339
340static unsigned target_check_power_on_reason(void)
341{
342 unsigned power_on_status = 0;
343 unsigned int status_len = sizeof(power_on_status);
344 unsigned smem_status;
345
346 smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,
347 &power_on_status, status_len);
348
Subbaraman Narayanamurthybd2424e2011-03-29 15:29:21 -0700349 if (smem_status)
Ajay Dudani59606432011-01-24 18:23:38 -0800350 {
351 dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n");
352 }
353
354 return power_on_status;
355}
356
357unsigned target_pause_for_battery_charge(void)
358{
359 if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG)
360 return 1;
361
362 return 0;
363}
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -0800364
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800365void target_serialno(unsigned char *buf)
366{
367 unsigned int serialno;
368 if(target_is_emmc_boot())
369 {
370 serialno = mmc_get_psn();
371 sprintf(buf,"%x",serialno);
372 }
373}
374
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -0800375void hsusb_gpio_init(void)
376{
377 uint32_t func;
378 uint32_t pull;
379 uint32_t dir;
380 uint32_t enable;
381 uint32_t drv;
382
383 /* GPIO 131 and 132 need to be configured for connecting to USB HS PHY */
384
385 func = 0;
386 enable = 1;
387 pull = GPIO_NO_PULL;
388 dir = 2;
389 drv = GPIO_2MA;
390 gpio_tlmm_config(131, func, dir, pull, drv, enable);
391 gpio_set(131, dir);
392
393 func = 0;
394 enable = 1;
395 pull = GPIO_NO_PULL;
396 dir = 1;
397 drv = GPIO_2MA;
398 gpio_tlmm_config(132, func, dir, pull, drv, enable);
399 gpio_set(132, dir);
400
401 return;
402}