blob: 5f765173a48eb0a3b589adcf49169c42f0238850 [file] [log] [blame]
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +05301/* Copyright (c) 2015, 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 <reg.h>
32#include <target.h>
33#include <platform.h>
34#include <uart_dm.h>
35#include <mmc.h>
36#include <platform/gpio.h>
37#include <dev/keys.h>
38#include <spmi_v2.h>
39#include <pm8x41.h>
40#include <board.h>
41#include <baseband.h>
42#include <hsusb.h>
43#include <scm.h>
44#include <platform/gpio.h>
45#include <platform/gpio.h>
46#include <platform/irqs.h>
47#include <platform/clock.h>
48#include <crypto5_wrapper.h>
49#include <partition_parser.h>
50#include <stdlib.h>
51
52#if LONG_PRESS_POWER_ON
53#include <shutdown_detect.h>
54#endif
55
56#define PMIC_ARB_CHANNEL_NUM 0
57#define PMIC_ARB_OWNER_ID 0
58#define TLMM_VOL_UP_BTN_GPIO 85
59
60#define FASTBOOT_MODE 0x77665500
61#define PON_SOFT_RB_SPARE 0x88F
62
63static uint32_t mmc_sdc_base[] =
64 { MSM_SDC1_BASE, MSM_SDC2_BASE };
65
66
67void target_early_init(void)
68{
69#if WITH_DEBUG_UART
70 uart_dm_init(1, 0, BLSP1_UART1_BASE);
71#endif
72}
73
74void target_mmc_caps(struct mmc_host *host)
75{
76 host->caps.ddr_mode = 0;
77 host->caps.hs200_mode = 0;
78 host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
79 host->caps.hs_clk_rate = MMC_CLK_50MHZ;
80}
81
82/* Return 1 if vol_up pressed */
83static int target_volume_up()
84{
85 uint8_t status = 0;
86
87 gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
88
89 /* Wait for the gpio config to take effect - debounce time */
90 thread_sleep(10);
91
92 /* Get status of GPIO */
93 status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
94
95 /* Active high signal. */
96 return status;
97}
98
99/* Return 1 if vol_down pressed */
100uint32_t target_volume_down()
101{
102 /* Volume down button tied in with PMIC RESIN. */
103 return pm8x41_resin_status();
104}
105
106static void target_keystatus()
107{
108 keys_init();
109
110 if(target_volume_down())
111 keys_post_event(KEY_VOLUMEDOWN, 1);
112
113 if(target_volume_up())
114 keys_post_event(KEY_VOLUMEUP, 1);
115}
116
117/* Configure PMIC and Drop PS_HOLD for shutdown */
118void shutdown_device()
119{
120 dprintf(CRITICAL, "Going down for shutdown.\n");
121
122 /* Configure PMIC for shutdown */
123 pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
124
125 /* Drop PS_HOLD for MSM */
126 writel(0x00, MPM2_MPM_PS_HOLD);
127
128 mdelay(5000);
129
130 dprintf(CRITICAL, "shutdown failed\n");
131
132 ASSERT(0);
133}
134
135
136void target_init(void)
137{
138 uint32_t base_addr;
139 uint8_t slot;
140
141 dprintf(INFO, "target_init()\n");
142
143 spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
144
145 target_keystatus();
146
147 /* Trying Slot 1*/
148 slot = 1;
149 base_addr = mmc_sdc_base[slot - 1];
150 if (mmc_boot_main(slot, base_addr)) {
151 /* Trying Slot 2 next */
152 slot = 2;
153 base_addr = mmc_sdc_base[slot - 1];
154 if (mmc_boot_main(slot, base_addr)) {
155 dprintf(CRITICAL, "mmc init failed!");
156 ASSERT(0);
157 }
158 }
159#if LONG_PRESS_POWER_ON
160 shutdown_detect();
161#endif
162}
163
164void target_serialno(unsigned char *buf)
165{
166 uint32_t serialno;
167 if (target_is_emmc_boot()) {
168 serialno = mmc_get_psn();
169 snprintf((char *)buf, 13, "%x", serialno);
170 }
171}
172
173unsigned board_machtype(void)
174{
175}
176
177int set_download_mode(enum dload_mode mode)
178{
179 int ret = 0;
180 ret = scm_dload_mode(mode);
181
182 pm8x41_clear_pmic_watchdog();
183
184 return ret;
185}
186
187int emmc_recovery_init(void)
188{
189 return _emmc_recovery_init();
190}
191
192unsigned target_pause_for_battery_charge(void)
193{
194 uint8_t pon_reason = pm8x41_get_pon_reason();
195 uint8_t is_cold_boot = pm8x41_get_is_cold_boot();
196 dprintf(INFO, "%s : pon_reason is %d cold_boot:%d\n", __func__,
197 pon_reason, is_cold_boot);
198 /* In case of fastboot reboot,adb reboot or if we see the power key
199 * pressed we do not want go into charger mode.
200 * fastboot reboot is warm boot with PON hard reset bit not set
201 * adb reboot is a cold boot with PON hard reset bit set
202 */
203 if (is_cold_boot &&
204 (!(pon_reason & HARD_RST)) &&
205 (!(pon_reason & KPDPWR_N)) &&
206 ((pon_reason & USB_CHG) || (pon_reason & DC_CHG) || (pon_reason & CBLPWR_N)))
207 return 1;
208 else
209 return 0;
210}
211
212/* UTMI MUX configuration to connect PHY to SNPS controller:
213 * Configure primary HS phy mux to use UTMI interface
214 * (connected to usb30 controller).
215 */
216static void tcsr_hs_phy_mux_configure(void)
217{
218 uint32_t reg;
219
220 reg = readl(USB2_PHY_SEL);
221
222 writel(reg | 0x1, USB2_PHY_SEL);
223}
224
225/* configure hs phy mux if using dwc controller */
226void target_usb_phy_mux_configure(void)
227{
228 if(!strcmp(target_usb_controller(), "dwc"))
229 {
230 tcsr_hs_phy_mux_configure();
231 }
232}
233
234/* Initialize target specific USB handlers */
235target_usb_iface_t* target_usb30_init()
236{
237 target_usb_iface_t *t_usb_iface;
238
239 t_usb_iface = calloc(1, sizeof(target_usb_iface_t));
240 ASSERT(t_usb_iface);
241
242 t_usb_iface->mux_config = target_usb_phy_mux_configure;
243 //t_usb_iface->clock_init = clock_usb30_init;
244
245 return t_usb_iface;
246}
247
248/* identify the usb controller to be used for the target */
249const char * target_usb_controller()
250{
251 return "dwc";
252}