blob: b8b91faff708f3ed801b41693a4b38a14603f305 [file] [log] [blame]
Shashank Mittal246f8d02011-01-21 17:12:27 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
5 *
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
Amol Jadi2dfe3392011-07-19 16:03:37 -070033#include <reg.h>
Shashank Mittal246f8d02011-01-21 17:12:27 -080034#include <debug.h>
35#include <dev/keys.h>
Kinson Chikea646242011-09-01 13:53:16 -070036#include <dev/ssbi.h>
Shashank Mittal246f8d02011-01-21 17:12:27 -080037#include <lib/ptable.h>
38#include <dev/flash.h>
39#include <smem.h>
Greg Griscod6250552011-06-29 14:40:23 -070040#include <mmc.h>
Shashank Mittal246f8d02011-01-21 17:12:27 -080041#include <platform/iomap.h>
Greg Griscod6250552011-06-29 14:40:23 -070042#include <platform.h>
Deepa Dinamani5e5c21a2012-02-16 18:59:57 -080043#include <crypto_hash.h>
Shashank Mittal246f8d02011-01-21 17:12:27 -080044
45#define MSM7X27A_FFA 3351
46#define MSM7X27A_SURF 3352
47#define MSM7X27A_RUMI3 3353
Channagoud Kadabi4c41c412011-09-08 15:38:30 +053048#define MSM7X27A_QRD1 3756
Channagoud Kadabi81100682011-07-26 16:14:29 +053049#define MSM7X25A_SURF 3772
50#define MSM7X25A_FFA 3771
Channagoud Kadabid53664b2011-12-28 16:39:15 +053051#define MSM7X27A_EVB 3934
Channagoud Kadabib33d4832012-02-06 17:10:56 +053052#define MSM7X27A_QRD3 4005
Channagoud Kadabi81ba1102011-10-01 16:37:59 +053053#define MSM8X25_RUMI3 3871
Channagoud Kadabi4c41c412011-09-08 15:38:30 +053054
Shashank Mittalef325412011-04-01 13:48:26 -070055#define LINUX_MACHTYPE MSM7X27A_SURF
Shashank Mittal246f8d02011-01-21 17:12:27 -080056
57#define VARIABLE_LENGTH 0x10101010
58#define DIFF_START_ADDR 0xF0F0F0F0
59#define NUM_PAGES_PER_BLOCK 0x40
Channagoud Kadabi16da3a22011-10-24 20:25:07 +053060#define RECOVERY_MODE 0x77665502
61#define FOTA_COOKIE 0x64645343
62
63unsigned int fota_cookie[1];
Shashank Mittal246f8d02011-01-21 17:12:27 -080064
65static struct ptable flash_ptable;
Shashank Mittalcb25d252011-04-05 12:13:30 -070066unsigned hw_platform = 0;
67unsigned target_msm_id = 0;
Shashank Mittal246f8d02011-01-21 17:12:27 -080068
Deepa Dinamani5e5c21a2012-02-16 18:59:57 -080069/* Setting this variable to different values defines the
70 * behavior of CE engine:
71 * platform_ce_type = CRYPTO_ENGINE_TYPE_NONE : No CE engine
72 * platform_ce_type = CRYPTO_ENGINE_TYPE_SW : Software CE engine
73 * platform_ce_type = CRYPTO_ENGINE_TYPE_HW : Hardware CE engine
74 * Behavior is determined in the target code.
75 */
76static crypto_engine_type platform_ce_type = CRYPTO_ENGINE_TYPE_SW;
77
Channagoud Kadabid53664b2011-12-28 16:39:15 +053078int machine_is_7x27a_evb();
79
Shashank Mittal246f8d02011-01-21 17:12:27 -080080/* for these partitions, start will be offset by either what we get from
81 * smem, or from the above offset if smem is not useful. Also, we should
82 * probably have smem_ptable code populate our flash_ptable.
83 *
84 * When smem provides us with a full partition table, we can get rid of
85 * this altogether.
86 *
87 */
Channagoud Kadabie57173d2011-12-19 15:42:44 +053088static struct ptentry board_part_list[] = {
Shashank Mittal246f8d02011-01-21 17:12:27 -080089 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080090 .start = 0,
91 .length = 10 /* In MB */ ,
92 .name = "boot",
93 },
Shashank Mittal246f8d02011-01-21 17:12:27 -080094 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080095 .start = DIFF_START_ADDR,
Channagoud Kadabi71961882012-02-09 16:32:41 +053096 .length = 253 /* In MB */ ,
Ajay Dudanib01e5062011-12-03 23:23:42 -080097 .name = "system",
98 },
Shashank Mittal246f8d02011-01-21 17:12:27 -080099 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800100 .start = DIFF_START_ADDR,
101 .length = 40 /* In MB */ ,
102 .name = "cache",
103 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800104 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800105 .start = DIFF_START_ADDR,
106 .length = 4 /* In MB */ ,
107 .name = "misc",
108 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800109 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800110 .start = DIFF_START_ADDR,
111 .length = VARIABLE_LENGTH,
112 .name = "userdata",
113 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800114 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800115 .start = DIFF_START_ADDR,
116 .length = 4 /* In MB */ ,
117 .name = "persist",
118 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800119 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800120 .start = DIFF_START_ADDR,
121 .length = 10 /* In MB */ ,
122 .name = "recovery",
123 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800124};
Ajay Dudanib01e5062011-12-03 23:23:42 -0800125
Channagoud Kadabie57173d2011-12-19 15:42:44 +0530126static int num_parts = sizeof(board_part_list) / sizeof(struct ptentry);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800127
Shashank Mittal246f8d02011-01-21 17:12:27 -0800128void smem_ptable_init(void);
129unsigned smem_get_apps_flash_start(void);
130
131void keypad_init(void);
132
133int target_is_emmc_boot(void);
134
135void target_init(void)
136{
137 unsigned offset;
138 struct flash_info *flash_info;
139 unsigned total_num_of_blocks;
140 unsigned next_ptr_start_adr = 0;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800141 unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive */
Shashank Mittal246f8d02011-01-21 17:12:27 -0800142 int i;
143
144 dprintf(INFO, "target_init()\n");
145
Shashank Mittal246f8d02011-01-21 17:12:27 -0800146#if (!ENABLE_NANDWRITE)
147 keys_init();
148 keypad_init();
149#endif
Shashank Mittal246f8d02011-01-21 17:12:27 -0800150
Kinson Chikce306ff2011-07-08 15:23:33 -0700151 /* Display splash screen if enabled */
152#if DISPLAY_SPLASH_SCREEN
Channagoud Kadabid53664b2011-12-28 16:39:15 +0530153 /* EVB platform comes with a new display panel, Until
154 * support for new panel is added disable splash screen
155 * for EVB
156 */
157 if (!machine_is_7x27a_evb()) {
158 display_init();
159 dprintf(SPEW, "Diplay initialized\n");
160 display_image_on_screen();
161 }
Kinson Chikce306ff2011-07-08 15:23:33 -0700162#endif
163
Ajay Dudanib01e5062011-12-03 23:23:42 -0800164 if (target_is_emmc_boot()) {
Amol Jadi2dfe3392011-07-19 16:03:37 -0700165 /* Must wait for modem-up before we can intialize MMC.
166 */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800167 while (readl(MSM_SHARED_BASE + 0x14) != 1) ;
Amol Jadi2dfe3392011-07-19 16:03:37 -0700168
Ajay Dudanib01e5062011-12-03 23:23:42 -0800169 if (mmc_boot_main(MMC_SLOT, MSM_SDC3_BASE)) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800170 dprintf(CRITICAL, "mmc init failed!");
171 ASSERT(0);
172 }
173 return;
174 }
175
176 ptable_init(&flash_ptable);
177 smem_ptable_init();
178
179 flash_init();
180 flash_info = flash_get_info();
181 ASSERT(flash_info);
182
183 offset = smem_get_apps_flash_start();
184 if (offset == 0xffffffff)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800185 while (1) ;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800186
187 total_num_of_blocks = flash_info->num_blocks;
188 blocks_per_1MB = (1 << 20) / (flash_info->block_size);
189
190 for (i = 0; i < num_parts; i++) {
191 struct ptentry *ptn = &board_part_list[i];
192 unsigned len = ((ptn->length) * blocks_per_1MB);
193
Ajay Dudanib01e5062011-12-03 23:23:42 -0800194 if (ptn->start != 0)
195 ASSERT(ptn->start == DIFF_START_ADDR);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800196
197 ptn->start = next_ptr_start_adr;
198
Ajay Dudanib01e5062011-12-03 23:23:42 -0800199 if (ptn->length == VARIABLE_LENGTH) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800200 unsigned length_for_prt = 0;
201 unsigned j;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800202 for (j = i + 1; j < num_parts; j++) {
203 struct ptentry *temp_ptn = &board_part_list[j];
204 ASSERT(temp_ptn->length != VARIABLE_LENGTH);
205 length_for_prt +=
206 ((temp_ptn->length) * blocks_per_1MB);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800207 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800208 len =
209 (total_num_of_blocks - 1) - (offset + ptn->start +
210 length_for_prt);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800211 ASSERT(len >= 0);
212 }
213 next_ptr_start_adr = ptn->start + len;
214 ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800215 len, ptn->flags, TYPE_APPS_PARTITION,
216 PERM_WRITEABLE);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800217 }
218
219 smem_add_modem_partitions(&flash_ptable);
220
221 ptable_dump(&flash_ptable);
222 flash_set_ptable(&flash_ptable);
223}
224
Shashank Mittalcb25d252011-04-05 12:13:30 -0700225void board_info(void)
226{
227 struct smem_board_info_v4 board_info_v4;
228 unsigned int board_info_len = 0;
229 unsigned smem_status;
230 unsigned format = 0;
231 unsigned id = 0;
232
233 if (hw_platform && target_msm_id)
234 return;
235
236 hw_platform = MSM7X27A_SURF;
237 target_msm_id = MSM7225A;
238
239 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800240 &format, sizeof(format), 0);
241 if (!smem_status) {
242 if (format == 4) {
Shashank Mittalcb25d252011-04-05 12:13:30 -0700243 board_info_len = sizeof(board_info_v4);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800244 smem_status =
245 smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
246 &board_info_v4,
247 board_info_len);
248 if (!smem_status) {
Shashank Mittalcb25d252011-04-05 12:13:30 -0700249 id = board_info_v4.board_info_v3.hw_platform;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800250 target_msm_id =
251 board_info_v4.board_info_v3.msm_id;
Shashank Mittalcb25d252011-04-05 12:13:30 -0700252 }
253 }
254
Channagoud Kadabi4c41c412011-09-08 15:38:30 +0530255 /* Detect SURF v/s FFA v/s QRD */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800256 switch (id) {
257 case 0x1:
258 /* Set the machine type based on msm ID */
259 if (target_msm_id == MSM7225A
260 || target_msm_id == MSM7625A
261 || target_msm_id == ESM7225A
262 || (target_msm_id >= MSM7225AA
263 && target_msm_id <= ESM7225AA))
264 hw_platform = MSM7X25A_SURF;
265 else
266 hw_platform = MSM7X27A_SURF;
267 break;
268 case 0x2:
269 if (target_msm_id == MSM7225A
270 || target_msm_id == MSM7625A
271 || target_msm_id == ESM7225A
272 || (target_msm_id >= MSM7225AA
273 && target_msm_id <= ESM7225AA))
274 hw_platform = MSM7X25A_FFA;
275 else
276 hw_platform = MSM7X27A_FFA;
277 break;
278 case 0xB:
Channagoud Kadabib33d4832012-02-06 17:10:56 +0530279 if(target_is_emmc_boot())
280 hw_platform = MSM7X27A_QRD1;
281 else
282 hw_platform = MSM7X27A_QRD3;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800283 break;
Channagoud Kadabid53664b2011-12-28 16:39:15 +0530284 case 0xC:
285 hw_platform = MSM7X27A_EVB;
286 break;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800287 default:
288 if (target_msm_id == MSM7225A
289 || target_msm_id == MSM7625A
290 || target_msm_id == ESM7225A
291 || (target_msm_id >= MSM7225AA
292 && target_msm_id <= ESM7225AA))
293 hw_platform = MSM7X25A_SURF;
294 else
295 hw_platform = MSM7X27A_SURF;
Shashank Mittalcb25d252011-04-05 12:13:30 -0700296 };
297
Ajay Dudanib01e5062011-12-03 23:23:42 -0800298 /* Set msm ID for target variants based on values read from smem */
299 switch (target_msm_id) {
300 case MSM7225A:
301 case MSM7625A:
302 case ESM7225A:
303 case MSM7225AA:
304 case MSM7625AA:
305 case ESM7225AA:
306 target_msm_id = MSM7625A;
307 break;
308 default:
309 target_msm_id = MSM7627A;
Shashank Mittalcb25d252011-04-05 12:13:30 -0700310 }
311 }
312 return;
313}
314
Shashank Mittal246f8d02011-01-21 17:12:27 -0800315unsigned board_machtype(void)
316{
Shashank Mittalcb25d252011-04-05 12:13:30 -0700317 board_info();
318 return hw_platform;
319}
320
321unsigned board_msm_id(void)
322{
323 board_info();
324 return target_msm_id;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800325}
326
Deepa Dinamani5e5c21a2012-02-16 18:59:57 -0800327crypto_engine_type board_ce_type(void)
328{
329 return platform_ce_type;
330}
331
Shashank Mittal246f8d02011-01-21 17:12:27 -0800332void reboot_device(unsigned reboot_reason)
333{
334 reboot(reboot_reason);
335}
336
Channagoud Kadabi16da3a22011-10-24 20:25:07 +0530337static void check_fota_cookie(void)
338{
339 struct ptentry *ptn;
340 struct ptable *ptable;
341 unsigned page_size = flash_page_size();
342 unsigned pagemask = page_size - 1;
343 int n = 0;
344
345 ptable = flash_get_ptable();
346 if (ptable == NULL) {
347 dprintf(CRITICAL, "ERROR: Partition table not found\n");
348 return;
349 }
350
351 ptn = ptable_find(ptable, "FOTA");
352 if (ptn == NULL) {
353 dprintf(CRITICAL, "ERROR: No FOTA partition found\n");
354 return;
355 }
356 n = (sizeof(fota_cookie) + pagemask) & (~pagemask);
357
358 if (flash_read(ptn, 0, fota_cookie, n)) {
359 dprintf(CRITICAL, "ERROR: flash read fail!\n");
360 return;
361 }
362 return;
363}
364
Shashank Mittal246f8d02011-01-21 17:12:27 -0800365unsigned check_reboot_mode(void)
366{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800367 unsigned mode[2] = { 0, 0 };
Shashank Mittal246f8d02011-01-21 17:12:27 -0800368 unsigned int mode_len = sizeof(mode);
369 unsigned smem_status;
370
371 smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800372 &mode, mode_len);
Channagoud Kadabi16da3a22011-10-24 20:25:07 +0530373
374 /*
375 * SMEM value is relied upon on power shutdown. Check either of SMEM
376 * or FOTA update cookie is set
377 */
378 check_fota_cookie();
379
Ajay Dudanib01e5062011-12-03 23:23:42 -0800380 if ((mode[0] == RECOVERY_MODE) || (fota_cookie[0] == FOTA_COOKIE))
Channagoud Kadabi16da3a22011-10-24 20:25:07 +0530381 return RECOVERY_MODE;
382
Ajay Dudanib01e5062011-12-03 23:23:42 -0800383 if (smem_status) {
384 dprintf(CRITICAL,
385 "ERROR: unable to read shared memory for reboot mode\n");
386 return 0;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800387 }
388 return mode[0];
389}
390
391static unsigned target_check_power_on_reason(void)
392{
393 unsigned power_on_status = 0;
394 unsigned int status_len = sizeof(power_on_status);
395 unsigned smem_status;
396
397 smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800398 &power_on_status, status_len);
399 if (smem_status) {
400 dprintf(CRITICAL,
401 "ERROR: unable to read shared memory for power on reason\n");
Shashank Mittal246f8d02011-01-21 17:12:27 -0800402 }
403
404 return power_on_status;
405}
406
407unsigned target_pause_for_battery_charge(void)
408{
Ajay Dudaniba822332011-11-25 13:37:31 -0800409 if (target_check_power_on_reason() == PWR_ON_EVENT_WALL_CHG)
Shashank Mittal246f8d02011-01-21 17:12:27 -0800410 return 1;
411 return 0;
412}
413
414void target_battery_charging_enable(unsigned enable, unsigned disconnect)
415{
416}
Shashank Mittal59392f32011-05-01 20:49:56 -0700417
418#if _EMMC_BOOT
419void target_serialno(unsigned char *buf)
420{
421 unsigned int serialno;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800422 serialno = mmc_get_psn();
423 sprintf(buf, "%x", serialno);
Shashank Mittal59392f32011-05-01 20:49:56 -0700424}
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -0700425
426int emmc_recovery_init(void)
427{
428 int rc;
429 rc = _emmc_recovery_init();
430 return rc;
431}
Shashank Mittal59392f32011-05-01 20:49:56 -0700432#endif
Channagoud Kadabid53664b2011-12-28 16:39:15 +0530433
434int machine_is_7x27a_evb()
435{
436 if (board_machtype() == MSM7X27A_EVB)
437 return 1;
438 else
439 return 0;
440}
Channagoud Kadabib33d4832012-02-06 17:10:56 +0530441
442int machine_is_7x27a_qrd3()
443{
444 if (board_machtype() == MSM7X27A_QRD3)
445 return 1;
446 else
447 return 0;
448}
449
450int machine_is_7x27a_qrd1()
451{
452 if (board_machtype() == MSM7X27A_QRD1)
453 return 1;
454 else
455 return 0;
456}
Channagoud Kadabi81ba1102011-10-01 16:37:59 +0530457int machine_is_8x25()
458{
459 if (board_machtype() == MSM8X25_RUMI3)
460 return 1;
461 else
462 return 0;
463}