blob: 1aae5a28877472aea6ac22aa2a93126c3aa3466d [file] [log] [blame]
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08004 * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -08005 *
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>
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -070035#include <dev/gpio.h>
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080036#include <dev/gpio_keypad.h>
37#include <lib/ptable.h>
38#include <dev/flash.h>
Chandan Uddaraju885e4db2009-12-03 22:45:26 -080039#include <smem.h>
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -070040#include <reg.h>
Greg Griscod6250552011-06-29 14:40:23 -070041#include <mmc.h>
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070042#include <platform/iomap.h>
Wentao Xu97df7fd2011-01-19 15:01:17 -050043#include <platform/machtype.h>
Greg Griscod6250552011-06-29 14:40:23 -070044#include <platform.h>
Chandan Uddarajuf759be32010-03-17 19:04:16 -070045
46#define MSM8255_ID 74
47#define MSM8655_ID 75
Ajay Dudani65077982010-09-12 23:55:10 -070048#define APQ8055_ID 85
Chandan Uddaraju885e4db2009-12-03 22:45:26 -080049
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080050#define VARIABLE_LENGTH 0x10101010
51#define DIFF_START_ADDR 0xF0F0F0F0
52#define NUM_PAGES_PER_BLOCK 0x40
53
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070054static unsigned mmc_sdc_base[] = { MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE};
55
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080056static struct ptable flash_ptable;
Chandan Uddaraju1434a602010-03-08 17:13:38 -080057static int hw_platform_type = -1;
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080058
59/* for these partitions, start will be offset by either what we get from
60 * smem, or from the above offset if smem is not useful. Also, we should
61 * probably have smem_ptable code populate our flash_ptable.
62 *
63 * When smem provides us with a full partition table, we can get rid of
64 * this altogether.
65 *
66 */
67static struct ptentry board_part_list[] = {
68 {
69 .start = 0,
Chandan Uddarajud56669f2010-04-19 22:15:06 -070070 .length = 5 /* In MB */,
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080071 .name = "boot",
72 },
73 {
Chandan Uddarajud56669f2010-04-19 22:15:06 -070074 .start = DIFF_START_ADDR,
David Ng3755bb82010-10-12 18:12:06 -070075 .length = 120 /* In MB */,
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080076 .name = "system",
77 },
78 {
Chandan Uddarajud56669f2010-04-19 22:15:06 -070079 .start = DIFF_START_ADDR,
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -070080 .length = 5 /* In MB */,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080081 .name = "cache",
Chandan Uddaraju94183c02010-01-15 15:13:59 -080082 },
83 {
Chandan Uddarajud56669f2010-04-19 22:15:06 -070084 .start = DIFF_START_ADDR,
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -070085 .length = 1 /* In MB */,
86 .name = "misc",
87 },
88 {
89 .start = DIFF_START_ADDR,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080090 .length = VARIABLE_LENGTH,
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080091 .name = "userdata",
92 },
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080093 {
94 .start = DIFF_START_ADDR,
Chandan Uddarajud56669f2010-04-19 22:15:06 -070095 .length = 3 /* In MB */,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080096 .name = "persist",
97 },
98 {
99 .start = DIFF_START_ADDR,
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700100 .length = 5 /* In MB */,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800101 .name = "recovery",
102 },
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800103};
104static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry);
105
106void smem_ptable_init(void);
107unsigned smem_get_apps_flash_start(void);
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700108unsigned smem_read_alloc_entry_offset(smem_mem_type_t, void *, int, int);
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800109
110void keypad_init(void);
111
David Ng183a7422009-12-07 14:55:21 -0800112static int emmc_boot = -1; /* set to uninitialized */
113int target_is_emmc_boot(void);
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800114static int platform_version = -1;
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700115static int target_msm_id = -1;
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700116static int interleaved_mode_enabled = -1;
117void enable_interleave_mode(int);
118
119int target_is_interleaved_mode(void)
120{
121 struct smem_board_info_v4 board_info_v4;
122 unsigned int board_info_len = 0;
123 unsigned smem_status;
124 char *build_type;
125 unsigned format = 0;
126
127 if (interleaved_mode_enabled != -1)
128 {
129 return interleaved_mode_enabled;
130 }
131
132 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
133 &format, sizeof(format), 0);
134 if(!smem_status)
135 {
136 if ((format == 3) || (format == 4))
137 {
138 if (format == 4)
139 board_info_len = sizeof(board_info_v4);
140 else
141 board_info_len = sizeof(board_info_v4.board_info_v3);
142
143 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
144 &board_info_v4, board_info_len);
145 if(!smem_status)
146 {
147 build_type = (char *)(board_info_v4.board_info_v3.build_id) + 9;
148
149 interleaved_mode_enabled = 0;
150
151 if (*build_type == 'C')
152 {
153 interleaved_mode_enabled = 1;
154 }
155 }
156 }
157 }
158
159 return interleaved_mode_enabled;
160}
David Ng183a7422009-12-07 14:55:21 -0800161
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800162void target_init(void)
163{
164 unsigned offset;
165 struct flash_info *flash_info;
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800166 unsigned total_num_of_blocks;
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800167 unsigned next_ptr_start_adr = 0;
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700168 unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -0700169 unsigned base_addr;
170 unsigned char slot;
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800171 int i;
172
173 dprintf(INFO, "target_init()\n");
174
Chandan Uddarajua0d26dd2009-12-13 01:04:38 -0800175#if (!ENABLE_NANDWRITE)
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -0800176 keys_init();
177 keypad_init();
Chandan Uddarajua0d26dd2009-12-13 01:04:38 -0800178#endif
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800179
David Ng183a7422009-12-07 14:55:21 -0800180 if (target_is_emmc_boot())
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -0700181 {
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -0700182 /* Trying Slot 2 first */
183 slot = 2;
184 base_addr = mmc_sdc_base[slot-1];
185 if(mmc_boot_main(slot, base_addr))
186 {
187 /* Trying Slot 4 next */
188 slot = 4;
189 base_addr = mmc_sdc_base[slot-1];
190 if(mmc_boot_main(slot, base_addr))
191 {
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700192 dprintf(CRITICAL, "mmc init failed!");
193 ASSERT(0);
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -0700194 }
195 }
David Ng183a7422009-12-07 14:55:21 -0800196 return;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -0700197 }
David Ng183a7422009-12-07 14:55:21 -0800198
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800199 ptable_init(&flash_ptable);
200 smem_ptable_init();
201
202 flash_init();
203 flash_info = flash_get_info();
204 ASSERT(flash_info);
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700205 enable_interleave_mode(target_is_interleaved_mode());
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800206
207 offset = smem_get_apps_flash_start();
208 if (offset == 0xffffffff)
209 while(1);
210
Chandan Uddaraju40605112010-08-09 14:25:08 -0700211 total_num_of_blocks = flash_info->num_blocks;
212 blocks_per_1MB = (1 << 20) / (flash_info->block_size);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800213
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800214 for (i = 0; i < num_parts; i++) {
215 struct ptentry *ptn = &board_part_list[i];
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700216 unsigned len = ((ptn->length) * blocks_per_1MB);
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800217
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700218 if(ptn->start != 0)
219 ASSERT(ptn->start == DIFF_START_ADDR);
220
221 ptn->start = next_ptr_start_adr;
222
223 if(ptn->length == VARIABLE_LENGTH)
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800224 {
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800225 unsigned length_for_prt = 0;
226 unsigned j;
227 for (j = i+1; j < num_parts; j++)
228 {
229 struct ptentry *temp_ptn = &board_part_list[j];
230 ASSERT(temp_ptn->length != VARIABLE_LENGTH);
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700231 length_for_prt += ((temp_ptn->length) * blocks_per_1MB);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800232 }
Shashank Mittal04059b72011-03-15 20:37:28 -0700233 len = total_num_of_blocks - (offset + ptn->start + length_for_prt);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800234 ASSERT(len >= 0);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800235 }
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700236 next_ptr_start_adr = ptn->start + len;
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700237 if(target_is_interleaved_mode()) {
238 ptable_add(&flash_ptable, ptn->name, offset + (ptn->start / 2),
239 (len / 2), ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
240 }
241 else {
242 ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
243 len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
244 }
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800245 }
246
Shashank Mittal8e49dec2010-03-01 15:19:04 -0800247 smem_add_modem_partitions(&flash_ptable);
248
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800249 ptable_dump(&flash_ptable);
250 flash_set_ptable(&flash_ptable);
251}
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800252
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800253int target_platform_version(void)
254{
255 return platform_version;
256}
257
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700258int target_is_msm8x55(void)
259{
260 if ((target_msm_id == MSM8255_ID) ||
Ajay Dudani65077982010-09-12 23:55:10 -0700261 (target_msm_id == MSM8655_ID) ||
262 (target_msm_id == APQ8055_ID))
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700263 return 1;
264 else
265 return 0;
266}
267
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800268unsigned board_machtype(void)
269{
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800270 struct smem_board_info_v4 board_info_v4;
271 unsigned int board_info_len = 0;
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800272 enum platform platform_type = 0;
273 unsigned smem_status;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800274 unsigned format = 0;
275 if(hw_platform_type != -1)
276 return hw_platform_type;
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800277
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800278 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
279 &format, sizeof(format), 0);
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700280 if(!smem_status)
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800281 {
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700282 if ((format == 3) || (format == 4))
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800283 {
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700284 if (format == 4)
285 board_info_len = sizeof(board_info_v4);
286 else
287 board_info_len = sizeof(board_info_v4.board_info_v3);
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800288
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700289 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
290 &board_info_v4, board_info_len);
291 if(!smem_status)
292 {
293 if(format == 4)
294 platform_version = board_info_v4.platform_version;
295
296 platform_type = board_info_v4.board_info_v3.hw_platform;
297 target_msm_id = board_info_v4.board_info_v3.msm_id;
298 switch (platform_type)
299 {
300 case HW_PLATFORM_SURF:
301 hw_platform_type = ((target_is_msm8x55()) ?
302 LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break;
303 case HW_PLATFORM_FFA:
304 hw_platform_type = ((target_is_msm8x55()) ?
305 LINUX_MACHTYPE_8x55_FFA : LINUX_MACHTYPE_7x30_FFA); break;
306 case HW_PLATFORM_FLUID:
307 hw_platform_type = LINUX_MACHTYPE_7x30_FLUID; break;
Chandan Uddarajud0864592010-05-21 18:22:00 -0700308 case HW_PLATFORM_SVLTE:
309 hw_platform_type = LINUX_MACHTYPE_8x55_SVLTE_FFA; break;
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700310 default:
311 hw_platform_type = ((target_is_msm8x55()) ?
312 LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break;
313 }
314 return hw_platform_type;
315 }
316 }
317 }
318 hw_platform_type = LINUX_MACHTYPE_7x30_SURF;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800319 return hw_platform_type;
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800320}
David Ng183a7422009-12-07 14:55:21 -0800321
Chandan Uddaraju94183c02010-01-15 15:13:59 -0800322void reboot_device(unsigned reboot_reason)
323{
324 reboot(reboot_reason);
325}
326
Chandan Uddarajude85d3f2010-01-05 16:32:33 -0800327unsigned check_reboot_mode(void)
328{
Chandan Uddaraju94183c02010-01-15 15:13:59 -0800329 unsigned mode[2] = {0, 0};
330 unsigned int mode_len = sizeof(mode);
331 unsigned smem_status;
332
333 smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE,
334 &mode, mode_len );
335 if(smem_status)
336 {
337 dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n");
338 return 0;
339 }
340 return mode[0];
Chandan Uddarajude85d3f2010-01-05 16:32:33 -0800341}
Chandan Uddaraju7f5b9012010-02-06 16:37:48 -0800342
Wentao Xu530c2d82010-11-09 18:30:18 -0500343static unsigned target_check_power_on_reason(void)
344{
345 unsigned power_on_status = 0;
346 unsigned int status_len = sizeof(power_on_status);
347 unsigned smem_status;
348
349 smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,
350 &power_on_status, status_len);
351
Subbaraman Narayanamurthybd2424e2011-03-29 15:29:21 -0700352 if (smem_status)
Wentao Xu530c2d82010-11-09 18:30:18 -0500353 {
354 dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n");
355 }
356
357 return power_on_status;
358}
359
360unsigned target_pause_for_battery_charge(void)
361{
362 //check power on reason only for fluid devices
363 if( hw_platform_type != LINUX_MACHTYPE_7x30_FLUID)
364 return 0;
365
366 if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG)
367 return 1;
368 return 0;
369}
370
Chandan Uddaraju7f5b9012010-02-06 16:37:48 -0800371void target_battery_charging_enable(unsigned enable, unsigned disconnect)
372{
373}
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800374
375#if _EMMC_BOOT
376void target_serialno(unsigned char *buf)
377{
378 unsigned int serialno;
379 serialno = mmc_get_psn();
380 sprintf(buf,"%x",serialno);
381}
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -0700382
383int emmc_recovery_init(void)
384{
385 int rc;
386 rc = _emmc_recovery_init();
387 return rc;
388}
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800389#endif