blob: 7af1875ef37e12d030835238685bd2b18674c38b [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>
Shashank Mittal246f8d02011-01-21 17:12:27 -080043
44#define MSM7X27A_FFA 3351
45#define MSM7X27A_SURF 3352
46#define MSM7X27A_RUMI3 3353
Channagoud Kadabi4c41c412011-09-08 15:38:30 +053047#define MSM7X27A_QRD1 3756
Channagoud Kadabi81100682011-07-26 16:14:29 +053048#define MSM7X25A_SURF 3772
49#define MSM7X25A_FFA 3771
Channagoud Kadabid53664b2011-12-28 16:39:15 +053050#define MSM7X27A_EVB 3934
Channagoud Kadabib33d4832012-02-06 17:10:56 +053051#define MSM7X27A_QRD3 4005
Channagoud Kadabi4c41c412011-09-08 15:38:30 +053052
Shashank Mittalef325412011-04-01 13:48:26 -070053#define LINUX_MACHTYPE MSM7X27A_SURF
Shashank Mittal246f8d02011-01-21 17:12:27 -080054
55#define VARIABLE_LENGTH 0x10101010
56#define DIFF_START_ADDR 0xF0F0F0F0
57#define NUM_PAGES_PER_BLOCK 0x40
Channagoud Kadabi16da3a22011-10-24 20:25:07 +053058#define RECOVERY_MODE 0x77665502
59#define FOTA_COOKIE 0x64645343
60
61unsigned int fota_cookie[1];
Shashank Mittal246f8d02011-01-21 17:12:27 -080062
63static struct ptable flash_ptable;
Shashank Mittalcb25d252011-04-05 12:13:30 -070064unsigned hw_platform = 0;
65unsigned target_msm_id = 0;
Shashank Mittal246f8d02011-01-21 17:12:27 -080066
Channagoud Kadabid53664b2011-12-28 16:39:15 +053067int machine_is_7x27a_evb();
68
Shashank Mittal246f8d02011-01-21 17:12:27 -080069/* for these partitions, start will be offset by either what we get from
70 * smem, or from the above offset if smem is not useful. Also, we should
71 * probably have smem_ptable code populate our flash_ptable.
72 *
73 * When smem provides us with a full partition table, we can get rid of
74 * this altogether.
75 *
76 */
Channagoud Kadabie57173d2011-12-19 15:42:44 +053077static struct ptentry board_part_list[] = {
Shashank Mittal246f8d02011-01-21 17:12:27 -080078 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080079 .start = 0,
80 .length = 10 /* In MB */ ,
81 .name = "boot",
82 },
Shashank Mittal246f8d02011-01-21 17:12:27 -080083 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080084 .start = DIFF_START_ADDR,
Channagoud Kadabi71961882012-02-09 16:32:41 +053085 .length = 253 /* In MB */ ,
Ajay Dudanib01e5062011-12-03 23:23:42 -080086 .name = "system",
87 },
Shashank Mittal246f8d02011-01-21 17:12:27 -080088 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080089 .start = DIFF_START_ADDR,
90 .length = 40 /* In MB */ ,
91 .name = "cache",
92 },
Shashank Mittal246f8d02011-01-21 17:12:27 -080093 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080094 .start = DIFF_START_ADDR,
95 .length = 4 /* In MB */ ,
96 .name = "misc",
97 },
Shashank Mittal246f8d02011-01-21 17:12:27 -080098 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080099 .start = DIFF_START_ADDR,
100 .length = VARIABLE_LENGTH,
101 .name = "userdata",
102 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800103 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800104 .start = DIFF_START_ADDR,
105 .length = 4 /* In MB */ ,
106 .name = "persist",
107 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800108 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800109 .start = DIFF_START_ADDR,
110 .length = 10 /* In MB */ ,
111 .name = "recovery",
112 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800113};
Ajay Dudanib01e5062011-12-03 23:23:42 -0800114
Channagoud Kadabie57173d2011-12-19 15:42:44 +0530115static int num_parts = sizeof(board_part_list) / sizeof(struct ptentry);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800116
Shashank Mittal246f8d02011-01-21 17:12:27 -0800117void smem_ptable_init(void);
118unsigned smem_get_apps_flash_start(void);
119
120void keypad_init(void);
121
122int target_is_emmc_boot(void);
123
124void target_init(void)
125{
126 unsigned offset;
127 struct flash_info *flash_info;
128 unsigned total_num_of_blocks;
129 unsigned next_ptr_start_adr = 0;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800130 unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive */
Shashank Mittal246f8d02011-01-21 17:12:27 -0800131 int i;
132
133 dprintf(INFO, "target_init()\n");
134
Shashank Mittal246f8d02011-01-21 17:12:27 -0800135#if (!ENABLE_NANDWRITE)
136 keys_init();
137 keypad_init();
138#endif
Shashank Mittal246f8d02011-01-21 17:12:27 -0800139
Kinson Chikce306ff2011-07-08 15:23:33 -0700140 /* Display splash screen if enabled */
141#if DISPLAY_SPLASH_SCREEN
Channagoud Kadabid53664b2011-12-28 16:39:15 +0530142 /* EVB platform comes with a new display panel, Until
143 * support for new panel is added disable splash screen
144 * for EVB
145 */
146 if (!machine_is_7x27a_evb()) {
147 display_init();
148 dprintf(SPEW, "Diplay initialized\n");
149 display_image_on_screen();
150 }
Kinson Chikce306ff2011-07-08 15:23:33 -0700151#endif
152
Ajay Dudanib01e5062011-12-03 23:23:42 -0800153 if (target_is_emmc_boot()) {
Amol Jadi2dfe3392011-07-19 16:03:37 -0700154 /* Must wait for modem-up before we can intialize MMC.
155 */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800156 while (readl(MSM_SHARED_BASE + 0x14) != 1) ;
Amol Jadi2dfe3392011-07-19 16:03:37 -0700157
Ajay Dudanib01e5062011-12-03 23:23:42 -0800158 if (mmc_boot_main(MMC_SLOT, MSM_SDC3_BASE)) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800159 dprintf(CRITICAL, "mmc init failed!");
160 ASSERT(0);
161 }
162 return;
163 }
164
165 ptable_init(&flash_ptable);
166 smem_ptable_init();
167
168 flash_init();
169 flash_info = flash_get_info();
170 ASSERT(flash_info);
171
172 offset = smem_get_apps_flash_start();
173 if (offset == 0xffffffff)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800174 while (1) ;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800175
176 total_num_of_blocks = flash_info->num_blocks;
177 blocks_per_1MB = (1 << 20) / (flash_info->block_size);
178
179 for (i = 0; i < num_parts; i++) {
180 struct ptentry *ptn = &board_part_list[i];
181 unsigned len = ((ptn->length) * blocks_per_1MB);
182
Ajay Dudanib01e5062011-12-03 23:23:42 -0800183 if (ptn->start != 0)
184 ASSERT(ptn->start == DIFF_START_ADDR);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800185
186 ptn->start = next_ptr_start_adr;
187
Ajay Dudanib01e5062011-12-03 23:23:42 -0800188 if (ptn->length == VARIABLE_LENGTH) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800189 unsigned length_for_prt = 0;
190 unsigned j;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800191 for (j = i + 1; j < num_parts; j++) {
192 struct ptentry *temp_ptn = &board_part_list[j];
193 ASSERT(temp_ptn->length != VARIABLE_LENGTH);
194 length_for_prt +=
195 ((temp_ptn->length) * blocks_per_1MB);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800196 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800197 len =
198 (total_num_of_blocks - 1) - (offset + ptn->start +
199 length_for_prt);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800200 ASSERT(len >= 0);
201 }
202 next_ptr_start_adr = ptn->start + len;
203 ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800204 len, ptn->flags, TYPE_APPS_PARTITION,
205 PERM_WRITEABLE);
Shashank Mittal246f8d02011-01-21 17:12:27 -0800206 }
207
208 smem_add_modem_partitions(&flash_ptable);
209
210 ptable_dump(&flash_ptable);
211 flash_set_ptable(&flash_ptable);
212}
213
Shashank Mittalcb25d252011-04-05 12:13:30 -0700214void board_info(void)
215{
216 struct smem_board_info_v4 board_info_v4;
217 unsigned int board_info_len = 0;
218 unsigned smem_status;
219 unsigned format = 0;
220 unsigned id = 0;
221
222 if (hw_platform && target_msm_id)
223 return;
224
225 hw_platform = MSM7X27A_SURF;
226 target_msm_id = MSM7225A;
227
228 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800229 &format, sizeof(format), 0);
230 if (!smem_status) {
231 if (format == 4) {
Shashank Mittalcb25d252011-04-05 12:13:30 -0700232 board_info_len = sizeof(board_info_v4);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800233 smem_status =
234 smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
235 &board_info_v4,
236 board_info_len);
237 if (!smem_status) {
Shashank Mittalcb25d252011-04-05 12:13:30 -0700238 id = board_info_v4.board_info_v3.hw_platform;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800239 target_msm_id =
240 board_info_v4.board_info_v3.msm_id;
Shashank Mittalcb25d252011-04-05 12:13:30 -0700241 }
242 }
243
Channagoud Kadabi4c41c412011-09-08 15:38:30 +0530244 /* Detect SURF v/s FFA v/s QRD */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800245 switch (id) {
246 case 0x1:
247 /* Set the machine type based on msm ID */
248 if (target_msm_id == MSM7225A
249 || target_msm_id == MSM7625A
250 || target_msm_id == ESM7225A
251 || (target_msm_id >= MSM7225AA
252 && target_msm_id <= ESM7225AA))
253 hw_platform = MSM7X25A_SURF;
254 else
255 hw_platform = MSM7X27A_SURF;
256 break;
257 case 0x2:
258 if (target_msm_id == MSM7225A
259 || target_msm_id == MSM7625A
260 || target_msm_id == ESM7225A
261 || (target_msm_id >= MSM7225AA
262 && target_msm_id <= ESM7225AA))
263 hw_platform = MSM7X25A_FFA;
264 else
265 hw_platform = MSM7X27A_FFA;
266 break;
267 case 0xB:
Channagoud Kadabib33d4832012-02-06 17:10:56 +0530268 if(target_is_emmc_boot())
269 hw_platform = MSM7X27A_QRD1;
270 else
271 hw_platform = MSM7X27A_QRD3;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800272 break;
Channagoud Kadabid53664b2011-12-28 16:39:15 +0530273 case 0xC:
274 hw_platform = MSM7X27A_EVB;
275 break;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800276 default:
277 if (target_msm_id == MSM7225A
278 || target_msm_id == MSM7625A
279 || target_msm_id == ESM7225A
280 || (target_msm_id >= MSM7225AA
281 && target_msm_id <= ESM7225AA))
282 hw_platform = MSM7X25A_SURF;
283 else
284 hw_platform = MSM7X27A_SURF;
Shashank Mittalcb25d252011-04-05 12:13:30 -0700285 };
286
Ajay Dudanib01e5062011-12-03 23:23:42 -0800287 /* Set msm ID for target variants based on values read from smem */
288 switch (target_msm_id) {
289 case MSM7225A:
290 case MSM7625A:
291 case ESM7225A:
292 case MSM7225AA:
293 case MSM7625AA:
294 case ESM7225AA:
295 target_msm_id = MSM7625A;
296 break;
297 default:
298 target_msm_id = MSM7627A;
Shashank Mittalcb25d252011-04-05 12:13:30 -0700299 }
300 }
301 return;
302}
303
Shashank Mittal246f8d02011-01-21 17:12:27 -0800304unsigned board_machtype(void)
305{
Shashank Mittalcb25d252011-04-05 12:13:30 -0700306 board_info();
307 return hw_platform;
308}
309
310unsigned board_msm_id(void)
311{
312 board_info();
313 return target_msm_id;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800314}
315
316void reboot_device(unsigned reboot_reason)
317{
318 reboot(reboot_reason);
319}
320
Channagoud Kadabi16da3a22011-10-24 20:25:07 +0530321static void check_fota_cookie(void)
322{
323 struct ptentry *ptn;
324 struct ptable *ptable;
325 unsigned page_size = flash_page_size();
326 unsigned pagemask = page_size - 1;
327 int n = 0;
328
329 ptable = flash_get_ptable();
330 if (ptable == NULL) {
331 dprintf(CRITICAL, "ERROR: Partition table not found\n");
332 return;
333 }
334
335 ptn = ptable_find(ptable, "FOTA");
336 if (ptn == NULL) {
337 dprintf(CRITICAL, "ERROR: No FOTA partition found\n");
338 return;
339 }
340 n = (sizeof(fota_cookie) + pagemask) & (~pagemask);
341
342 if (flash_read(ptn, 0, fota_cookie, n)) {
343 dprintf(CRITICAL, "ERROR: flash read fail!\n");
344 return;
345 }
346 return;
347}
348
Shashank Mittal246f8d02011-01-21 17:12:27 -0800349unsigned check_reboot_mode(void)
350{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800351 unsigned mode[2] = { 0, 0 };
Shashank Mittal246f8d02011-01-21 17:12:27 -0800352 unsigned int mode_len = sizeof(mode);
353 unsigned smem_status;
354
355 smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800356 &mode, mode_len);
Channagoud Kadabi16da3a22011-10-24 20:25:07 +0530357
358 /*
359 * SMEM value is relied upon on power shutdown. Check either of SMEM
360 * or FOTA update cookie is set
361 */
362 check_fota_cookie();
363
Ajay Dudanib01e5062011-12-03 23:23:42 -0800364 if ((mode[0] == RECOVERY_MODE) || (fota_cookie[0] == FOTA_COOKIE))
Channagoud Kadabi16da3a22011-10-24 20:25:07 +0530365 return RECOVERY_MODE;
366
Ajay Dudanib01e5062011-12-03 23:23:42 -0800367 if (smem_status) {
368 dprintf(CRITICAL,
369 "ERROR: unable to read shared memory for reboot mode\n");
370 return 0;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800371 }
372 return mode[0];
373}
374
375static unsigned target_check_power_on_reason(void)
376{
377 unsigned power_on_status = 0;
378 unsigned int status_len = sizeof(power_on_status);
379 unsigned smem_status;
380
381 smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800382 &power_on_status, status_len);
383 if (smem_status) {
384 dprintf(CRITICAL,
385 "ERROR: unable to read shared memory for power on reason\n");
Shashank Mittal246f8d02011-01-21 17:12:27 -0800386 }
387
388 return power_on_status;
389}
390
391unsigned target_pause_for_battery_charge(void)
392{
Ajay Dudaniba822332011-11-25 13:37:31 -0800393 if (target_check_power_on_reason() == PWR_ON_EVENT_WALL_CHG)
Shashank Mittal246f8d02011-01-21 17:12:27 -0800394 return 1;
395 return 0;
396}
397
398void target_battery_charging_enable(unsigned enable, unsigned disconnect)
399{
400}
Shashank Mittal59392f32011-05-01 20:49:56 -0700401
402#if _EMMC_BOOT
403void target_serialno(unsigned char *buf)
404{
405 unsigned int serialno;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800406 serialno = mmc_get_psn();
407 sprintf(buf, "%x", serialno);
Shashank Mittal59392f32011-05-01 20:49:56 -0700408}
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -0700409
410int emmc_recovery_init(void)
411{
412 int rc;
413 rc = _emmc_recovery_init();
414 return rc;
415}
Shashank Mittal59392f32011-05-01 20:49:56 -0700416#endif
Channagoud Kadabid53664b2011-12-28 16:39:15 +0530417
418int machine_is_7x27a_evb()
419{
420 if (board_machtype() == MSM7X27A_EVB)
421 return 1;
422 else
423 return 0;
424}
Channagoud Kadabib33d4832012-02-06 17:10:56 +0530425
426int machine_is_7x27a_qrd3()
427{
428 if (board_machtype() == MSM7X27A_QRD3)
429 return 1;
430 else
431 return 0;
432}
433
434int machine_is_7x27a_qrd1()
435{
436 if (board_machtype() == MSM7X27A_QRD1)
437 return 1;
438 else
439 return 0;
440}