blob: 35c19c8898632e06e9f3fc649ca3c9c1396b99ef [file] [log] [blame]
lijuang395b5e62015-11-19 17:39:44 +08001/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Channagoud Kadabi92db1122014-06-25 16:00:13 -04002 *
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 <platform/timer.h>
52#include <stdlib.h>
Channagoud Kadabi196b27c2015-01-19 13:53:38 -050053#include <string.h>
54#include <sdhci_msm.h>
Channagoud Kadabi92db1122014-06-25 16:00:13 -040055
56extern bool target_use_signed_kernel(void);
57static void set_sdc_power_ctrl();
58
59static unsigned int target_id;
60
61#if MMC_SDHCI_SUPPORT
62struct mmc_device *dev;
63#endif
64
65#define PMIC_ARB_CHANNEL_NUM 0
66#define PMIC_ARB_OWNER_ID 0
67
68#define WDOG_DEBUG_DISABLE_BIT 17
69
70#define CE_INSTANCE 2
71#define CE_EE 1
72#define CE_FIFO_SIZE 64
73#define CE_READ_PIPE 3
74#define CE_WRITE_PIPE 2
75#define CE_READ_PIPE_LOCK_GRP 0
76#define CE_WRITE_PIPE_LOCK_GRP 0
77#define CE_ARRAY_SIZE 20
78
79#define FASTBOOT_MODE 0x77665500
80
81#define BOARD_SOC_VERSION1(soc_rev) (soc_rev >= 0x10000 && soc_rev < 0x20000)
82
83#if MMC_SDHCI_SUPPORT
84static uint32_t mmc_sdhci_base[] =
85 { MSM_SDC1_SDHCI_BASE };
86static uint32_t mmc_sdc_pwrctl_irq[] =
87 { SDCC1_PWRCTL_IRQ };
88#endif
89
90static uint32_t mmc_sdc_base[] =
91 { MSM_SDC1_BASE };
92
93void target_early_init(void)
94{
95#if WITH_DEBUG_UART
Channagoud Kadabi196b27c2015-01-19 13:53:38 -050096 uart_dm_init(3, 0, BLSP1_UART3_BASE);
Channagoud Kadabi92db1122014-06-25 16:00:13 -040097#endif
98}
99
100/* Return 1 if vol_up pressed */
101static int target_volume_up()
102{
103 return 0;
104}
105
106/* Return 1 if vol_down pressed */
107uint32_t target_volume_down()
108{
109 return 0;
110}
111
112static void target_keystatus()
113{
114 keys_init();
115
116 if (target_volume_down())
117 keys_post_event(KEY_VOLUMEDOWN, 1);
118
119 if (target_volume_up())
120 keys_post_event(KEY_VOLUMEUP, 1);
121}
122
123/* Set up params for h/w CE. */
124void target_crypto_init_params()
125{
126 struct crypto_init_params ce_params;
127
128 /* Set up base addresses and instance. */
129 ce_params.crypto_instance = CE_INSTANCE;
130 ce_params.crypto_base = MSM_CE2_BASE;
131 ce_params.bam_base = MSM_CE2_BAM_BASE;
132
133 /* Set up BAM config. */
134 ce_params.bam_ee = CE_EE;
135 ce_params.pipes.read_pipe = CE_READ_PIPE;
136 ce_params.pipes.write_pipe = CE_WRITE_PIPE;
137 ce_params.pipes.read_pipe_grp = CE_READ_PIPE_LOCK_GRP;
138 ce_params.pipes.write_pipe_grp = CE_WRITE_PIPE_LOCK_GRP;
139
140 /* Assign buffer sizes. */
141 ce_params.num_ce = CE_ARRAY_SIZE;
142 ce_params.read_fifo_size = CE_FIFO_SIZE;
143 ce_params.write_fifo_size = CE_FIFO_SIZE;
144
145 /* BAM is initialized by TZ for this platform.
146 * Do not do it again as the initialization address space
147 * is locked.
148 */
149 ce_params.do_bam_init = 0;
150
151 crypto_init_params(&ce_params);
152}
153
154crypto_engine_type board_ce_type(void)
155{
156 return CRYPTO_ENGINE_TYPE_HW;
157}
158
159#if MMC_SDHCI_SUPPORT
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500160
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400161static void target_mmc_sdhci_init()
162{
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500163 static uint32_t mmc_clks[] = {
164 MMC_CLK_200MHZ, MMC_CLK_96MHZ, MMC_CLK_50MHZ };
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400165
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500166 struct mmc_config_data config;
167 unsigned int i;
168
169 memset(&config, 0, sizeof config);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400170 config.bus_width = DATA_BUS_WIDTH_8BIT;
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400171
172 /* Trying Slot 1*/
173 config.slot = 1;
174 config.sdhc_base = mmc_sdhci_base[config.slot - 1];
175 config.pwrctl_base = mmc_sdc_base[config.slot - 1];
176 config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500177 config.hs400_support = 0;
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400178
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500179 for (i = 0; i < ARRAY_SIZE(mmc_clks); ++i) {
180 config.max_clk_rate = mmc_clks[i];
181 dprintf(INFO, "SDHC Running at %u MHz\n",
182 config.max_clk_rate / 1000000);
183 dev = mmc_init(&config);
184 if (dev && partition_read_table() == 0)
185 return;
186 }
187
188 if (dev == NULL)
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400189 dprintf(CRITICAL, "mmc init failed!");
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500190 else
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400191 dprintf(CRITICAL, "Error reading the partition table info\n");
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500192 ASSERT(0);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400193}
194
195void *target_mmc_device()
196{
197 return (void *) dev;
198}
199
200#else
201
202static void target_mmc_mci_init()
203{
204 uint32_t base_addr;
205 uint8_t slot;
206
207 /* Trying Slot 1 */
208 slot = 1;
209 base_addr = mmc_sdc_base[slot - 1];
210
211 if (mmc_boot_main(slot, base_addr))
212 {
213 dprintf(CRITICAL, "mmc init failed!");
214 ASSERT(0);
215 }
216}
217
218/*
219 * Function to set the capabilities for the host
220 */
221void target_mmc_caps(struct mmc_host *host)
222{
223 host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
224 host->caps.ddr_mode = 0;
225 host->caps.hs200_mode = 1;
226 host->caps.hs_clk_rate = MMC_CLK_96MHZ;
227}
228
229#endif
230
231void target_init(void)
232{
233 dprintf(INFO, "target_init()\n");
234
235 target_keystatus();
236
237 if (target_use_signed_kernel())
238 target_crypto_init_params();
239
240 /*
241 * Set drive strength & pull ctrl for
242 * emmc
243 */
244 set_sdc_power_ctrl();
245
246#if MMC_SDHCI_SUPPORT
247 target_mmc_sdhci_init();
248#else
249 target_mmc_mci_init();
250#endif
251}
252
253unsigned board_machtype(void)
254{
255 return target_id;
256}
257
258void target_fastboot_init(void)
259{
260}
261
262/* Detect the target type */
263void target_detect(struct board_data *board)
264{
265 /* This property is filled as part of board.c */
266}
267
268/* Detect the modem type */
269void target_baseband_detect(struct board_data *board)
270{
271 uint32_t platform;
272 uint32_t platform_subtype;
273
274 platform = board->platform;
275 platform_subtype = board->platform_subtype;
276
277 /*
278 * Look for platform subtype if present, else
279 * check for platform type to decide on the
280 * baseband type
281 */
282 switch (platform_subtype) {
283 case HW_PLATFORM_SUBTYPE_UNKNOWN:
284 break;
285 default:
286 dprintf(CRITICAL, "Platform Subtype : %u is not supported\n",platform_subtype);
287 ASSERT(0);
288 };
289
290 switch (platform) {
Channagoud Kadabi6a8ec852015-02-19 14:59:14 -0500291 case FSM9008:
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400292 case FSM9010:
Channagoud Kadabi6a8ec852015-02-19 14:59:14 -0500293 case FSM9016:
294 case FSM9055:
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400295 board->baseband = BASEBAND_MSM;
296 break;
297 default:
298 dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
299 ASSERT(0);
300 };
301}
302
303unsigned target_baseband()
304{
305 return board_baseband();
306}
307
308void target_serialno(unsigned char *buf)
309{
310 unsigned int serialno;
311 if (target_is_emmc_boot()) {
312 serialno = mmc_get_psn();
313 snprintf((char *)buf, 13, "%x", serialno);
314 }
315}
316
317unsigned check_reboot_mode(void)
318{
319 uint32_t restart_reason = 0;
320 uint32_t restart_reason_addr;
321
Kranthikumar Kurapatifaadb712015-07-23 13:56:34 -0400322 restart_reason_addr = RESTART_REASON_ADDR_V2;
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400323
324 /* Read reboot reason and scrub it */
325 restart_reason = readl(restart_reason_addr);
326 writel(0x00, restart_reason_addr);
327
328 return restart_reason;
329}
330
lijuang395b5e62015-11-19 17:39:44 +0800331int set_download_mode(enum reboot_reason mode)
332{
333 if (mode == NORMAL_DLOAD || mode == EMERGENCY_DLOAD)
334 dload_util_write_cookie(mode == NORMAL_DLOAD ?
335 DLOAD_MODE_ADDR_V2 : EMERGENCY_DLOAD_MODE_ADDR_V2, mode);
336
337 return 0;
338}
339
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400340void reboot_device(unsigned reboot_reason)
341{
lijuang395b5e62015-11-19 17:39:44 +0800342 /* Set cookie for dload mode */
343 if(set_download_mode(reboot_reason)) {
344 dprintf(CRITICAL, "HALT: set_download_mode not supported\n");
345 return;
346 }
347
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400348 /* Write the reboot reason */
Kranthikumar Kurapatifaadb712015-07-23 13:56:34 -0400349 writel(reboot_reason, RESTART_REASON_ADDR_V2);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400350
351 /* Disable Watchdog Debug.
352 * Required becuase of a H/W bug which causes the system to
353 * reset partially even for non watchdog resets.
354 */
355 writel(readl(GCC_WDOG_DEBUG) & ~(1 << WDOG_DEBUG_DISABLE_BIT), GCC_WDOG_DEBUG);
356
357 dsb();
358
359 /* Wait until the write takes effect. */
360 while(readl(GCC_WDOG_DEBUG) & (1 << WDOG_DEBUG_DISABLE_BIT));
361
362 /* Drop PS_HOLD for MSM */
363 writel(0x00, MPM2_MPM_PS_HOLD);
364
365 mdelay(5000);
366
367 dprintf(CRITICAL, "Rebooting failed\n");
368}
369
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400370/* Returns 1 if target supports continuous splash screen. */
371int target_cont_splash_screen()
372{
373 return 0;
374}
375
376unsigned target_pause_for_battery_charge(void)
377{
378 return 0;
379}
380
381void target_uninit(void)
382{
383#if MMC_SDHCI_SUPPORT
384 mmc_put_card_to_sleep(dev);
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500385 sdhci_mode_disable(&dev->host);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400386#else
387 mmc_put_card_to_sleep();
388#endif
389}
390
391void shutdown_device()
392{
393 dprintf(CRITICAL, "Going down for shutdown.\n");
394
395 /* Drop PS_HOLD for MSM */
396 writel(0x00, MPM2_MPM_PS_HOLD);
397
398 mdelay(5000);
399
400 dprintf(CRITICAL, "Shutdown failed\n");
401}
402
403static void set_sdc_power_ctrl()
404{
405 /* Drive strength configs for sdc pins */
406 struct tlmm_cfgs sdc1_hdrv_cfg[] =
407 {
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500408 {
409 off: SDC1_CLK_HDRV_CTL_OFF,
410 val: TLMM_CUR_VAL_10MA,
411 mask: TLMM_HDRV_MASK
412 },
413 {
414 off: SDC1_CMD_HDRV_CTL_OFF,
415 val: TLMM_CUR_VAL_10MA,
416 mask: TLMM_HDRV_MASK
417 },
418 {
419 off: SDC1_DATA_HDRV_CTL_OFF,
420 val: TLMM_CUR_VAL_10MA,
421 mask: TLMM_HDRV_MASK
422 },
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400423 };
424
425 /* Pull configs for sdc pins */
426 struct tlmm_cfgs sdc1_pull_cfg[] =
427 {
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500428 {
429 off: SDC1_CLK_PULL_CTL_OFF,
430 val: TLMM_NO_PULL,
431 mask: TLMM_PULL_MASK
432 },
433 {
434 off: SDC1_CMD_PULL_CTL_OFF,
435 val: TLMM_PULL_UP,
436 mask: TLMM_PULL_MASK
437 },
438 {
439 off: SDC1_DATA_PULL_CTL_OFF,
440 val: TLMM_PULL_UP,
441 mask: TLMM_PULL_MASK
442 },
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400443 };
444
445 /* Set the drive strength & pull control values */
446 tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
447 tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
448}
449
450int emmc_recovery_init(void)
451{
452 extern int _emmc_recovery_init(void);
453
454 return _emmc_recovery_init();
455}
456
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500457#define USB30_QSCRATCH_GENERAL_CFG (MSM_USB30_QSCRATCH_BASE + 0x08)
458#define USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_SEL (1 << 0)
459#define USB30_QSCRATCH_GENERAL_CFG_PIPE3_PHYSTATUS_SW (1 << 3)
460#define USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_DIS (1 << 8)
461
462#define CM_DWC_USB2_USB_PHY_UTMI_CTRL5 (CM_DWC_USB2_CM_DWC_USB2_BASE + 0x74)
463#define CM_DWC_USB2_USB_PHY_HS_PHY_CTRL_COMMON0 (CM_DWC_USB2_CM_DWC_USB2_BASE + 0x78)
464#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X0 (CM_DWC_USB2_CM_DWC_USB2_BASE + 0x98)
465#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X1 (CM_DWC_USB2_CM_DWC_USB2_BASE + 0x9c)
466#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X2 (CM_DWC_USB2_CM_DWC_USB2_BASE + 0xa0)
467#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X3 (CM_DWC_USB2_CM_DWC_USB2_BASE + 0xa4)
468#define CM_DWC_USB2_USB_PHY_REFCLK_CTRL (CM_DWC_USB2_CM_DWC_USB2_BASE + 0xe8)
469
470void target_usb_phy_mux_configure(void)
471{
472}
473
474void target_usb_phy_init(void)
475{
476 uint32_t val;
477
478 /* Disable clock */
479 val = readl(USB30_QSCRATCH_GENERAL_CFG);
480 val |= USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_DIS;
481 writel(val, USB30_QSCRATCH_GENERAL_CFG);
482 mdelay(1);
483
484 /* Select UTMI instead of PIPE3 */
485 val |= USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_SEL;
486 writel(val, USB30_QSCRATCH_GENERAL_CFG);
487 val |= USB30_QSCRATCH_GENERAL_CFG_PIPE3_PHYSTATUS_SW;
488 writel(val, USB30_QSCRATCH_GENERAL_CFG);
489 mdelay(1);
490
491 /* Enable clock */
492 val &= ~USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_DIS;
493 writel(val, USB30_QSCRATCH_GENERAL_CFG);
494
495 /* Initialize HS PICO PHY */
496 writel(0xc4, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X0);
497 writel(0x88, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X1);
498 writel(0x11, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X2);
499 writel(0x03, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X3);
500
501 writel(0x02, CM_DWC_USB2_USB_PHY_UTMI_CTRL5);
502 mdelay(1);
503 writel(0x00, CM_DWC_USB2_USB_PHY_UTMI_CTRL5);
504
505 val = readl(CM_DWC_USB2_USB_PHY_REFCLK_CTRL);
506 val &= ~(7 << 1);
507 val |= (6 << 1);
508 writel(val, CM_DWC_USB2_USB_PHY_REFCLK_CTRL);
509
510 val = readl(CM_DWC_USB2_USB_PHY_HS_PHY_CTRL_COMMON0);
511 val &= ~(7 << 4);
512 val |= (7 << 4);
513 writel(val, CM_DWC_USB2_USB_PHY_HS_PHY_CTRL_COMMON0);
514}
515
516void target_usb_phy_reset(void)
517{
518}
519
520target_usb_iface_t* target_usb30_init()
521{
522 target_usb_iface_t *t_usb_iface;
523
524 t_usb_iface = calloc(1, sizeof(target_usb_iface_t));
525 ASSERT(t_usb_iface);
526
527 t_usb_iface->mux_config = target_usb_phy_mux_configure;
528 t_usb_iface->phy_init = target_usb_phy_init;
529 t_usb_iface->phy_reset = target_usb_phy_reset;
530 t_usb_iface->clock_init = clock_usb30_init;
531 t_usb_iface->vbus_override = 1;
532
533 return t_usb_iface;
534}
535
536/* identify the usb controller to be used for the target */
537const char * target_usb_controller()
538{
539 return "dwc";
540}
541
542/* configure hs phy mux if using dwc controller */
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400543void target_usb_stop(void)
544{
545}