blob: e7b7961d3d56be0f4fe58997314dc4ee9eb72354 [file] [log] [blame]
Kinson Chik18e36332011-08-15 10:07:28 -07001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
Aparna Mallavarapu7784b582013-03-20 18:34:36 +05305 * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
Kinson Chik18e36332011-08-15 10:07:28 -07006 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google, Inc. nor the names of its contributors
17 * may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <reg.h>
35#include <debug.h>
36#include <lib/ptable.h>
37#include <dev/flash.h>
Kinson Chik53f8d322011-08-30 13:39:38 -070038#include <dev/pm8921.h>
39#include <dev/ssbi.h>
Kinson Chik175e8472011-09-06 17:01:26 -070040#include <string.h>
Kinson Chik18e36332011-08-15 10:07:28 -070041#include <smem.h>
42#include <gsbi.h>
43#include <platform/iomap.h>
44#include <platform.h>
45
46#define MDM9X15_CDP 3675
47#define MDM9X15_MTP 3681
Ameya Thakur7f31b8d2012-03-30 14:50:35 -070048#define LINUX_MACHTYPE MDM9X15_CDP
49
50#define RECOVERY_MODE 0x77665502
51#define FOTA_COOKIE 0x64645343
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -070052#define FOTA_PARTITION 5
53#define DSP3_PARTITION 5
Kinson Chik18e36332011-08-15 10:07:28 -070054
Kinson Chik18e36332011-08-15 10:07:28 -070055static struct ptable flash_ptable;
56unsigned hw_platform = 0;
57unsigned target_msm_id = 0;
58
Kinson Chik175e8472011-09-06 17:01:26 -070059/* Partition names for fastboot flash */
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -070060static char *apps_ptn_names[] = { "aboot", "boot", "cache", "misc", "recovery", "fota",
Deepa Dinamani13e32c42012-03-12 14:34:17 -070061 "recoveryfs", "system", "userdata" };
Ajay Dudanib01e5062011-12-03 23:23:42 -080062
Kinson Chik175e8472011-09-06 17:01:26 -070063/* Partitions should be in this order */
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -070064static char *ptable_ptn_names[] = { "APPSBL", "APPS", "CACHE", "MISC", "RECOVERY",
Deepa Dinamani13e32c42012-03-12 14:34:17 -070065 "FOTA", "RECOVERYFS", "SYSTEM", "USERDATA" };
Ajay Dudanib01e5062011-12-03 23:23:42 -080066
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -070067static unsigned ptn_name_count = 9;
Deepa Dinamani13e32c42012-03-12 14:34:17 -070068
69/* Apps partition flags to detect the presence of FOTA partitions.
70 * Initially, assume that the FOTA partitions are absent.
71 */
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -070072static unsigned int apps_ptn_flag[] = {1, 1, 0, 0, 0, 0, 0, 1, 1};
73/* Modem partition flags to detect the presence of DSP3 partitions.
74 * Initially, assume that the DSP3 partition is absent.
75 * The order of modem partiotions -
76 * "mibib", "sbl2", "rpm", "efs2", "dsp1", "dsp3", "dsp2"
77 */
78static unsigned int modem_ptn_flag[] = {1, 1, 1, 1, 1, 0, 1};
Deepa Dinamani13e32c42012-03-12 14:34:17 -070079
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -070080static unsigned modem_ptn_count = 7;
Kinson Chik175e8472011-09-06 17:01:26 -070081
Kinson Chik18e36332011-08-15 10:07:28 -070082static const uint8_t uart_gsbi_id = GSBI_ID_4;
83
Kinson Chik53f8d322011-08-30 13:39:38 -070084static pm8921_dev_t pmic;
85
Kinson Chik18e36332011-08-15 10:07:28 -070086void smem_ptable_init(void);
Kinson Chik18e36332011-08-15 10:07:28 -070087extern void reboot(unsigned reboot_reason);
Kinson Chik175e8472011-09-06 17:01:26 -070088void update_ptable_apps_partitions(void);
89void update_ptable_modem_partitions(void);
Neeti Desai7e5380b2012-04-27 11:12:16 -070090void update_ptable_reorder(void);
Kinson Chik0b1c8162011-08-31 16:31:57 -070091extern int fake_key_get_state(void);
Kinson Chik18e36332011-08-15 10:07:28 -070092
93void target_init(void)
94{
Kinson Chik18e36332011-08-15 10:07:28 -070095 struct flash_info *flash_info;
Kinson Chik18e36332011-08-15 10:07:28 -070096
97 dprintf(INFO, "target_init()\n");
Kinson Chik53f8d322011-08-30 13:39:38 -070098
99 /* Initialize PMIC driver */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800100 pmic.read = (pm8921_read_func) & pa1_ssbi2_read_bytes;
101 pmic.write = (pm8921_write_func) & pa1_ssbi2_write_bytes;
Kinson Chik53f8d322011-08-30 13:39:38 -0700102
103 pm8921_init(&pmic);
104
Kinson Chik18e36332011-08-15 10:07:28 -0700105 ptable_init(&flash_ptable);
106 smem_ptable_init();
107
108 flash_init();
109 flash_info = flash_get_info();
110 ASSERT(flash_info);
111
Kinson Chik18e36332011-08-15 10:07:28 -0700112 smem_add_modem_partitions(&flash_ptable);
113
Kinson Chik175e8472011-09-06 17:01:26 -0700114 /* Update the naming for apps partitions and type */
115 update_ptable_apps_partitions();
116
117 /* Update modem partitions to lower case for fastboot */
118 update_ptable_modem_partitions();
119
Kinson Chik18e36332011-08-15 10:07:28 -0700120 ptable_dump(&flash_ptable);
Neeti Desai7e5380b2012-04-27 11:12:16 -0700121
122 /* Reorder the partition table */
123 update_ptable_reorder();
124
125 flash_set_ptable( &flash_ptable);
Kinson Chik18e36332011-08-15 10:07:28 -0700126}
127
Ameya Thakur7f31b8d2012-03-30 14:50:35 -0700128
129static int read_from_flash(struct ptentry* ptn, int offset, int size, void *dest)
130{
131 void *buffer = NULL;
132 unsigned page_size = flash_page_size();
133 unsigned page_mask = page_size - 1;
134 int read_size = (size + page_mask) & (~page_mask);
135
136 buffer = malloc(read_size);
137 if(!buffer){
138 dprintf(CRITICAL, "ERROR : Malloc failed for read_from_flash \n");
139 return -1;
140 }
141 if(flash_read(ptn, offset, buffer, read_size)){
142 dprintf(CRITICAL, "ERROR : Flash read failed \n");
143 return -1;
144 }
145 memcpy(dest, buffer, size);
146 free(buffer);
147 return 0;
148}
149
150
151static unsigned int get_fota_cookie(void)
152{
153 struct ptentry *ptn;
154 struct ptable *ptable;
155 unsigned int cookie = 0;
156
157 ptable = flash_get_ptable();
158 if (ptable == NULL) {
159 dprintf(CRITICAL, "ERROR: Partition table not found\n");
160 return 0;
161 }
162
163 ptn = ptable_find(ptable, "fota");
164 if (ptn == NULL) {
165 dprintf(CRITICAL, "ERROR: No fota partition found\n");
166 return 0;
167 }
168 if(read_from_flash(ptn, 0, sizeof(unsigned int), &cookie) == -1){
169 dprintf(CRITICAL,"ERROR: failed to read fota cookie from flash");
170 return 0;
171 }
172 return cookie;
173}
174
Deepa Dinamani0e372682011-12-19 17:09:00 -0800175unsigned check_reboot_mode(void)
176{
177 unsigned restart_reason = 0;
Ameya Thakur7f31b8d2012-03-30 14:50:35 -0700178 unsigned int cookie = 0;
Deepa Dinamani0e372682011-12-19 17:09:00 -0800179
180 /* Read reboot reason and scrub it */
181 restart_reason = readl(RESTART_REASON_ADDR);
182 writel(0x00, RESTART_REASON_ADDR);
183
Ameya Thakur7f31b8d2012-03-30 14:50:35 -0700184 /* SMEM value is not relied upon on power shutdown.
185 * Check either of SMEM or FOTA update cookie is set.
186 * Check fota cookie only when fota partition is available on target
187 */
188 if (apps_ptn_flag[FOTA_PARTITION] == 1) {
189 cookie = get_fota_cookie();
190 if (cookie == FOTA_COOKIE)
191 return RECOVERY_MODE;
192 }
Deepa Dinamani0e372682011-12-19 17:09:00 -0800193 return restart_reason;
194}
195
Kinson Chik18e36332011-08-15 10:07:28 -0700196void board_info(void)
197{
198 struct smem_board_info_v4 board_info_v4;
Aparna Mallavarapu7784b582013-03-20 18:34:36 +0530199 struct smem_board_info_v7 board_info_v7;
Kinson Chik18e36332011-08-15 10:07:28 -0700200 unsigned int board_info_len = 0;
201 unsigned smem_status;
202 unsigned format = 0;
203 unsigned id = 0;
204
205 if (hw_platform && target_msm_id)
206 return;
207
208 hw_platform = MDM9X15_CDP;
209 target_msm_id = MDM9600;
210
211 smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800212 &format, sizeof(format), 0);
213 if (!smem_status) {
214 if (format == 4) {
Kinson Chik18e36332011-08-15 10:07:28 -0700215 board_info_len = sizeof(board_info_v4);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800216 smem_status =
217 smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
218 &board_info_v4,
219 board_info_len);
220 if (!smem_status) {
Kinson Chik18e36332011-08-15 10:07:28 -0700221 id = board_info_v4.board_info_v3.hw_platform;
222 target_msm_id =
Ajay Dudanib01e5062011-12-03 23:23:42 -0800223 board_info_v4.board_info_v3.msm_id;
Kinson Chik18e36332011-08-15 10:07:28 -0700224 }
Aparna Mallavarapu7784b582013-03-20 18:34:36 +0530225 } else if (format == 7) {
226 board_info_len = sizeof(board_info_v7);
227 smem_status =
228 smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
229 &board_info_v7,
230 board_info_len);
231 if (!smem_status) {
232 id = board_info_v7.board_info_v3.hw_platform;
233 target_msm_id =
234 board_info_v7.board_info_v3.msm_id;
235 }
236 } else
237 ASSERT(0);
Kinson Chik18e36332011-08-15 10:07:28 -0700238 }
239 return;
240}
241
242unsigned board_machtype(void)
243{
244 board_info();
245 return hw_platform;
246}
247
248void reboot_device(unsigned reboot_reason)
249{
Deepa Dinamani0e372682011-12-19 17:09:00 -0800250 /* Write reboot reason */
251 writel(reboot_reason, RESTART_REASON_ADDR);
252
Kinson Chik53f8d322011-08-30 13:39:38 -0700253 /* Actually reset the chip */
254 pm8921_config_reset_pwr_off(1);
255 writel(0, MSM_PSHOLD_CTL_SU);
256 mdelay(10000);
257
Ajay Dudanib01e5062011-12-03 23:23:42 -0800258 dprintf(CRITICAL, "Rebooting failed\n");
Kinson Chik18e36332011-08-15 10:07:28 -0700259 return;
260}
261
262uint8_t target_uart_gsbi(void)
263{
264 return uart_gsbi_id;
265}
266
Kinson Chik0b1c8162011-08-31 16:31:57 -0700267/*
268 * Return 1 to trigger to fastboot
269 */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800270int fastboot_trigger(void)
271{
Kinson Chik0b1c8162011-08-31 16:31:57 -0700272 int ret;
273 ret = fake_key_get_state();
Deepa Dinamani7519fd52012-02-08 20:32:17 -0800274 /* Want to trigger when dip switch is on */
275 return (ret);
Kinson Chik18e36332011-08-15 10:07:28 -0700276}
Kinson Chik175e8472011-09-06 17:01:26 -0700277
278void update_ptable_modem_partitions(void)
279{
280 uint32_t ptn_index, i = 0;
281 uint32_t name_size;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800282 struct ptentry *ptentry_ptr = flash_ptable.parts;
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -0700283 struct ptentry *dsp3_ptn;
Kinson Chik175e8472011-09-06 17:01:26 -0700284
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -0700285 dsp3_ptn = ptable_find(&flash_ptable, "DSP3");
286
287 /* Check for DSP3 partition and its size */
288 if (dsp3_ptn != NULL)
289 if (dsp3_ptn->length > 0)
290 modem_ptn_flag[DSP3_PARTITION] = 1;
291
292 for (ptn_index = 0; ptn_index < modem_ptn_count; ptn_index++)
293 {
294 if (!modem_ptn_flag[ptn_index])
295 continue;
296
Kinson Chik175e8472011-09-06 17:01:26 -0700297 name_size = strlen(ptentry_ptr[ptn_index].name);
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -0700298 for (i = 0; i < name_size; i++)
299 {
Kinson Chik175e8472011-09-06 17:01:26 -0700300 ptentry_ptr[ptn_index].name[i] =
Deepa Dinamaniaf1bfb32012-06-05 19:59:58 -0700301 tolower(ptentry_ptr[ptn_index].name[i]);
Kinson Chik175e8472011-09-06 17:01:26 -0700302 }
Neeti Desaif52e2212012-09-26 17:22:06 -0700303 ptentry_ptr[ptn_index].type = TYPE_APPS_PARTITION;
Kinson Chik175e8472011-09-06 17:01:26 -0700304 }
305}
306
307void update_ptable_apps_partitions(void)
308{
309 uint32_t ptn_index, name_index = 0;
310 uint32_t end = 0xffffffff;
311 uint32_t name_size = strlen(ptable_ptn_names[name_index]);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800312 struct ptentry *ptentry_ptr = flash_ptable.parts;
Deepa Dinamani13e32c42012-03-12 14:34:17 -0700313 struct ptentry *fota_ptn;
314 unsigned int size;
315
316 fota_ptn = ptable_find(&flash_ptable, "FOTA");
317
318 /* Check for FOTA partitions and their size */
319 if (fota_ptn != NULL) {
320 if (fota_ptn->length > 0) {
321 /* FOTA partitions are present */
322 apps_ptn_flag[2] = 1;
323 apps_ptn_flag[3] = 1;
324 apps_ptn_flag[4] = 1;
325 apps_ptn_flag[5] = 1;
326 apps_ptn_flag[6] = 1;
327
328 }
329 }
Kinson Chik175e8472011-09-06 17:01:26 -0700330
Ajay Dudanib01e5062011-12-03 23:23:42 -0800331 for (ptn_index = 0; ptentry_ptr[ptn_index].start != end; ptn_index++) {
Kinson Chik175e8472011-09-06 17:01:26 -0700332 if (!(strncmp(ptentry_ptr[ptn_index].name,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800333 ptable_ptn_names[name_index], name_size))) {
Kinson Chik175e8472011-09-06 17:01:26 -0700334 name_size = strlen(apps_ptn_names[name_index]);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800335 name_size++; /* For null termination */
Kinson Chik175e8472011-09-06 17:01:26 -0700336
337 /* Update the partition names to something familiar */
338 if (name_size <= MAX_PTENTRY_NAME)
339 strncpy(ptentry_ptr[ptn_index].name,
340 apps_ptn_names[name_index], name_size);
341
342 /* Aboot uses modem page layout, leave aboot ptn */
343 if (name_index != 0)
344 ptentry_ptr[ptn_index].type =
Ajay Dudanib01e5062011-12-03 23:23:42 -0800345 TYPE_APPS_PARTITION;
Kinson Chik175e8472011-09-06 17:01:26 -0700346
Deepa Dinamani13e32c42012-03-12 14:34:17 -0700347 /* Check for valid partitions
348 * according to the apps_ptn_flag
349 */
350 do {
351 /* Don't go out of bounds */
352 name_index++;
353 if (name_index >= ptn_name_count)
354 goto ptn_name_update_done;
355 name_size =
356 strlen(ptable_ptn_names[name_index]);
357 } while (!apps_ptn_flag[name_index]);
Kinson Chik175e8472011-09-06 17:01:26 -0700358 }
359 }
Kinson Chik8480e3d2011-10-11 15:07:47 -0700360
Deepa Dinamani13e32c42012-03-12 14:34:17 -0700361ptn_name_update_done:
Kinson Chik8480e3d2011-10-11 15:07:47 -0700362 /* Update the end to be actual end for grow partition */
363 ptn_index--;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800364 for (; ptentry_ptr[ptn_index].length != end; ptn_index++) {
365 };
Kinson Chik8480e3d2011-10-11 15:07:47 -0700366
367 /* If SMEM ptable is updated already then don't manually update this */
368 if (ptentry_ptr[ptn_index].start != end)
369 ptentry_ptr[ptn_index].length =
Ajay Dudanib01e5062011-12-03 23:23:42 -0800370 ((struct flash_info *)flash_get_info())->num_blocks -
371 ptentry_ptr[ptn_index].start;
Kinson Chik175e8472011-09-06 17:01:26 -0700372}
Neeti Desai7e5380b2012-04-27 11:12:16 -0700373
374void update_ptable_reorder(void)
375{
376 int boot_index;
377 struct ptentry boot_ptn;
378
379 boot_index = ptable_get_index(&flash_ptable, "boot");
380 if(boot_index == -1) {
381 dprintf (CRITICAL, "ERROR: Boot Partition not found. \n");
382 return;
383 }
384 boot_ptn = flash_ptable.parts[boot_index] ;
385 flash_ptable.parts[boot_index] = flash_ptable.parts[0];
386 flash_ptable.parts[0] = boot_ptn;
387}