blob: 8bfc791a8cb4b546ba8381d835781275b97ebe4a [file] [log] [blame]
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +05301/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <platform/iomap.h>
31#include <platform/irqs.h>
32#include <platform/gpio.h>
33#include <reg.h>
34#include <target.h>
35#include <platform.h>
36#include <dload_util.h>
37#include <uart_dm.h>
38#include <mmc.h>
39#include <spmi.h>
40#include <board.h>
41#include <smem.h>
42#include <baseband.h>
43#include <dev/keys.h>
44#include <crypto5_wrapper.h>
45#include <hsusb.h>
46#include <clock.h>
47#include <partition_parser.h>
48#include <scm.h>
49#include <platform/clock.h>
50#include <platform/gpio.h>
51#include <stdlib.h>
52
53extern bool target_use_signed_kernel(void);
54static void set_sdc_power_ctrl();
55
56static unsigned int target_id;
57
58#if MMC_SDHCI_SUPPORT
59struct mmc_device *dev;
60#endif
61
62#define PMIC_ARB_CHANNEL_NUM 0
63#define PMIC_ARB_OWNER_ID 0
64
65#define WDOG_DEBUG_DISABLE_BIT 17
66
67#define CE_INSTANCE 2
68#define CE_EE 1
69#define CE_FIFO_SIZE 64
70#define CE_READ_PIPE 3
71#define CE_WRITE_PIPE 2
72#define CE_READ_PIPE_LOCK_GRP 0
73#define CE_WRITE_PIPE_LOCK_GRP 0
74#define CE_ARRAY_SIZE 20
75
76#ifdef SSD_ENABLE
77#define SSD_CE_INSTANCE_1 1
78#define SSD_PARTITION_SIZE 8192
79#endif
80
81#define FASTBOOT_MODE 0x77665500
82
83#define BOARD_SOC_VERSION1(soc_rev) (soc_rev >= 0x10000 && soc_rev < 0x20000)
84
85#if MMC_SDHCI_SUPPORT
86static uint32_t mmc_sdhci_base[] =
87 { MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
88#endif
89
90static uint32_t mmc_sdc_base[] =
91 { MSM_SDC1_BASE, MSM_SDC2_BASE };
92
93static uint32_t mmc_sdc_pwrctl_irq[] =
94 { SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
95
96void target_early_init(void)
97{
98#if WITH_DEBUG_UART
99 uart_dm_init(9, 0, BLSP2_UART3_BASE);
100#endif
101}
102
103/* Return 1 if vol_up pressed */
104static int target_volume_up()
105{
106 return 0;
107}
108
109/* Return 1 if vol_down pressed */
110uint32_t target_volume_down()
111{
112 return 0;
113}
114
115static void target_keystatus()
116{
117 keys_init();
118
119 if (target_volume_down())
120 keys_post_event(KEY_VOLUMEDOWN, 1);
121
122 if (target_volume_up())
123 keys_post_event(KEY_VOLUMEUP, 1);
124}
125
126/* Set up params for h/w CE. */
127void target_crypto_init_params()
128{
129 struct crypto_init_params ce_params;
130
131 /* Set up base addresses and instance. */
132 ce_params.crypto_instance = CE_INSTANCE;
133 ce_params.crypto_base = MSM_CE2_BASE;
134 ce_params.bam_base = MSM_CE2_BAM_BASE;
135
136 /* Set up BAM config. */
137 ce_params.bam_ee = CE_EE;
138 ce_params.pipes.read_pipe = CE_READ_PIPE;
139 ce_params.pipes.write_pipe = CE_WRITE_PIPE;
140 ce_params.pipes.read_pipe_grp = CE_READ_PIPE_LOCK_GRP;
141 ce_params.pipes.write_pipe_grp = CE_WRITE_PIPE_LOCK_GRP;
142
143 /* Assign buffer sizes. */
144 ce_params.num_ce = CE_ARRAY_SIZE;
145 ce_params.read_fifo_size = CE_FIFO_SIZE;
146 ce_params.write_fifo_size = CE_FIFO_SIZE;
147
148 /* BAM is initialized by TZ for this platform.
149 * Do not do it again as the initialization address space
150 * is locked.
151 */
152 ce_params.do_bam_init = 0;
153
154 crypto_init_params(&ce_params);
155}
156
157crypto_engine_type board_ce_type(void)
158{
159 return CRYPTO_ENGINE_TYPE_HW;
160}
161
162#if MMC_SDHCI_SUPPORT
163static void target_mmc_sdhci_init()
164{
165 struct mmc_config_data config = {0};
166
167 config.bus_width = DATA_BUS_WIDTH_8BIT;
168 config.max_clk_rate = MMC_CLK_200MHZ;
169
170 /* Trying Slot 1*/
171 config.slot = 1;
172 config.sdhc_base = mmc_sdhci_base[config.slot - 1];
173 config.pwrctl_base = mmc_sdc_base[config.slot - 1];
174 config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
175
176 if (!(dev = mmc_init(&config))) {
177 /* Trying Slot 2 next */
178 config.slot = 2;
179 config.sdhc_base = mmc_sdhci_base[config.slot - 1];
180 config.pwrctl_base = mmc_sdc_base[config.slot - 1];
181 config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
182
183 if (!(dev = mmc_init(&config))) {
184 dprintf(CRITICAL, "mmc init failed!");
185 ASSERT(0);
186 }
187 }
188
189 /*
190 * MMC initialization is complete, read the partition table info
191 */
192 if (partition_read_table()) {
193 dprintf(CRITICAL, "Error reading the partition table info\n");
194 ASSERT(0);
195 }
196}
197
198struct mmc_device *target_mmc_device()
199{
200 return dev;
201}
202
203#else
204
205static void target_mmc_mci_init()
206{
207 uint32_t base_addr;
208 uint8_t slot;
209
210 /* Trying Slot 1 */
211 slot = 1;
212 base_addr = mmc_sdc_base[slot - 1];
213
214 if (mmc_boot_main(slot, base_addr))
215 {
216 /* Trying Slot 2 next */
217 slot = 2;
218 base_addr = mmc_sdc_base[slot - 1];
219 if (mmc_boot_main(slot, base_addr)) {
220 dprintf(CRITICAL, "mmc init failed!");
221 ASSERT(0);
222 }
223 }
224}
225
226/*
227 * Function to set the capabilities for the host
228 */
229void target_mmc_caps(struct mmc_host *host)
230{
231 host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
232 host->caps.ddr_mode = 1;
233 host->caps.hs200_mode = 1;
234 host->caps.hs_clk_rate = MMC_CLK_96MHZ;
235}
236
237#endif
238
239void target_init(void)
240{
241 dprintf(INFO, "target_init()\n");
242
243 target_keystatus();
244
245 if (target_use_signed_kernel())
246 target_crypto_init_params();
247
248 /*
249 * Set drive strength & pull ctrl for
250 * emmc
251 */
252 set_sdc_power_ctrl();
253
254#if MMC_SDHCI_SUPPORT
255 target_mmc_sdhci_init();
256#else
257 target_mmc_mci_init();
258#endif
259}
260
261unsigned board_machtype(void)
262{
263 return target_id;
264}
265
266/* Do any target specific intialization needed before entering fastboot mode */
267#ifdef SSD_ENABLE
268static void ssd_load_keystore_from_emmc()
269{
270 uint64_t ptn = 0;
271 int index = -1;
272 uint32_t size = SSD_PARTITION_SIZE;
273 int ret = -1;
274
275 uint32_t *buffer = (uint32_t *)memalign(CACHE_LINE,
276 ROUNDUP(SSD_PARTITION_SIZE, CACHE_LINE));
277
278 if (!buffer) {
279 dprintf(CRITICAL, "Error Allocating memory for SSD buffer\n");
280 ASSERT(0);
281 }
282
283 index = partition_get_index("ssd");
284
285 ptn = partition_get_offset(index);
286 if(ptn == 0){
287 dprintf(CRITICAL,"ERROR: ssd parition not found");
288 return;
289 }
290
291 if(mmc_read(ptn, buffer, size)){
292 dprintf(CRITICAL,"ERROR:Cannot read data\n");
293 return;
294 }
295
296 ret = scm_protect_keystore((uint32_t *)&buffer[0],size);
297 if(ret != 0)
298 dprintf(CRITICAL,"ERROR: scm_protect_keystore Failed");
299
300 free(buffer);
301}
302#endif
303
304void target_fastboot_init(void)
305{
306#ifdef SSD_ENABLE
307 clock_ce_enable(SSD_CE_INSTANCE_1);
308 ssd_load_keystore_from_emmc();
309#endif
310}
311
312/* Detect the target type */
313void target_detect(struct board_data *board)
314{
315 board->target = LINUX_MACHTYPE_UNKNOWN;
316}
317
318/* Detect the modem type */
319void target_baseband_detect(struct board_data *board)
320{
321 uint32_t platform;
322 uint32_t platform_subtype;
323
324 platform = board->platform;
325 platform_subtype = board->platform_subtype;
326
327 /*
328 * Look for platform subtype if present, else
329 * check for platform type to decide on the
330 * baseband type
331 */
332 switch (platform_subtype) {
333 case HW_PLATFORM_SUBTYPE_UNKNOWN:
334 break;
335 default:
336 dprintf(CRITICAL, "Platform Subtype : %u is not supported\n",platform_subtype);
337 ASSERT(0);
338 };
339
340 switch (platform) {
341 case FSM9900:
342 board->baseband = BASEBAND_MSM;
343 break;
344 default:
345 dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
346 ASSERT(0);
347 };
348}
349
350unsigned target_baseband()
351{
352 return board_baseband();
353}
354
355void target_serialno(unsigned char *buf)
356{
357 unsigned int serialno;
358 if (target_is_emmc_boot()) {
359 serialno = mmc_get_psn();
360 snprintf((char *)buf, 13, "%x", serialno);
361 }
362}
363
364unsigned check_reboot_mode(void)
365{
366 uint32_t restart_reason = 0;
367 uint32_t restart_reason_addr;
368
369 restart_reason_addr = RESTART_REASON_ADDR;
370
371 /* Read reboot reason and scrub it */
372 restart_reason = readl(restart_reason_addr);
373 writel(0x00, restart_reason_addr);
374
375 return restart_reason;
376}
377
378void reboot_device(unsigned reboot_reason)
379{
380 /* Write the reboot reason */
381 writel(reboot_reason, RESTART_REASON_ADDR);
382
383 /* Disable Watchdog Debug.
384 * Required becuase of a H/W bug which causes the system to
385 * reset partially even for non watchdog resets.
386 */
387 writel(readl(GCC_WDOG_DEBUG) & ~(1 << WDOG_DEBUG_DISABLE_BIT), GCC_WDOG_DEBUG);
388
389 dsb();
390
391 /* Wait until the write takes effect. */
392 while(readl(GCC_WDOG_DEBUG) & (1 << WDOG_DEBUG_DISABLE_BIT));
393
394 /* Drop PS_HOLD for MSM */
395 writel(0x00, MPM2_MPM_PS_HOLD);
396
397 mdelay(5000);
398
399 dprintf(CRITICAL, "Rebooting failed\n");
400}
401
402int set_download_mode(enum dload_mode mode)
403{
404 dload_util_write_cookie(mode == NORMAL_DLOAD ?
405 DLOAD_MODE_ADDR_V2 : EMERGENCY_DLOAD_MODE_ADDR_V2, mode);
406
407 return 0;
408}
409
410/* Check if MSM needs VBUS mimic for USB */
411static int target_needs_vbus_mimic()
412{
413 return 0;
414}
415
416/* Do target specific usb initialization */
417void target_usb_init(void)
418{
419}
420
421/* Returns 1 if target supports continuous splash screen. */
422int target_cont_splash_screen()
423{
424 return 0;
425}
426
427unsigned target_pause_for_battery_charge(void)
428{
429 return 0;
430}
431
432void target_uninit(void)
433{
434#if MMC_SDHCI_SUPPORT
435 mmc_put_card_to_sleep(dev);
436#else
437 mmc_put_card_to_sleep();
438#endif
439#ifdef SSD_ENABLE
440 clock_ce_disable(SSD_CE_INSTANCE_1);
441#endif
442}
443
444void shutdown_device()
445{
446 dprintf(CRITICAL, "Going down for shutdown.\n");
447
448 /* Drop PS_HOLD for MSM */
449 writel(0x00, MPM2_MPM_PS_HOLD);
450
451 mdelay(5000);
452
453 dprintf(CRITICAL, "Shutdown failed\n");
454}
455
456static void set_sdc_power_ctrl()
457{
458 /* Drive strength configs for sdc pins */
459 struct tlmm_cfgs sdc1_hdrv_cfg[] =
460 {
461 { SDC1_CLK_HDRV_CTL_OFF, TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK },
462 { SDC1_CMD_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
463 { SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
464 };
465
466 /* Pull configs for sdc pins */
467 struct tlmm_cfgs sdc1_pull_cfg[] =
468 {
469 { SDC1_CLK_PULL_CTL_OFF, TLMM_NO_PULL, TLMM_PULL_MASK },
470 { SDC1_CMD_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
471 { SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
472 };
473
474 /* Set the drive strength & pull control values */
475 tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
476 tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
477}
478
479int emmc_recovery_init(void)
480{
481 return _emmc_recovery_init();
482}
483
484void target_usb_stop(void)
485{
486}