blob: 4c2b319720db218ac2185924af1445af74578b2b [file] [log] [blame]
lijuang395b5e62015-11-19 17:39:44 +08001/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +05302 *
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{
Channagoud Kadabi56e5bac2014-10-23 09:52:40 -0400165 static uint32_t mmc_clks[] = {
166 MMC_CLK_96MHZ, MMC_CLK_50MHZ };
167
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530168 struct mmc_config_data config = {0};
Channagoud Kadabi56e5bac2014-10-23 09:52:40 -0400169 int i;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530170
171 config.bus_width = DATA_BUS_WIDTH_8BIT;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530172
173 /* Trying Slot 1*/
174 config.slot = 1;
175 config.sdhc_base = mmc_sdhci_base[config.slot - 1];
176 config.pwrctl_base = mmc_sdc_base[config.slot - 1];
177 config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
Channagoud Kadabi56e5bac2014-10-23 09:52:40 -0400178 config.hs400_support = 0;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530179
Channagoud Kadabi56e5bac2014-10-23 09:52:40 -0400180 for (i = 0; i < ARRAY_SIZE(mmc_clks); ++i) {
181 config.max_clk_rate = mmc_clks[i];
182 dprintf(INFO, "SDHC Running at %u MHz\n",
183 config.max_clk_rate / 1000000);
184 dev = mmc_init(&config);
185 if (dev && partition_read_table() == 0)
186 return;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530187 }
188
Channagoud Kadabi56e5bac2014-10-23 09:52:40 -0400189 if (dev == NULL)
190 dprintf(CRITICAL, "mmc init failed!");
191 else
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530192 dprintf(CRITICAL, "Error reading the partition table info\n");
Channagoud Kadabi56e5bac2014-10-23 09:52:40 -0400193 ASSERT(0);
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530194}
195
Gururaj Rao044f49b2014-04-08 19:18:40 +0530196void *target_mmc_device()
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530197{
Gururaj Rao044f49b2014-04-08 19:18:40 +0530198 return (void *) dev;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530199}
200
201#else
202
203static void target_mmc_mci_init()
204{
205 uint32_t base_addr;
206 uint8_t slot;
207
208 /* Trying Slot 1 */
209 slot = 1;
210 base_addr = mmc_sdc_base[slot - 1];
211
212 if (mmc_boot_main(slot, base_addr))
213 {
214 /* Trying Slot 2 next */
215 slot = 2;
216 base_addr = mmc_sdc_base[slot - 1];
217 if (mmc_boot_main(slot, base_addr)) {
218 dprintf(CRITICAL, "mmc init failed!");
219 ASSERT(0);
220 }
221 }
222}
223
224/*
225 * Function to set the capabilities for the host
226 */
227void target_mmc_caps(struct mmc_host *host)
228{
229 host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
230 host->caps.ddr_mode = 1;
231 host->caps.hs200_mode = 1;
232 host->caps.hs_clk_rate = MMC_CLK_96MHZ;
233}
234
235#endif
236
237void target_init(void)
238{
239 dprintf(INFO, "target_init()\n");
240
241 target_keystatus();
242
243 if (target_use_signed_kernel())
244 target_crypto_init_params();
245
246 /*
247 * Set drive strength & pull ctrl for
248 * emmc
249 */
250 set_sdc_power_ctrl();
251
252#if MMC_SDHCI_SUPPORT
253 target_mmc_sdhci_init();
254#else
255 target_mmc_mci_init();
256#endif
257}
258
259unsigned board_machtype(void)
260{
261 return target_id;
262}
263
264/* Do any target specific intialization needed before entering fastboot mode */
265#ifdef SSD_ENABLE
266static void ssd_load_keystore_from_emmc()
267{
268 uint64_t ptn = 0;
269 int index = -1;
270 uint32_t size = SSD_PARTITION_SIZE;
271 int ret = -1;
272
273 uint32_t *buffer = (uint32_t *)memalign(CACHE_LINE,
274 ROUNDUP(SSD_PARTITION_SIZE, CACHE_LINE));
275
276 if (!buffer) {
277 dprintf(CRITICAL, "Error Allocating memory for SSD buffer\n");
278 ASSERT(0);
279 }
280
281 index = partition_get_index("ssd");
282
283 ptn = partition_get_offset(index);
284 if(ptn == 0){
285 dprintf(CRITICAL,"ERROR: ssd parition not found");
286 return;
287 }
288
289 if(mmc_read(ptn, buffer, size)){
290 dprintf(CRITICAL,"ERROR:Cannot read data\n");
291 return;
292 }
293
294 ret = scm_protect_keystore((uint32_t *)&buffer[0],size);
295 if(ret != 0)
296 dprintf(CRITICAL,"ERROR: scm_protect_keystore Failed");
297
298 free(buffer);
299}
300#endif
301
302void target_fastboot_init(void)
303{
304#ifdef SSD_ENABLE
305 clock_ce_enable(SSD_CE_INSTANCE_1);
306 ssd_load_keystore_from_emmc();
307#endif
308}
309
310/* Detect the target type */
311void target_detect(struct board_data *board)
312{
Channagoud Kadabib2881982014-02-11 15:39:59 -0800313 /* This property is filled as part of board.c */
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530314}
315
316/* Detect the modem type */
317void target_baseband_detect(struct board_data *board)
318{
319 uint32_t platform;
320 uint32_t platform_subtype;
321
322 platform = board->platform;
323 platform_subtype = board->platform_subtype;
324
325 /*
326 * Look for platform subtype if present, else
327 * check for platform type to decide on the
328 * baseband type
329 */
330 switch (platform_subtype) {
331 case HW_PLATFORM_SUBTYPE_UNKNOWN:
332 break;
333 default:
334 dprintf(CRITICAL, "Platform Subtype : %u is not supported\n",platform_subtype);
335 ASSERT(0);
336 };
337
338 switch (platform) {
339 case FSM9900:
V S Ramanjaneya Kumar Ta44a36a2013-12-03 13:53:48 +0530340 case FSM9905:
341 case FSM9910:
342 case FSM9915:
343 case FSM9950:
344 case FSM9955:
Channagoud Kadabi1c4d7a22015-02-11 11:21:36 -0500345 case FSM9916:
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530346 board->baseband = BASEBAND_MSM;
347 break;
348 default:
349 dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
350 ASSERT(0);
351 };
352}
353
354unsigned target_baseband()
355{
356 return board_baseband();
357}
358
359void target_serialno(unsigned char *buf)
360{
361 unsigned int serialno;
362 if (target_is_emmc_boot()) {
363 serialno = mmc_get_psn();
364 snprintf((char *)buf, 13, "%x", serialno);
365 }
366}
367
368unsigned check_reboot_mode(void)
369{
370 uint32_t restart_reason = 0;
371 uint32_t restart_reason_addr;
372
Channagoud Kadabi5ad51f82015-02-11 11:43:04 -0500373 restart_reason_addr = RESTART_REASON_ADDR_V2;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530374
375 /* Read reboot reason and scrub it */
376 restart_reason = readl(restart_reason_addr);
377 writel(0x00, restart_reason_addr);
378
379 return restart_reason;
380}
381
lijuang395b5e62015-11-19 17:39:44 +0800382int set_download_mode(enum reboot_reason mode)
383{
384 if (mode == NORMAL_DLOAD || mode == EMERGENCY_DLOAD)
385 dload_util_write_cookie(mode == NORMAL_DLOAD ?
386 DLOAD_MODE_ADDR_V2 : EMERGENCY_DLOAD_MODE_ADDR_V2, mode);
387
388 return 0;
389}
390
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530391void reboot_device(unsigned reboot_reason)
392{
lijuang395b5e62015-11-19 17:39:44 +0800393 /* Set cookie for dload mode */
394 if(set_download_mode(reboot_reason)) {
395 dprintf(CRITICAL, "HALT: set_download_mode not supported\n");
396 return;
397 }
398
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530399 /* Write the reboot reason */
Channagoud Kadabi5ad51f82015-02-11 11:43:04 -0500400 writel(reboot_reason, RESTART_REASON_ADDR_V2);
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530401
402 /* Disable Watchdog Debug.
403 * Required becuase of a H/W bug which causes the system to
404 * reset partially even for non watchdog resets.
405 */
406 writel(readl(GCC_WDOG_DEBUG) & ~(1 << WDOG_DEBUG_DISABLE_BIT), GCC_WDOG_DEBUG);
407
408 dsb();
409
410 /* Wait until the write takes effect. */
411 while(readl(GCC_WDOG_DEBUG) & (1 << WDOG_DEBUG_DISABLE_BIT));
412
413 /* Drop PS_HOLD for MSM */
414 writel(0x00, MPM2_MPM_PS_HOLD);
415
416 mdelay(5000);
417
418 dprintf(CRITICAL, "Rebooting failed\n");
419}
420
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530421/* Check if MSM needs VBUS mimic for USB */
422static int target_needs_vbus_mimic()
423{
V S Ramanjaneya Kumar Tc1945892013-08-27 11:39:53 +0530424 return 1;
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530425}
426
427/* Do target specific usb initialization */
428void target_usb_init(void)
429{
V S Ramanjaneya Kumar Tc1945892013-08-27 11:39:53 +0530430 uint32_t val;
431
432 if (target_needs_vbus_mimic()) {
433 /* Select and enable external configuration with USB PHY */
434 ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
435
436 /* Enable sess_vld */
437 val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
438 writel(val, USB_GENCONFIG_2);
439
440 /* Enable external vbus configuration in the LINK */
441 val = readl(USB_USBCMD);
442 val |= SESS_VLD_CTRL;
443 writel(val, USB_USBCMD);
444 }
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530445}
446
447/* Returns 1 if target supports continuous splash screen. */
448int target_cont_splash_screen()
449{
450 return 0;
451}
452
453unsigned target_pause_for_battery_charge(void)
454{
455 return 0;
456}
457
458void target_uninit(void)
459{
460#if MMC_SDHCI_SUPPORT
461 mmc_put_card_to_sleep(dev);
462#else
463 mmc_put_card_to_sleep();
464#endif
465#ifdef SSD_ENABLE
466 clock_ce_disable(SSD_CE_INSTANCE_1);
467#endif
468}
469
470void shutdown_device()
471{
472 dprintf(CRITICAL, "Going down for shutdown.\n");
473
474 /* Drop PS_HOLD for MSM */
475 writel(0x00, MPM2_MPM_PS_HOLD);
476
477 mdelay(5000);
478
479 dprintf(CRITICAL, "Shutdown failed\n");
480}
481
482static void set_sdc_power_ctrl()
483{
484 /* Drive strength configs for sdc pins */
485 struct tlmm_cfgs sdc1_hdrv_cfg[] =
486 {
Channagoud Kadabi61528192014-06-09 15:34:17 -0700487 { SDC1_CLK_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +0530488 { SDC1_CMD_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
489 { SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
490 };
491
492 /* Pull configs for sdc pins */
493 struct tlmm_cfgs sdc1_pull_cfg[] =
494 {
495 { SDC1_CLK_PULL_CTL_OFF, TLMM_NO_PULL, TLMM_PULL_MASK },
496 { SDC1_CMD_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
497 { SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
498 };
499
500 /* Set the drive strength & pull control values */
501 tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
502 tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
503}
504
505int emmc_recovery_init(void)
506{
507 return _emmc_recovery_init();
508}
509
510void target_usb_stop(void)
511{
512}