blob: 217e5c937c53cbccc42ade1bb480f3b6c2005c30 [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>
Greg Griscod2471ef2011-07-14 13:00:42 -070036#include <dev/gpio.h>
Shashank Mittal23b8f422010-04-16 19:27:21 -070037#include <lib/ptable.h>
38#include <dev/flash.h>
39#include <smem.h>
Greg Griscod6250552011-06-29 14:40:23 -070040#include <mmc.h>
41#include <platform/timer.h>
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070042#include <platform/iomap.h>
Amol Jadic52c8a32011-07-12 11:27:04 -070043#include <platform/gpio.h>
Ajay Dudanid04110c2011-01-17 23:55:07 -080044#include <baseband.h>
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070045#include <reg.h>
Greg Griscod6250552011-06-29 14:40:23 -070046#include <platform.h>
Amol Jadic52c8a32011-07-12 11:27:04 -070047#include <gsbi.h>
Greg Griscod2471ef2011-07-14 13:00:42 -070048#include <platform/scm-io.h>
Shashank Mittal23b8f422010-04-16 19:27:21 -070049
Amol Jadic52c8a32011-07-12 11:27:04 -070050#define LINUX_MACHTYPE_8660_SURF 2755
51#define LINUX_MACHTYPE_8660_FFA 3017
52#define LINUX_MACHTYPE_8660_FLUID 3124
53#define LINUX_MACHTYPE_8660_QT 3298
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080054#define LINUX_MACHTYPE_8660_CHARM_SURF 3181
55#define LINUX_MACHTYPE_8660_CHARM_FFA 3199
Ajay Dudani62a0d3e2011-07-01 14:27:31 -070056#define LINUX_MACHTYPE_8x60_DRAGON 3586
Shashank Mittal23b8f422010-04-16 19:27:21 -070057
Amol Jadic52c8a32011-07-12 11:27:04 -070058static const uint8_t uart_gsbi_id = GSBI_ID_12;
59
Shashank Mittal23b8f422010-04-16 19:27:21 -070060void keypad_init(void);
Greg Griscod2471ef2011-07-14 13:00:42 -070061extern void dmb(void);
Shashank Mittal23b8f422010-04-16 19:27:21 -070062
Shashank Mittal23b8f422010-04-16 19:27:21 -070063int target_is_emmc_boot(void);
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070064void debug_led_write(char);
65char debug_led_read();
Shashank Mittalc69512e2010-09-22 16:40:48 -070066uint32_t platform_id_read (void);
Greg Griscod6250552011-06-29 14:40:23 -070067void setup_fpga(void);
Shashank Mittal6df16072011-07-14 18:44:01 -070068int pm8901_reset_pwr_off(int reset);
69int pm8058_reset_pwr_off(int reset);
70int pm8058_rtc0_alarm_irq_disable(void);
71static void target_shutdown_for_rtc_alarm(void);
Shashank Mittal23b8f422010-04-16 19:27:21 -070072void target_init(void)
73{
Shashank Mittal6df16072011-07-14 18:44:01 -070074 target_shutdown_for_rtc_alarm();
Shashank Mittal23b8f422010-04-16 19:27:21 -070075 dprintf(INFO, "target_init()\n");
76
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070077 setup_fpga();
Subbaraman Narayanamurthy50d936f2010-09-08 17:09:00 -070078
79 /* Setting Debug LEDs ON */
80 debug_led_write(0xFF);
Chandan Uddarajubedca152010-06-02 23:05:15 -070081#if (!ENABLE_NANDWRITE)
82 keys_init();
83 keypad_init();
84#endif
Kinson Chikce306ff2011-07-08 15:23:33 -070085
86 /* Display splash screen if enabled */
87#if DISPLAY_SPLASH_SCREEN
88 display_init();
89 dprintf(SPEW, "Diplay initialized\n");
90 display_image_on_screen();
91#endif
92
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070093 if(mmc_boot_main(MMC_SLOT,MSM_SDC1_BASE))
Shashank Mittal23b8f422010-04-16 19:27:21 -070094 {
95 dprintf(CRITICAL, "mmc init failed!");
96 ASSERT(0);
97 }
98}
99
100unsigned board_machtype(void)
101{
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800102 struct smem_board_info_v5 board_info_v5;
Shashank Mittal2249a072011-02-14 19:24:17 -0800103 struct smem_board_info_v6 board_info_v6;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800104 unsigned int board_info_len = 0;
105 unsigned smem_status = 0;
106 unsigned format = 0;
107 unsigned id = 0;
108 unsigned hw_platform = 0;
109 unsigned fused_chip = 0;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800110 unsigned platform_subtype = 0;
Greg Griscod2471ef2011-07-14 13:00:42 -0700111 static unsigned mach_id = 0xFFFFFFFF;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700112
Greg Griscod2471ef2011-07-14 13:00:42 -0700113 if(mach_id != 0xFFFFFFFF)
Subbaraman Narayanamurthy8f0b0452011-03-11 18:30:10 -0800114 return mach_id;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800115 /* Detect external msm if this is a "fusion" */
116 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
117 &format, sizeof(format), 0);
118 if(!smem_status)
119 {
Shashank Mittal2249a072011-02-14 19:24:17 -0800120 if (format == 5)
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800121 {
122 board_info_len = sizeof(board_info_v5);
123
124 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
125 &board_info_v5, board_info_len);
126 if(!smem_status)
127 {
128 fused_chip = board_info_v5.fused_chip;
Shashank Mittal2249a072011-02-14 19:24:17 -0800129 id = board_info_v5.board_info_v3.hw_platform;
130 }
131 }
132 else if (format == 6)
133 {
134 board_info_len = sizeof(board_info_v6);
135
136 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
137 &board_info_v6, board_info_len);
138 if(!smem_status)
139 {
140 fused_chip = board_info_v6.fused_chip;
141 id = board_info_v6.board_info_v3.hw_platform;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800142 platform_subtype = board_info_v6.platform_subtype;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800143 }
144 }
145 }
146
147 /* Detect SURF v/s FFA v/s Fluid */
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800148 switch(id)
149 {
150 case 0x1:
151 hw_platform = HW_PLATFORM_SURF;
152 break;
153 case 0x2:
154 hw_platform = HW_PLATFORM_FFA;
155 break;
156 case 0x3:
157 hw_platform = HW_PLATFORM_FLUID;
158 break;
Ajay Dudani8b3262a2011-01-17 13:55:30 -0800159 case 0x6:
160 hw_platform = HW_PLATFORM_QT;
161 break;
Ajay Dudani62a0d3e2011-07-01 14:27:31 -0700162 case 0xA:
163 hw_platform = HW_PLATFORM_DRAGON;
164 break;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800165 default:
166 /* Writing to Debug LED register and reading back to auto detect
167 SURF and FFA. If we read back, it is SURF */
168 debug_led_write(0xA5);
169
170 if((debug_led_read() & 0xFF) == 0xA5)
171 {
172 debug_led_write(0);
173 hw_platform = HW_PLATFORM_SURF;
174 }
175 else
176 hw_platform = HW_PLATFORM_FFA;
177 };
178
Ajay Dudani295f38b2011-02-25 15:28:07 -0800179 /* Use platform_subtype or fused_chip information to determine machine id */
180 if (format >= 6)
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800181 {
Ajay Dudani295f38b2011-02-25 15:28:07 -0800182 switch(platform_subtype)
183 {
184 case HW_PLATFORM_SUBTYPE_CSFB:
185 case HW_PLATFORM_SUBTYPE_SVLTE2A:
186 if (hw_platform == HW_PLATFORM_SURF)
187 mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
188 else if (hw_platform == HW_PLATFORM_FFA)
189 mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
190 break;
191 default:
192 if (hw_platform == HW_PLATFORM_SURF)
193 mach_id = LINUX_MACHTYPE_8660_SURF;
194 else if (hw_platform == HW_PLATFORM_FFA)
195 mach_id = LINUX_MACHTYPE_8660_FFA;
196 else if (hw_platform == HW_PLATFORM_FLUID)
197 mach_id = LINUX_MACHTYPE_8660_FLUID;
198 else if (hw_platform == HW_PLATFORM_QT)
199 mach_id = LINUX_MACHTYPE_8660_QT;
Ajay Dudani62a0d3e2011-07-01 14:27:31 -0700200 else if (hw_platform == HW_PLATFORM_DRAGON)
201 mach_id = LINUX_MACHTYPE_8x60_DRAGON;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800202 }
203 }
204 else if (format == 5)
205 {
206 switch(fused_chip)
207 {
208 case UNKNOWN:
209 if (hw_platform == HW_PLATFORM_SURF)
210 mach_id = LINUX_MACHTYPE_8660_SURF;
211 else if (hw_platform == HW_PLATFORM_FFA)
212 mach_id = LINUX_MACHTYPE_8660_FFA;
213 else if (hw_platform == HW_PLATFORM_FLUID)
214 mach_id = LINUX_MACHTYPE_8660_FLUID;
215 else if (hw_platform == HW_PLATFORM_QT)
216 mach_id = LINUX_MACHTYPE_8660_QT;
Ajay Dudani62a0d3e2011-07-01 14:27:31 -0700217 else if (hw_platform == HW_PLATFORM_DRAGON)
218 mach_id = LINUX_MACHTYPE_8x60_DRAGON;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800219 break;
220
221 case MDM9200:
222 case MDM9600:
223 if (hw_platform == HW_PLATFORM_SURF)
224 mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
225 else if (hw_platform == HW_PLATFORM_FFA)
226 mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
227 break;
228
229 default:
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800230 mach_id = LINUX_MACHTYPE_8660_FFA;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800231 }
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800232 }
233
234 return mach_id;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700235}
236
Shashank Mittal6df16072011-07-14 18:44:01 -0700237void shutdown_device()
238{
239 gpio_config_pshold();
240 pm8058_reset_pwr_off(0);
241 pm8901_reset_pwr_off(0);
242
243 writel(0, MSM_PSHOLD_CTL_SU);
244 mdelay(10000);
245 dprintf(CRITICAL, "Shutdown failed\n");
246}
247
Shashank Mittal23b8f422010-04-16 19:27:21 -0700248void reboot_device(unsigned reboot_reason)
249{
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700250 /* Reset WDG0 counter */
251 writel(1,MSM_WDT0_RST);
252 /* Disable WDG0 */
253 writel(0,MSM_WDT0_EN);
254 /* Set WDG0 bark time */
255 writel(0x31F3,MSM_WDT0_BT);
256 /* Enable WDG0 */
257 writel(3,MSM_WDT0_EN);
258 dmb();
259 /* Enable WDG output */
Subbaraman Narayanamurthy346bdcb2011-02-24 12:02:58 -0800260 secure_writel(3,MSM_TCSR_BASE + TCSR_WDOG_CFG);
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700261 mdelay(10000);
262 dprintf (CRITICAL, "Rebooting failed\n");
Shashank Mittal23b8f422010-04-16 19:27:21 -0700263 return;
264}
265
266unsigned check_reboot_mode(void)
267{
Ajay Dudani77421292010-10-27 19:34:06 -0700268 unsigned restart_reason = 0;
Greg Griscod2471ef2011-07-14 13:00:42 -0700269 void *restart_reason_addr = (void *) 0x2A05F65C;
Ajay Dudani77421292010-10-27 19:34:06 -0700270
271 /* Read reboot reason and scrub it */
272 restart_reason = readl(restart_reason_addr);
273 writel(0x00, restart_reason_addr);
274
275 return restart_reason;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700276}
277
278void target_battery_charging_enable(unsigned enable, unsigned disconnect)
279{
280}
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -0700281
282void setup_fpga()
283{
284 writel(0x147, GPIO_CFG133_ADDR);
285 writel(0x144, GPIO_CFG135_ADDR);
286 writel(0x144, GPIO_CFG136_ADDR);
287 writel(0x144, GPIO_CFG137_ADDR);
288 writel(0x144, GPIO_CFG138_ADDR);
289 writel(0x144, GPIO_CFG139_ADDR);
290 writel(0x144, GPIO_CFG140_ADDR);
291 writel(0x144, GPIO_CFG141_ADDR);
292 writel(0x144, GPIO_CFG142_ADDR);
293 writel(0x144, GPIO_CFG143_ADDR);
294 writel(0x144, GPIO_CFG144_ADDR);
295 writel(0x144, GPIO_CFG145_ADDR);
296 writel(0x144, GPIO_CFG146_ADDR);
297 writel(0x144, GPIO_CFG147_ADDR);
298 writel(0x144, GPIO_CFG148_ADDR);
299 writel(0x144, GPIO_CFG149_ADDR);
300 writel(0x144, GPIO_CFG150_ADDR);
301 writel(0x147, GPIO_CFG151_ADDR);
302 writel(0x147, GPIO_CFG152_ADDR);
303 writel(0x147, GPIO_CFG153_ADDR);
304 writel(0x3, GPIO_CFG154_ADDR);
305 writel(0x147, GPIO_CFG155_ADDR);
306 writel(0x147, GPIO_CFG156_ADDR);
307 writel(0x147, GPIO_CFG157_ADDR);
308 writel(0x3, GPIO_CFG158_ADDR);
309
310 writel(0x00000B31, EBI2_CHIP_SELECT_CFG0);
311 writel(0xA3030020, EBI2_XMEM_CS3_CFG1);
312}
313
314void debug_led_write(char val)
315{
316 writeb(val,SURF_DEBUG_LED_ADDR);
317}
318
319char debug_led_read()
320{
321 return readb(SURF_DEBUG_LED_ADDR);
322}
Ajay Dudanid04110c2011-01-17 23:55:07 -0800323
324unsigned target_baseband()
325{
326 struct smem_board_info_v5 board_info_v5;
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800327 struct smem_board_info_v6 board_info_v6;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800328 unsigned int board_info_len = 0;
329 unsigned smem_status = 0;
330 unsigned format = 0;
331 unsigned baseband = BASEBAND_MSM;
332
333 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
334 &format, sizeof(format), 0);
335 if(!smem_status)
336 {
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800337 if (format == 5)
Ajay Dudanid04110c2011-01-17 23:55:07 -0800338 {
339 board_info_len = sizeof(board_info_v5);
340
341 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
342 &board_info_v5, board_info_len);
343 if(!smem_status)
344 {
345 /* Check for LTE fused targets or APQ. Default to MSM */
346 if (board_info_v5.fused_chip == MDM9200)
347 baseband = BASEBAND_CSFB;
348 else if (board_info_v5.fused_chip == MDM9600)
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800349 baseband = BASEBAND_SVLTE2A;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800350 else if (board_info_v5.board_info_v3.msm_id == APQ8060)
351 baseband = BASEBAND_APQ;
352 else
353 baseband = BASEBAND_MSM;
354 }
355 }
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800356 else if (format >= 6)
357 {
358 board_info_len = sizeof(board_info_v6);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800359
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800360 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
361 &board_info_v6, board_info_len);
362 if(!smem_status)
363 {
364 /* Check for LTE fused targets or APQ. Default to MSM */
365 if (board_info_v6.platform_subtype == HW_PLATFORM_SUBTYPE_CSFB)
366 baseband = BASEBAND_CSFB;
367 else if (board_info_v6.platform_subtype == HW_PLATFORM_SUBTYPE_SVLTE2A)
368 baseband = BASEBAND_SVLTE2A;
369 else if (board_info_v6.board_info_v3.msm_id == APQ8060)
370 baseband = BASEBAND_APQ;
371 else
372 baseband = BASEBAND_MSM;
373 }
374 }
375 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800376 return baseband;
377}
Ajay Dudani59606432011-01-24 18:23:38 -0800378
379static unsigned target_check_power_on_reason(void)
380{
381 unsigned power_on_status = 0;
382 unsigned int status_len = sizeof(power_on_status);
383 unsigned smem_status;
384
385 smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,
386 &power_on_status, status_len);
387
Subbaraman Narayanamurthybd2424e2011-03-29 15:29:21 -0700388 if (smem_status)
Ajay Dudani59606432011-01-24 18:23:38 -0800389 {
390 dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n");
391 }
Shashank Mittal6df16072011-07-14 18:44:01 -0700392 dprintf(INFO,"Power on reason %u\n", power_on_status);
Ajay Dudani59606432011-01-24 18:23:38 -0800393 return power_on_status;
394}
395
Shashank Mittal6df16072011-07-14 18:44:01 -0700396static void target_shutdown_for_rtc_alarm(void)
397{
398 if (target_check_power_on_reason() == PWR_ON_EVENT_RTC_ALARM)
399 {
400 dprintf(CRITICAL, "Power on due to RTC alarm. Going to shutdown!!\n");
401 pm8058_rtc0_alarm_irq_disable();
402 shutdown_device();
403 }
404}
405
Ajay Dudani59606432011-01-24 18:23:38 -0800406unsigned target_pause_for_battery_charge(void)
407{
408 if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG)
409 return 1;
410
411 return 0;
412}
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -0800413
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800414void target_serialno(unsigned char *buf)
415{
416 unsigned int serialno;
417 if(target_is_emmc_boot())
418 {
419 serialno = mmc_get_psn();
Greg Griscod2471ef2011-07-14 13:00:42 -0700420 sprintf((char *) buf, "%x", serialno);
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800421 }
422}
423
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -0800424void hsusb_gpio_init(void)
425{
426 uint32_t func;
427 uint32_t pull;
428 uint32_t dir;
429 uint32_t enable;
430 uint32_t drv;
431
432 /* GPIO 131 and 132 need to be configured for connecting to USB HS PHY */
433
434 func = 0;
435 enable = 1;
436 pull = GPIO_NO_PULL;
437 dir = 2;
438 drv = GPIO_2MA;
439 gpio_tlmm_config(131, func, dir, pull, drv, enable);
440 gpio_set(131, dir);
441
442 func = 0;
443 enable = 1;
444 pull = GPIO_NO_PULL;
445 dir = 1;
446 drv = GPIO_2MA;
447 gpio_tlmm_config(132, func, dir, pull, drv, enable);
448 gpio_set(132, dir);
449
450 return;
451}
Amol Jadic52c8a32011-07-12 11:27:04 -0700452
453uint8_t target_uart_gsbi(void)
454{
455 return uart_gsbi_id;
456}