blob: 3692770bc7431034022b14b9b97aa74fb3a425fe [file] [log] [blame]
Terence Hampson2e1705f2012-04-11 19:55:29 -04001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -08002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/platform_device.h>
17#include <linux/bootmem.h>
18#include <asm/mach-types.h>
19#include <asm/mach/mmc.h>
20#include <mach/msm_bus_board.h>
21#include <mach/board.h>
22#include <mach/gpio.h>
23#include <mach/gpiomux.h>
24#include "devices.h"
Stepan Moskovchenko5a83dba2011-12-05 17:30:17 -080025#include "board-8960.h"
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -080026
27/* MSM8960 has 5 SDCC controllers */
28enum sdcc_controllers {
29 SDCC1,
30 SDCC2,
31 SDCC3,
32 SDCC4,
33 SDCC5,
34 MAX_SDCC_CONTROLLER
35};
36
37/* All SDCC controllers require VDD/VCC voltage */
38static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
39 /* SDCC1 : eMMC card connected */
40 [SDCC1] = {
41 .name = "sdc_vdd",
42 .high_vol_level = 2950000,
43 .low_vol_level = 2950000,
44 .always_on = 1,
45 .lpm_sup = 1,
46 .lpm_uA = 9000,
47 .hpm_uA = 200000, /* 200mA */
48 },
Pratibhasagar V57c808e2012-01-12 13:47:30 +053049 /* SDCC2 : SDIO slot connected */
50 [SDCC2] = {
51 .name = "sdc_vdd",
52 .high_vol_level = 1800000,
53 .low_vol_level = 1800000,
54 .always_on = 1,
55 .lpm_sup = 1,
56 .lpm_uA = 9000,
57 .hpm_uA = 200000, /* 200mA */
58 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -080059 /* SDCC3 : External card slot connected */
60 [SDCC3] = {
61 .name = "sdc_vdd",
62 .high_vol_level = 2950000,
63 .low_vol_level = 2950000,
64 .hpm_uA = 600000, /* 600mA */
65 }
66};
67
68/* Only slots having eMMC card will require VCCQ voltage */
69static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
70 /* SDCC1 : eMMC card connected */
71 [SDCC1] = {
72 .name = "sdc_vccq",
73 .always_on = 1,
74 .high_vol_level = 1800000,
75 .low_vol_level = 1800000,
76 .hpm_uA = 200000, /* 200mA */
77 }
78};
79
80/* All SDCC controllers may require voting for VDD PAD voltage */
81static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
82 /* SDCC3 : External card slot connected */
83 [SDCC3] = {
84 .name = "sdc_vddp",
85 .high_vol_level = 2950000,
86 .low_vol_level = 1850000,
87 .always_on = 1,
88 .lpm_sup = 1,
89 /* Max. Active current required is 16 mA */
90 .hpm_uA = 16000,
91 /*
92 * Sleep current required is ~300 uA. But min. vote can be
93 * in terms of mA (min. 1 mA). So let's vote for 2 mA
94 * during sleep.
95 */
96 .lpm_uA = 2000,
97 }
98};
99
100static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
101 /* SDCC1 : eMMC card connected */
102 [SDCC1] = {
103 .vdd_data = &mmc_vdd_reg_data[SDCC1],
104 .vccq_data = &mmc_vccq_reg_data[SDCC1],
105 },
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530106 /* SDCC2 : SDIO card slot connected */
107 [SDCC2] = {
108 .vdd_data = &mmc_vdd_reg_data[SDCC2],
109 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800110 /* SDCC3 : External card slot connected */
111 [SDCC3] = {
112 .vdd_data = &mmc_vdd_reg_data[SDCC3],
113 .vddp_data = &mmc_vddp_reg_data[SDCC3],
114 }
115};
116
117/* SDC1 pad data */
118static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
119 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
120 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
121 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
122};
123
124static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
125 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
126 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
127 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
128};
129
130static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
131 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
132 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
133 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
134};
135
136static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
137 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
Subhash Jadavani32a43982012-01-20 16:51:06 +0530138 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
139 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800140};
141
142/* SDC3 pad data */
143static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
144 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
145 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
146 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
147};
148
149static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
150 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
151 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
152 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
153};
154
155static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
156 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
157 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
158 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
159};
160
161static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
162 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
163 /*
164 * SDC3 CMD line should be PULLed UP otherwise fluid platform will
165 * see transitions (1 -> 0 and 0 -> 1) on card detection line,
166 * which would result in false card detection interrupts.
167 */
168 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
169 /*
170 * Keeping DATA lines status to PULL UP will make sure that
171 * there is no current leak during sleep if external pull up
172 * is connected to DATA lines.
173 */
174 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
175};
176
177static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
178 [SDCC1] = {
179 .on = sdc1_pad_pull_on_cfg,
180 .off = sdc1_pad_pull_off_cfg,
181 .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
182 },
183 [SDCC3] = {
184 .on = sdc3_pad_pull_on_cfg,
185 .off = sdc3_pad_pull_off_cfg,
186 .size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
187 },
188};
189
190static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
191 [SDCC1] = {
192 .on = sdc1_pad_drv_on_cfg,
193 .off = sdc1_pad_drv_off_cfg,
194 .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
195 },
196 [SDCC3] = {
197 .on = sdc3_pad_drv_on_cfg,
198 .off = sdc3_pad_drv_off_cfg,
199 .size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
200 },
201};
202
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530203struct msm_mmc_gpio sdc2_gpio[] = {
204 {92, "sdc2_dat_3"},
205 {91, "sdc2_dat_2"},
206 {90, "sdc2_dat_1"},
207 {89, "sdc2_dat_0"},
208 {97, "sdc2_cmd"},
209 {98, "sdc2_clk"}
210};
211
212struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
213 [SDCC2] = {
214 .gpio = sdc2_gpio,
215 .size = ARRAY_SIZE(sdc2_gpio),
216 }
217};
218
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800219static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
220 [SDCC1] = {
221 .pull = &mmc_pad_pull_data[SDCC1],
222 .drv = &mmc_pad_drv_data[SDCC1]
223 },
224 [SDCC3] = {
225 .pull = &mmc_pad_pull_data[SDCC3],
226 .drv = &mmc_pad_drv_data[SDCC3]
227 },
228};
229
230static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
231 [SDCC1] = {
232 .pad_data = &mmc_pad_data[SDCC1],
233 },
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530234 [SDCC2] = {
235 .is_gpio = 1,
236 .gpio_data = &mmc_gpio_data[SDCC2],
237 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800238 [SDCC3] = {
239 .pad_data = &mmc_pad_data[SDCC3],
240 },
241};
242
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530243#define MSM_MPM_PIN_SDC1_DAT1 17
244#define MSM_MPM_PIN_SDC3_DAT1 21
245
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800246static unsigned int sdc1_sup_clk_rates[] = {
247 400000, 24000000, 48000000
248};
249
Terence Hampson2e1705f2012-04-11 19:55:29 -0400250#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800251static unsigned int sdc3_sup_clk_rates[] = {
Subhash Jadavani2f64f5a2011-12-06 17:17:23 +0530252 400000, 24000000, 48000000, 96000000, 192000000
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800253};
Terence Hampson2e1705f2012-04-11 19:55:29 -0400254#endif
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800255
256#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
257static struct mmc_platform_data msm8960_sdc1_data = {
258 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
259#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
260 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
261#else
262 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
263#endif
264 .sup_clk_table = sdc1_sup_clk_rates,
265 .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
266 .pclk_src_dfab = 1,
267 .nonremovable = 1,
268 .vreg_data = &mmc_slot_vreg_data[SDCC1],
Subhash Jadavani933e6a62011-12-26 18:05:04 +0530269 .pin_data = &mmc_slot_pin_data[SDCC1],
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530270 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC1_DAT1,
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800271};
272#endif
273
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530274#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
275static unsigned int sdc2_sup_clk_rates[] = {
276 400000, 24000000, 48000000
277};
278
279static struct mmc_platform_data msm8960_sdc2_data = {
280 .ocr_mask = MMC_VDD_165_195,
281 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
282 .sup_clk_table = sdc2_sup_clk_rates,
283 .sup_clk_cnt = ARRAY_SIZE(sdc2_sup_clk_rates),
284 .pclk_src_dfab = 1,
285 .vreg_data = &mmc_slot_vreg_data[SDCC2],
286 .pin_data = &mmc_slot_pin_data[SDCC2],
287 .sdiowakeup_irq = MSM_GPIO_TO_INT(90),
288};
289#endif
290
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800291#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
292static struct mmc_platform_data msm8960_sdc3_data = {
293 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
294 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
295 .sup_clk_table = sdc3_sup_clk_rates,
296 .sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
297 .pclk_src_dfab = 1,
298#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
299 .wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(16),
300#endif
301 .vreg_data = &mmc_slot_vreg_data[SDCC3],
302 .pin_data = &mmc_slot_pin_data[SDCC3],
303#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
304 .status_gpio = PM8921_GPIO_PM_TO_SYS(26),
305 .status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
306 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
Krishna Konda360aa422011-12-06 18:27:41 -0800307 .is_status_gpio_active_low = true,
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800308#endif
309 .xpc_cap = 1,
310 .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
311 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
Subhash Jadavani2f64f5a2011-12-06 17:17:23 +0530312 MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_600),
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530313 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC3_DAT1,
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800314};
315#endif
316
317void __init msm8960_init_mmc(void)
318{
319#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
320 /* SDC1 : eMMC card connected */
321 msm_add_sdcc(1, &msm8960_sdc1_data);
322#endif
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530323#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
324 /* SDC2: SDIO slot for WLAN*/
325 msm_add_sdcc(2, &msm8960_sdc2_data);
326#endif
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800327#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800328 /* SDC3: External card slot */
329 msm_add_sdcc(3, &msm8960_sdc3_data);
330#endif
331}