blob: 371ad1ef23a289bfb9fb743d5eb10381c9ca8e30 [file] [log] [blame]
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
Shashank Mittal8e49dec2010-03-01 15:19:04 -08004 * Copyright (c) 2009-2010, 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>
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070041#include <platform/iomap.h>
Chandan Uddaraju885e4db2009-12-03 22:45:26 -080042
Chandan Uddarajud0864592010-05-21 18:22:00 -070043#define LINUX_MACHTYPE_7x30_SURF 1007016
44#define LINUX_MACHTYPE_7x30_FFA 1007017
45#define LINUX_MACHTYPE_7x30_FLUID 1007018
46#define LINUX_MACHTYPE_8x55_SURF 2768
47#define LINUX_MACHTYPE_8x55_FFA 2769
48#define LINUX_MACHTYPE_8x55_SVLTE_FFA 2863
49#define LINUX_MACHTYPE_8x55_SVLTE_SURF 2864
Chandan Uddarajuf759be32010-03-17 19:04:16 -070050
51#define MSM8255_ID 74
52#define MSM8655_ID 75
Ajay Dudani65077982010-09-12 23:55:10 -070053#define APQ8055_ID 85
Chandan Uddaraju885e4db2009-12-03 22:45:26 -080054
55//Enum values for 7x30 target platforms.
56enum platform
57{
58 HW_PLATFORM_UNKNOWN = 0,
59 HW_PLATFORM_SURF = 1,
60 HW_PLATFORM_FFA = 2,
61 HW_PLATFORM_FLUID = 3,
Chandan Uddarajud0864592010-05-21 18:22:00 -070062 HW_PLATFORM_SVLTE = 4,
Chandan Uddaraju885e4db2009-12-03 22:45:26 -080063 HW_PLATFORM_32BITS = 0x7FFFFFFF
64};
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080065
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080066#define VARIABLE_LENGTH 0x10101010
67#define DIFF_START_ADDR 0xF0F0F0F0
68#define NUM_PAGES_PER_BLOCK 0x40
69
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070070static unsigned mmc_sdc_base[] = { MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE};
71
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080072static struct ptable flash_ptable;
Chandan Uddaraju1434a602010-03-08 17:13:38 -080073static int hw_platform_type = -1;
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080074
75/* for these partitions, start will be offset by either what we get from
76 * smem, or from the above offset if smem is not useful. Also, we should
77 * probably have smem_ptable code populate our flash_ptable.
78 *
79 * When smem provides us with a full partition table, we can get rid of
80 * this altogether.
81 *
82 */
83static struct ptentry board_part_list[] = {
84 {
85 .start = 0,
Chandan Uddarajud56669f2010-04-19 22:15:06 -070086 .length = 5 /* In MB */,
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080087 .name = "boot",
88 },
89 {
Chandan Uddarajud56669f2010-04-19 22:15:06 -070090 .start = DIFF_START_ADDR,
David Ng3755bb82010-10-12 18:12:06 -070091 .length = 120 /* In MB */,
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -080092 .name = "system",
93 },
94 {
Chandan Uddarajud56669f2010-04-19 22:15:06 -070095 .start = DIFF_START_ADDR,
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -070096 .length = 30 /* In MB */,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -080097 .name = "cache",
Chandan Uddaraju94183c02010-01-15 15:13:59 -080098 },
99 {
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700100 .start = DIFF_START_ADDR,
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -0700101 .length = 1 /* In MB */,
102 .name = "misc",
103 },
104 {
105 .start = DIFF_START_ADDR,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800106 .length = VARIABLE_LENGTH,
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800107 .name = "userdata",
108 },
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800109 {
110 .start = DIFF_START_ADDR,
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700111 .length = 3 /* In MB */,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800112 .name = "persist",
113 },
114 {
115 .start = DIFF_START_ADDR,
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700116 .length = 5 /* In MB */,
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800117 .name = "recovery",
118 },
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800119};
120static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry);
121
122void smem_ptable_init(void);
123unsigned smem_get_apps_flash_start(void);
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700124unsigned smem_read_alloc_entry_offset(smem_mem_type_t, void *, int, int);
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800125
126void keypad_init(void);
127
David Ng183a7422009-12-07 14:55:21 -0800128static int emmc_boot = -1; /* set to uninitialized */
129int target_is_emmc_boot(void);
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800130static int platform_version = -1;
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700131static int target_msm_id = -1;
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700132static int interleaved_mode_enabled = -1;
133void enable_interleave_mode(int);
134
135int target_is_interleaved_mode(void)
136{
137 struct smem_board_info_v4 board_info_v4;
138 unsigned int board_info_len = 0;
139 unsigned smem_status;
140 char *build_type;
141 unsigned format = 0;
142
143 if (interleaved_mode_enabled != -1)
144 {
145 return interleaved_mode_enabled;
146 }
147
148 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
149 &format, sizeof(format), 0);
150 if(!smem_status)
151 {
152 if ((format == 3) || (format == 4))
153 {
154 if (format == 4)
155 board_info_len = sizeof(board_info_v4);
156 else
157 board_info_len = sizeof(board_info_v4.board_info_v3);
158
159 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
160 &board_info_v4, board_info_len);
161 if(!smem_status)
162 {
163 build_type = (char *)(board_info_v4.board_info_v3.build_id) + 9;
164
165 interleaved_mode_enabled = 0;
166
167 if (*build_type == 'C')
168 {
169 interleaved_mode_enabled = 1;
170 }
171 }
172 }
173 }
174
175 return interleaved_mode_enabled;
176}
David Ng183a7422009-12-07 14:55:21 -0800177
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800178void target_init(void)
179{
180 unsigned offset;
181 struct flash_info *flash_info;
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800182 unsigned total_num_of_blocks;
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800183 unsigned next_ptr_start_adr = 0;
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700184 unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -0700185 unsigned base_addr;
186 unsigned char slot;
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800187 int i;
188
189 dprintf(INFO, "target_init()\n");
190
Chandan Uddarajua0d26dd2009-12-13 01:04:38 -0800191#if (!ENABLE_NANDWRITE)
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -0800192 keys_init();
193 keypad_init();
Chandan Uddarajua0d26dd2009-12-13 01:04:38 -0800194#endif
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800195
David Ng183a7422009-12-07 14:55:21 -0800196 if (target_is_emmc_boot())
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -0700197 {
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -0700198 /* Trying Slot 2 first */
199 slot = 2;
200 base_addr = mmc_sdc_base[slot-1];
201 if(mmc_boot_main(slot, base_addr))
202 {
203 /* Trying Slot 4 next */
204 slot = 4;
205 base_addr = mmc_sdc_base[slot-1];
206 if(mmc_boot_main(slot, base_addr))
207 {
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700208 dprintf(CRITICAL, "mmc init failed!");
209 ASSERT(0);
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -0700210 }
211 }
David Ng183a7422009-12-07 14:55:21 -0800212 return;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -0700213 }
David Ng183a7422009-12-07 14:55:21 -0800214
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800215 ptable_init(&flash_ptable);
216 smem_ptable_init();
217
218 flash_init();
219 flash_info = flash_get_info();
220 ASSERT(flash_info);
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700221 enable_interleave_mode(target_is_interleaved_mode());
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800222
223 offset = smem_get_apps_flash_start();
224 if (offset == 0xffffffff)
225 while(1);
226
Chandan Uddaraju40605112010-08-09 14:25:08 -0700227 total_num_of_blocks = flash_info->num_blocks;
228 blocks_per_1MB = (1 << 20) / (flash_info->block_size);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800229
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800230 for (i = 0; i < num_parts; i++) {
231 struct ptentry *ptn = &board_part_list[i];
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700232 unsigned len = ((ptn->length) * blocks_per_1MB);
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800233
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700234 if(ptn->start != 0)
235 ASSERT(ptn->start == DIFF_START_ADDR);
236
237 ptn->start = next_ptr_start_adr;
238
239 if(ptn->length == VARIABLE_LENGTH)
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800240 {
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800241 unsigned length_for_prt = 0;
242 unsigned j;
243 for (j = i+1; j < num_parts; j++)
244 {
245 struct ptentry *temp_ptn = &board_part_list[j];
246 ASSERT(temp_ptn->length != VARIABLE_LENGTH);
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700247 length_for_prt += ((temp_ptn->length) * blocks_per_1MB);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800248 }
249 len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt);
250 ASSERT(len >= 0);
Chandan Uddaraju9e5ab962010-01-21 15:36:37 -0800251 }
Chandan Uddarajud56669f2010-04-19 22:15:06 -0700252 next_ptr_start_adr = ptn->start + len;
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700253 if(target_is_interleaved_mode()) {
254 ptable_add(&flash_ptable, ptn->name, offset + (ptn->start / 2),
255 (len / 2), ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
256 }
257 else {
258 ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
259 len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
260 }
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800261 }
262
Shashank Mittal8e49dec2010-03-01 15:19:04 -0800263 smem_add_modem_partitions(&flash_ptable);
264
Chandan Uddaraju8adde5a2009-11-17 11:31:28 -0800265 ptable_dump(&flash_ptable);
266 flash_set_ptable(&flash_ptable);
267}
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800268
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800269int target_platform_version(void)
270{
271 return platform_version;
272}
273
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700274int target_is_msm8x55(void)
275{
276 if ((target_msm_id == MSM8255_ID) ||
Ajay Dudani65077982010-09-12 23:55:10 -0700277 (target_msm_id == MSM8655_ID) ||
278 (target_msm_id == APQ8055_ID))
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700279 return 1;
280 else
281 return 0;
282}
283
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800284unsigned board_machtype(void)
285{
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800286 struct smem_board_info_v4 board_info_v4;
287 unsigned int board_info_len = 0;
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800288 enum platform platform_type = 0;
289 unsigned smem_status;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800290 unsigned format = 0;
291 if(hw_platform_type != -1)
292 return hw_platform_type;
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800293
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800294 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
295 &format, sizeof(format), 0);
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700296 if(!smem_status)
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800297 {
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700298 if ((format == 3) || (format == 4))
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800299 {
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700300 if (format == 4)
301 board_info_len = sizeof(board_info_v4);
302 else
303 board_info_len = sizeof(board_info_v4.board_info_v3);
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800304
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700305 smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
306 &board_info_v4, board_info_len);
307 if(!smem_status)
308 {
309 if(format == 4)
310 platform_version = board_info_v4.platform_version;
311
312 platform_type = board_info_v4.board_info_v3.hw_platform;
313 target_msm_id = board_info_v4.board_info_v3.msm_id;
314 switch (platform_type)
315 {
316 case HW_PLATFORM_SURF:
317 hw_platform_type = ((target_is_msm8x55()) ?
318 LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break;
319 case HW_PLATFORM_FFA:
320 hw_platform_type = ((target_is_msm8x55()) ?
321 LINUX_MACHTYPE_8x55_FFA : LINUX_MACHTYPE_7x30_FFA); break;
322 case HW_PLATFORM_FLUID:
323 hw_platform_type = LINUX_MACHTYPE_7x30_FLUID; break;
Chandan Uddarajud0864592010-05-21 18:22:00 -0700324 case HW_PLATFORM_SVLTE:
325 hw_platform_type = LINUX_MACHTYPE_8x55_SVLTE_FFA; break;
Chandan Uddarajuf759be32010-03-17 19:04:16 -0700326 default:
327 hw_platform_type = ((target_is_msm8x55()) ?
328 LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break;
329 }
330 return hw_platform_type;
331 }
332 }
333 }
334 hw_platform_type = LINUX_MACHTYPE_7x30_SURF;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800335 return hw_platform_type;
Chandan Uddaraju885e4db2009-12-03 22:45:26 -0800336}
David Ng183a7422009-12-07 14:55:21 -0800337
Chandan Uddaraju94183c02010-01-15 15:13:59 -0800338void reboot_device(unsigned reboot_reason)
339{
340 reboot(reboot_reason);
341}
342
Chandan Uddarajude85d3f2010-01-05 16:32:33 -0800343unsigned check_reboot_mode(void)
344{
Chandan Uddaraju94183c02010-01-15 15:13:59 -0800345 unsigned mode[2] = {0, 0};
346 unsigned int mode_len = sizeof(mode);
347 unsigned smem_status;
348
349 smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE,
350 &mode, mode_len );
351 if(smem_status)
352 {
353 dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n");
354 return 0;
355 }
356 return mode[0];
Chandan Uddarajude85d3f2010-01-05 16:32:33 -0800357}
Chandan Uddaraju7f5b9012010-02-06 16:37:48 -0800358
359void target_battery_charging_enable(unsigned enable, unsigned disconnect)
360{
361}