blob: 8a80a8c4f3b458a4e1bc0fb186f1b03a8d8ad8a3 [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>
P.V. Phani Kumara053a322015-08-13 18:36:05 +053040#include <pm8x41_hw.h>
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053041#include <board.h>
42#include <baseband.h>
43#include <hsusb.h>
44#include <scm.h>
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053045#include <platform/irqs.h>
46#include <platform/clock.h>
P.V. Phani Kumara053a322015-08-13 18:36:05 +053047#include <platform/timer.h>
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053048#include <crypto5_wrapper.h>
49#include <partition_parser.h>
50#include <stdlib.h>
P.V. Phani Kumara053a322015-08-13 18:36:05 +053051#include <rpm-smd.h>
52#include <spmi.h>
53#include <sdhci_msm.h>
54#include <clock.h>
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053055
56#if LONG_PRESS_POWER_ON
57#include <shutdown_detect.h>
58#endif
59
60#define PMIC_ARB_CHANNEL_NUM 0
61#define PMIC_ARB_OWNER_ID 0
62#define TLMM_VOL_UP_BTN_GPIO 85
63
64#define FASTBOOT_MODE 0x77665500
65#define PON_SOFT_RB_SPARE 0x88F
66
P.V. Phani Kumara053a322015-08-13 18:36:05 +053067struct mmc_device *dev;
68
69static uint32_t mmc_pwrctl_base[] =
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053070 { MSM_SDC1_BASE, MSM_SDC2_BASE };
71
P.V. Phani Kumara053a322015-08-13 18:36:05 +053072static uint32_t mmc_sdhci_base[] =
73 { MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
74
75static uint32_t mmc_sdc_pwrctl_irq[] =
76 { SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053077
78void target_early_init(void)
79{
80#if WITH_DEBUG_UART
81 uart_dm_init(1, 0, BLSP1_UART1_BASE);
82#endif
83}
84
P.V. Phani Kumara053a322015-08-13 18:36:05 +053085static void set_sdc_power_ctrl()
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053086{
P.V. Phani Kumara053a322015-08-13 18:36:05 +053087 /* Drive strength configs for sdc pins */
88 struct tlmm_cfgs sdc1_hdrv_cfg[] =
89 {
90 { SDC1_CLK_HDRV_CTL_OFF, TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, 0},
91 { SDC1_CMD_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, 0},
92 { SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK , 0},
93 };
94
95 /* Pull configs for sdc pins */
96 struct tlmm_cfgs sdc1_pull_cfg[] =
97 {
98 { SDC1_CLK_PULL_CTL_OFF, TLMM_NO_PULL, TLMM_PULL_MASK, 0},
99 { SDC1_CMD_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK, 0},
100 { SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK, 0},
101 };
102
103 struct tlmm_cfgs sdc1_rclk_cfg[] =
104 {
105 { SDC1_RCLK_PULL_CTL_OFF, TLMM_PULL_DOWN, TLMM_PULL_MASK, 0},
106 };
107
108 /* Set the drive strength & pull control values */
109 tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
110 tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
111 tlmm_set_pull_ctrl(sdc1_rclk_cfg, ARRAY_SIZE(sdc1_rclk_cfg));
112}
113
114void target_sdc_init()
115{
116 struct mmc_config_data config;
117
118 /* Set drive strength & pull ctrl values */
119 set_sdc_power_ctrl();
120
121 config.slot = MMC_SLOT;
122 config.bus_width = DATA_BUS_WIDTH_8BIT;
123 config.max_clk_rate = MMC_CLK_192MHZ;
124 config.sdhc_base = mmc_sdhci_base[config.slot - 1];
125 config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
126 config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
127 config.hs400_support = 1;
128
129 if (!(dev = mmc_init(&config))) {
130 /* Try different config. values */
131 config.max_clk_rate = MMC_CLK_200MHZ;
132 config.sdhc_base = mmc_sdhci_base[config.slot - 1];
133 config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
134 config.pwr_irq = mmc_sdc_pwrctl_irq[config.slot - 1];
135 config.hs400_support = 0;
136
137 if (!(dev = mmc_init(&config))) {
138 dprintf(CRITICAL, "mmc init failed!");
139 ASSERT(0);
140 }
141 }
142}
143
144void *target_mmc_device()
145{
146 return (void *) dev;
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530147}
148
149/* Return 1 if vol_up pressed */
150static int target_volume_up()
151{
152 uint8_t status = 0;
153
154 gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
155
156 /* Wait for the gpio config to take effect - debounce time */
157 thread_sleep(10);
158
159 /* Get status of GPIO */
160 status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
161
162 /* Active high signal. */
163 return status;
164}
165
166/* Return 1 if vol_down pressed */
167uint32_t target_volume_down()
168{
169 /* Volume down button tied in with PMIC RESIN. */
170 return pm8x41_resin_status();
171}
172
173static void target_keystatus()
174{
175 keys_init();
176
177 if(target_volume_down())
178 keys_post_event(KEY_VOLUMEDOWN, 1);
179
180 if(target_volume_up())
181 keys_post_event(KEY_VOLUMEUP, 1);
182}
183
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530184void target_init(void)
185{
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530186 dprintf(INFO, "target_init()\n");
187
188 spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
189
190 target_keystatus();
191
P.V. Phani Kumara053a322015-08-13 18:36:05 +0530192 target_sdc_init();
193 if (partition_read_table())
194 {
195 dprintf(CRITICAL, "Error reading the partition table info\n");
196 ASSERT(0);
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530197 }
P.V. Phani Kumara053a322015-08-13 18:36:05 +0530198
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530199#if LONG_PRESS_POWER_ON
200 shutdown_detect();
201#endif
202}
203
204void target_serialno(unsigned char *buf)
205{
206 uint32_t serialno;
207 if (target_is_emmc_boot()) {
208 serialno = mmc_get_psn();
209 snprintf((char *)buf, 13, "%x", serialno);
210 }
211}
212
213unsigned board_machtype(void)
214{
P.V. Phani Kumara053a322015-08-13 18:36:05 +0530215 return LINUX_MACHTYPE_UNKNOWN;
216}
217
218/* Detect the target type */
219void target_detect(struct board_data *board)
220{
221 /* This is already filled as part of board.c */
222}
223
224void target_baseband_detect(struct board_data *board)
225{
226 uint32_t platform;
227
228 platform = board->platform;
229
230 switch(platform) {
231 case MSMTITANIUM:
232 board->baseband = BASEBAND_MSM;
233 break;
234 default:
235 dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
236 ASSERT(0);
237 };
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530238}
239
240int set_download_mode(enum dload_mode mode)
241{
242 int ret = 0;
243 ret = scm_dload_mode(mode);
244
245 pm8x41_clear_pmic_watchdog();
246
247 return ret;
248}
249
250int emmc_recovery_init(void)
251{
252 return _emmc_recovery_init();
253}
254
255unsigned target_pause_for_battery_charge(void)
256{
257 uint8_t pon_reason = pm8x41_get_pon_reason();
258 uint8_t is_cold_boot = pm8x41_get_is_cold_boot();
259 dprintf(INFO, "%s : pon_reason is %d cold_boot:%d\n", __func__,
260 pon_reason, is_cold_boot);
261 /* In case of fastboot reboot,adb reboot or if we see the power key
262 * pressed we do not want go into charger mode.
263 * fastboot reboot is warm boot with PON hard reset bit not set
264 * adb reboot is a cold boot with PON hard reset bit set
265 */
266 if (is_cold_boot &&
267 (!(pon_reason & HARD_RST)) &&
268 (!(pon_reason & KPDPWR_N)) &&
269 ((pon_reason & USB_CHG) || (pon_reason & DC_CHG) || (pon_reason & CBLPWR_N)))
270 return 1;
271 else
272 return 0;
273}
274
275/* UTMI MUX configuration to connect PHY to SNPS controller:
276 * Configure primary HS phy mux to use UTMI interface
277 * (connected to usb30 controller).
278 */
279static void tcsr_hs_phy_mux_configure(void)
280{
281 uint32_t reg;
282
283 reg = readl(USB2_PHY_SEL);
284
285 writel(reg | 0x1, USB2_PHY_SEL);
286}
287
288/* configure hs phy mux if using dwc controller */
289void target_usb_phy_mux_configure(void)
290{
291 if(!strcmp(target_usb_controller(), "dwc"))
292 {
293 tcsr_hs_phy_mux_configure();
294 }
295}
296
297/* Initialize target specific USB handlers */
298target_usb_iface_t* target_usb30_init()
299{
300 target_usb_iface_t *t_usb_iface;
301
302 t_usb_iface = calloc(1, sizeof(target_usb_iface_t));
303 ASSERT(t_usb_iface);
304
305 t_usb_iface->mux_config = target_usb_phy_mux_configure;
306 //t_usb_iface->clock_init = clock_usb30_init;
307
308 return t_usb_iface;
309}
310
311/* identify the usb controller to be used for the target */
312const char * target_usb_controller()
313{
314 return "dwc";
315}
P.V. Phani Kumara053a322015-08-13 18:36:05 +0530316
317
318crypto_engine_type board_ce_type(void)
319{
320 return CRYPTO_ENGINE_TYPE_HW;
321}
322
323
324void pmic_reset_configure(uint8_t reset_type)
325{
326 pm8x41_reset_configure(reset_type);
327}