blob: 46aa6655adbbf9e3ca70c73a33963f5f57995ff7 [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>
Kinson Chikea646242011-09-01 13:53:16 -070035#include <dev/ssbi.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>
Wentao Xu8d6150c2011-06-22 11:03:18 -040049#include <platform/machtype.h>
Shashank Mittal23b8f422010-04-16 19:27:21 -070050
Amol Jadic52c8a32011-07-12 11:27:04 -070051static const uint8_t uart_gsbi_id = GSBI_ID_12;
52
Shashank Mittal23b8f422010-04-16 19:27:21 -070053void keypad_init(void);
Greg Griscod2471ef2011-07-14 13:00:42 -070054extern void dmb(void);
Shashank Mittal23b8f422010-04-16 19:27:21 -070055
Shashank Mittal23b8f422010-04-16 19:27:21 -070056int target_is_emmc_boot(void);
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070057void debug_led_write(char);
58char debug_led_read();
Shashank Mittalc69512e2010-09-22 16:40:48 -070059uint32_t platform_id_read (void);
Greg Griscod6250552011-06-29 14:40:23 -070060void setup_fpga(void);
Shashank Mittal6df16072011-07-14 18:44:01 -070061int pm8901_reset_pwr_off(int reset);
62int pm8058_reset_pwr_off(int reset);
63int pm8058_rtc0_alarm_irq_disable(void);
64static void target_shutdown_for_rtc_alarm(void);
Shashank Mittal23b8f422010-04-16 19:27:21 -070065void target_init(void)
66{
Shashank Mittal6df16072011-07-14 18:44:01 -070067 target_shutdown_for_rtc_alarm();
Shashank Mittal23b8f422010-04-16 19:27:21 -070068 dprintf(INFO, "target_init()\n");
69
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -070070 setup_fpga();
Subbaraman Narayanamurthy50d936f2010-09-08 17:09:00 -070071
72 /* Setting Debug LEDs ON */
73 debug_led_write(0xFF);
Chandan Uddarajubedca152010-06-02 23:05:15 -070074#if (!ENABLE_NANDWRITE)
75 keys_init();
76 keypad_init();
77#endif
Kinson Chikce306ff2011-07-08 15:23:33 -070078
79 /* Display splash screen if enabled */
80#if DISPLAY_SPLASH_SCREEN
81 display_init();
82 dprintf(SPEW, "Diplay initialized\n");
83 display_image_on_screen();
84#endif
85
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070086 if(mmc_boot_main(MMC_SLOT,MSM_SDC1_BASE))
Shashank Mittal23b8f422010-04-16 19:27:21 -070087 {
88 dprintf(CRITICAL, "mmc init failed!");
89 ASSERT(0);
90 }
91}
92
93unsigned board_machtype(void)
94{
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080095 struct smem_board_info_v5 board_info_v5;
Shashank Mittal2249a072011-02-14 19:24:17 -080096 struct smem_board_info_v6 board_info_v6;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -080097 unsigned int board_info_len = 0;
98 unsigned smem_status = 0;
99 unsigned format = 0;
100 unsigned id = 0;
101 unsigned hw_platform = 0;
102 unsigned fused_chip = 0;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800103 unsigned platform_subtype = 0;
Greg Griscod2471ef2011-07-14 13:00:42 -0700104 static unsigned mach_id = 0xFFFFFFFF;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700105
Greg Griscod2471ef2011-07-14 13:00:42 -0700106 if(mach_id != 0xFFFFFFFF)
Subbaraman Narayanamurthy8f0b0452011-03-11 18:30:10 -0800107 return mach_id;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800108 /* Detect external msm if this is a "fusion" */
109 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
110 &format, sizeof(format), 0);
111 if(!smem_status)
112 {
Shashank Mittal2249a072011-02-14 19:24:17 -0800113 if (format == 5)
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800114 {
115 board_info_len = sizeof(board_info_v5);
116
117 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
118 &board_info_v5, board_info_len);
119 if(!smem_status)
120 {
121 fused_chip = board_info_v5.fused_chip;
Shashank Mittal2249a072011-02-14 19:24:17 -0800122 id = board_info_v5.board_info_v3.hw_platform;
123 }
124 }
125 else if (format == 6)
126 {
127 board_info_len = sizeof(board_info_v6);
128
129 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
130 &board_info_v6, board_info_len);
131 if(!smem_status)
132 {
133 fused_chip = board_info_v6.fused_chip;
134 id = board_info_v6.board_info_v3.hw_platform;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800135 platform_subtype = board_info_v6.platform_subtype;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800136 }
137 }
138 }
139
140 /* Detect SURF v/s FFA v/s Fluid */
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800141 switch(id)
142 {
143 case 0x1:
144 hw_platform = HW_PLATFORM_SURF;
145 break;
146 case 0x2:
147 hw_platform = HW_PLATFORM_FFA;
148 break;
149 case 0x3:
150 hw_platform = HW_PLATFORM_FLUID;
151 break;
Ajay Dudani8b3262a2011-01-17 13:55:30 -0800152 case 0x6:
153 hw_platform = HW_PLATFORM_QT;
154 break;
Ajay Dudani62a0d3e2011-07-01 14:27:31 -0700155 case 0xA:
156 hw_platform = HW_PLATFORM_DRAGON;
157 break;
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800158 default:
159 /* Writing to Debug LED register and reading back to auto detect
160 SURF and FFA. If we read back, it is SURF */
161 debug_led_write(0xA5);
162
163 if((debug_led_read() & 0xFF) == 0xA5)
164 {
165 debug_led_write(0);
166 hw_platform = HW_PLATFORM_SURF;
167 }
168 else
169 hw_platform = HW_PLATFORM_FFA;
170 };
171
Ajay Dudani295f38b2011-02-25 15:28:07 -0800172 /* Use platform_subtype or fused_chip information to determine machine id */
173 if (format >= 6)
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800174 {
Ajay Dudani295f38b2011-02-25 15:28:07 -0800175 switch(platform_subtype)
176 {
177 case HW_PLATFORM_SUBTYPE_CSFB:
178 case HW_PLATFORM_SUBTYPE_SVLTE2A:
179 if (hw_platform == HW_PLATFORM_SURF)
180 mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
181 else if (hw_platform == HW_PLATFORM_FFA)
182 mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
183 break;
184 default:
185 if (hw_platform == HW_PLATFORM_SURF)
186 mach_id = LINUX_MACHTYPE_8660_SURF;
187 else if (hw_platform == HW_PLATFORM_FFA)
188 mach_id = LINUX_MACHTYPE_8660_FFA;
189 else if (hw_platform == HW_PLATFORM_FLUID)
190 mach_id = LINUX_MACHTYPE_8660_FLUID;
191 else if (hw_platform == HW_PLATFORM_QT)
192 mach_id = LINUX_MACHTYPE_8660_QT;
Ajay Dudani62a0d3e2011-07-01 14:27:31 -0700193 else if (hw_platform == HW_PLATFORM_DRAGON)
194 mach_id = LINUX_MACHTYPE_8x60_DRAGON;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800195 }
196 }
197 else if (format == 5)
198 {
199 switch(fused_chip)
200 {
201 case UNKNOWN:
202 if (hw_platform == HW_PLATFORM_SURF)
203 mach_id = LINUX_MACHTYPE_8660_SURF;
204 else if (hw_platform == HW_PLATFORM_FFA)
205 mach_id = LINUX_MACHTYPE_8660_FFA;
206 else if (hw_platform == HW_PLATFORM_FLUID)
207 mach_id = LINUX_MACHTYPE_8660_FLUID;
208 else if (hw_platform == HW_PLATFORM_QT)
209 mach_id = LINUX_MACHTYPE_8660_QT;
Ajay Dudani62a0d3e2011-07-01 14:27:31 -0700210 else if (hw_platform == HW_PLATFORM_DRAGON)
211 mach_id = LINUX_MACHTYPE_8x60_DRAGON;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800212 break;
213
214 case MDM9200:
215 case MDM9600:
216 if (hw_platform == HW_PLATFORM_SURF)
217 mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
218 else if (hw_platform == HW_PLATFORM_FFA)
219 mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
220 break;
221
222 default:
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800223 mach_id = LINUX_MACHTYPE_8660_FFA;
Ajay Dudani295f38b2011-02-25 15:28:07 -0800224 }
Ajay Dudani16ea8fb2010-11-23 19:15:38 -0800225 }
226
227 return mach_id;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700228}
229
Shashank Mittal6df16072011-07-14 18:44:01 -0700230void shutdown_device()
231{
232 gpio_config_pshold();
233 pm8058_reset_pwr_off(0);
234 pm8901_reset_pwr_off(0);
235
236 writel(0, MSM_PSHOLD_CTL_SU);
237 mdelay(10000);
238 dprintf(CRITICAL, "Shutdown failed\n");
239}
240
Shashank Mittal23b8f422010-04-16 19:27:21 -0700241void reboot_device(unsigned reboot_reason)
242{
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700243 /* Reset WDG0 counter */
244 writel(1,MSM_WDT0_RST);
245 /* Disable WDG0 */
246 writel(0,MSM_WDT0_EN);
247 /* Set WDG0 bark time */
248 writel(0x31F3,MSM_WDT0_BT);
249 /* Enable WDG0 */
250 writel(3,MSM_WDT0_EN);
251 dmb();
252 /* Enable WDG output */
Subbaraman Narayanamurthy346bdcb2011-02-24 12:02:58 -0800253 secure_writel(3,MSM_TCSR_BASE + TCSR_WDOG_CFG);
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700254 mdelay(10000);
255 dprintf (CRITICAL, "Rebooting failed\n");
Shashank Mittal23b8f422010-04-16 19:27:21 -0700256 return;
257}
258
259unsigned check_reboot_mode(void)
260{
Ajay Dudani77421292010-10-27 19:34:06 -0700261 unsigned restart_reason = 0;
Greg Griscod2471ef2011-07-14 13:00:42 -0700262 void *restart_reason_addr = (void *) 0x2A05F65C;
Ajay Dudani77421292010-10-27 19:34:06 -0700263
264 /* Read reboot reason and scrub it */
265 restart_reason = readl(restart_reason_addr);
266 writel(0x00, restart_reason_addr);
267
268 return restart_reason;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700269}
270
271void target_battery_charging_enable(unsigned enable, unsigned disconnect)
272{
273}
Subbaraman Narayanamurthyf9b6e0d2010-09-08 16:51:43 -0700274
275void setup_fpga()
276{
277 writel(0x147, GPIO_CFG133_ADDR);
278 writel(0x144, GPIO_CFG135_ADDR);
279 writel(0x144, GPIO_CFG136_ADDR);
280 writel(0x144, GPIO_CFG137_ADDR);
281 writel(0x144, GPIO_CFG138_ADDR);
282 writel(0x144, GPIO_CFG139_ADDR);
283 writel(0x144, GPIO_CFG140_ADDR);
284 writel(0x144, GPIO_CFG141_ADDR);
285 writel(0x144, GPIO_CFG142_ADDR);
286 writel(0x144, GPIO_CFG143_ADDR);
287 writel(0x144, GPIO_CFG144_ADDR);
288 writel(0x144, GPIO_CFG145_ADDR);
289 writel(0x144, GPIO_CFG146_ADDR);
290 writel(0x144, GPIO_CFG147_ADDR);
291 writel(0x144, GPIO_CFG148_ADDR);
292 writel(0x144, GPIO_CFG149_ADDR);
293 writel(0x144, GPIO_CFG150_ADDR);
294 writel(0x147, GPIO_CFG151_ADDR);
295 writel(0x147, GPIO_CFG152_ADDR);
296 writel(0x147, GPIO_CFG153_ADDR);
297 writel(0x3, GPIO_CFG154_ADDR);
298 writel(0x147, GPIO_CFG155_ADDR);
299 writel(0x147, GPIO_CFG156_ADDR);
300 writel(0x147, GPIO_CFG157_ADDR);
301 writel(0x3, GPIO_CFG158_ADDR);
302
303 writel(0x00000B31, EBI2_CHIP_SELECT_CFG0);
304 writel(0xA3030020, EBI2_XMEM_CS3_CFG1);
305}
306
307void debug_led_write(char val)
308{
309 writeb(val,SURF_DEBUG_LED_ADDR);
310}
311
312char debug_led_read()
313{
314 return readb(SURF_DEBUG_LED_ADDR);
315}
Ajay Dudanid04110c2011-01-17 23:55:07 -0800316
317unsigned target_baseband()
318{
319 struct smem_board_info_v5 board_info_v5;
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800320 struct smem_board_info_v6 board_info_v6;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800321 unsigned int board_info_len = 0;
322 unsigned smem_status = 0;
323 unsigned format = 0;
324 unsigned baseband = BASEBAND_MSM;
325
326 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
327 &format, sizeof(format), 0);
328 if(!smem_status)
329 {
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800330 if (format == 5)
Ajay Dudanid04110c2011-01-17 23:55:07 -0800331 {
332 board_info_len = sizeof(board_info_v5);
333
334 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
335 &board_info_v5, board_info_len);
336 if(!smem_status)
337 {
338 /* Check for LTE fused targets or APQ. Default to MSM */
339 if (board_info_v5.fused_chip == MDM9200)
340 baseband = BASEBAND_CSFB;
341 else if (board_info_v5.fused_chip == MDM9600)
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800342 baseband = BASEBAND_SVLTE2A;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800343 else if (board_info_v5.board_info_v3.msm_id == APQ8060)
344 baseband = BASEBAND_APQ;
345 else
346 baseband = BASEBAND_MSM;
347 }
348 }
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800349 else if (format >= 6)
350 {
351 board_info_len = sizeof(board_info_v6);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800352
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800353 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
354 &board_info_v6, board_info_len);
355 if(!smem_status)
356 {
357 /* Check for LTE fused targets or APQ. Default to MSM */
358 if (board_info_v6.platform_subtype == HW_PLATFORM_SUBTYPE_CSFB)
359 baseband = BASEBAND_CSFB;
360 else if (board_info_v6.platform_subtype == HW_PLATFORM_SUBTYPE_SVLTE2A)
361 baseband = BASEBAND_SVLTE2A;
362 else if (board_info_v6.board_info_v3.msm_id == APQ8060)
363 baseband = BASEBAND_APQ;
364 else
365 baseband = BASEBAND_MSM;
366 }
367 }
368 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800369 return baseband;
370}
Ajay Dudani59606432011-01-24 18:23:38 -0800371
372static unsigned target_check_power_on_reason(void)
373{
374 unsigned power_on_status = 0;
375 unsigned int status_len = sizeof(power_on_status);
376 unsigned smem_status;
377
378 smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,
379 &power_on_status, status_len);
380
Subbaraman Narayanamurthybd2424e2011-03-29 15:29:21 -0700381 if (smem_status)
Ajay Dudani59606432011-01-24 18:23:38 -0800382 {
383 dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n");
384 }
Shashank Mittal6df16072011-07-14 18:44:01 -0700385 dprintf(INFO,"Power on reason %u\n", power_on_status);
Ajay Dudani59606432011-01-24 18:23:38 -0800386 return power_on_status;
387}
388
Shashank Mittal6df16072011-07-14 18:44:01 -0700389static void target_shutdown_for_rtc_alarm(void)
390{
391 if (target_check_power_on_reason() == PWR_ON_EVENT_RTC_ALARM)
392 {
393 dprintf(CRITICAL, "Power on due to RTC alarm. Going to shutdown!!\n");
394 pm8058_rtc0_alarm_irq_disable();
395 shutdown_device();
396 }
397}
398
Ajay Dudani59606432011-01-24 18:23:38 -0800399unsigned target_pause_for_battery_charge(void)
400{
401 if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG)
402 return 1;
403
404 return 0;
405}
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -0800406
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800407void target_serialno(unsigned char *buf)
408{
409 unsigned int serialno;
410 if(target_is_emmc_boot())
411 {
412 serialno = mmc_get_psn();
Greg Griscod2471ef2011-07-14 13:00:42 -0700413 sprintf((char *) buf, "%x", serialno);
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800414 }
415}
416
Subbaraman Narayanamurthyb0111a12011-02-03 14:24:16 -0800417void hsusb_gpio_init(void)
418{
419 uint32_t func;
420 uint32_t pull;
421 uint32_t dir;
422 uint32_t enable;
423 uint32_t drv;
424
425 /* GPIO 131 and 132 need to be configured for connecting to USB HS PHY */
426
427 func = 0;
428 enable = 1;
429 pull = GPIO_NO_PULL;
430 dir = 2;
431 drv = GPIO_2MA;
432 gpio_tlmm_config(131, func, dir, pull, drv, enable);
433 gpio_set(131, dir);
434
435 func = 0;
436 enable = 1;
437 pull = GPIO_NO_PULL;
438 dir = 1;
439 drv = GPIO_2MA;
440 gpio_tlmm_config(132, func, dir, pull, drv, enable);
441 gpio_set(132, dir);
442
443 return;
444}
Amol Jadic52c8a32011-07-12 11:27:04 -0700445
446uint8_t target_uart_gsbi(void)
447{
448 return uart_gsbi_id;
449}
Shashank Mittal162244e2011-08-08 19:01:25 -0700450
451int emmc_recovery_init(void)
452{
453 int rc;
454 rc = _emmc_recovery_init();
455 return rc;
456}
457