blob: 1279b75de122f73488fdc0a0f26ee026f8ebe529 [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>
Steve Mucklef132c6c2012-06-06 18:30:57 -070018#include <linux/gpio.h>
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -080019#include <asm/mach-types.h>
20#include <asm/mach/mmc.h>
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -080021#include <mach/board.h>
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -080022#include <mach/gpiomux.h>
23#include "devices.h"
Stepan Moskovchenko5a83dba2011-12-05 17:30:17 -080024#include "board-8960.h"
Subhash Jadavanibcd435f2012-04-24 18:26:49 +053025#include "board-storage-common-a.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,
Pratibhasagar V26cf2652012-01-12 17:31:21 +053097 },
98 /* SDCC4 : SDIO slot connected */
99 [SDCC4] = {
100 .name = "sdc_vddp",
101 .high_vol_level = 1800000,
102 .low_vol_level = 1800000,
103 .always_on = 1,
104 .lpm_sup = 1,
105 .hpm_uA = 200000, /* 200mA */
106 .lpm_uA = 2000,
107 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800108};
109
110static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
111 /* SDCC1 : eMMC card connected */
112 [SDCC1] = {
113 .vdd_data = &mmc_vdd_reg_data[SDCC1],
114 .vccq_data = &mmc_vccq_reg_data[SDCC1],
115 },
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530116 /* SDCC2 : SDIO card slot connected */
117 [SDCC2] = {
118 .vdd_data = &mmc_vdd_reg_data[SDCC2],
119 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800120 /* SDCC3 : External card slot connected */
121 [SDCC3] = {
122 .vdd_data = &mmc_vdd_reg_data[SDCC3],
123 .vddp_data = &mmc_vddp_reg_data[SDCC3],
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530124 },
125 /* SDCC4 : SDIO card slot connected */
126 [SDCC4] = {
127 .vddp_data = &mmc_vddp_reg_data[SDCC4],
128 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800129};
130
131/* SDC1 pad data */
132static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
133 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
134 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
135 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
136};
137
138static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
139 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
140 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
141 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
142};
143
144static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
145 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
146 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
147 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
148};
149
150static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
151 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
Subhash Jadavani32a43982012-01-20 16:51:06 +0530152 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
153 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800154};
155
156/* SDC3 pad data */
157static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
158 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
159 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
160 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
161};
162
163static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
164 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
165 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
166 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
167};
168
169static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
170 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
171 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
172 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
173};
174
175static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
176 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
177 /*
178 * SDC3 CMD line should be PULLed UP otherwise fluid platform will
179 * see transitions (1 -> 0 and 0 -> 1) on card detection line,
180 * which would result in false card detection interrupts.
181 */
182 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
183 /*
184 * Keeping DATA lines status to PULL UP will make sure that
185 * there is no current leak during sleep if external pull up
186 * is connected to DATA lines.
187 */
188 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
189};
190
191static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
192 [SDCC1] = {
193 .on = sdc1_pad_pull_on_cfg,
194 .off = sdc1_pad_pull_off_cfg,
195 .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
196 },
197 [SDCC3] = {
198 .on = sdc3_pad_pull_on_cfg,
199 .off = sdc3_pad_pull_off_cfg,
200 .size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
201 },
202};
203
204static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
205 [SDCC1] = {
206 .on = sdc1_pad_drv_on_cfg,
207 .off = sdc1_pad_drv_off_cfg,
208 .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
209 },
210 [SDCC3] = {
211 .on = sdc3_pad_drv_on_cfg,
212 .off = sdc3_pad_drv_off_cfg,
213 .size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
214 },
215};
216
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530217struct msm_mmc_gpio sdc2_gpio[] = {
218 {92, "sdc2_dat_3"},
219 {91, "sdc2_dat_2"},
220 {90, "sdc2_dat_1"},
221 {89, "sdc2_dat_0"},
222 {97, "sdc2_cmd"},
223 {98, "sdc2_clk"}
224};
225
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530226struct msm_mmc_gpio sdc4_gpio[] = {
227 {83, "sdc4_dat_3"},
228 {84, "sdc4_dat_2"},
229 {85, "sdc4_dat_1"},
230 {86, "sdc4_dat_0"},
231 {87, "sdc4_cmd"},
232 {88, "sdc4_clk"}
233};
234
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530235struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
236 [SDCC2] = {
237 .gpio = sdc2_gpio,
238 .size = ARRAY_SIZE(sdc2_gpio),
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530239 },
240 [SDCC4] = {
241 .gpio = sdc4_gpio,
242 .size = ARRAY_SIZE(sdc4_gpio),
243 },
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530244};
245
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800246static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
247 [SDCC1] = {
248 .pull = &mmc_pad_pull_data[SDCC1],
249 .drv = &mmc_pad_drv_data[SDCC1]
250 },
251 [SDCC3] = {
252 .pull = &mmc_pad_pull_data[SDCC3],
253 .drv = &mmc_pad_drv_data[SDCC3]
254 },
255};
256
257static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
258 [SDCC1] = {
259 .pad_data = &mmc_pad_data[SDCC1],
260 },
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530261 [SDCC2] = {
262 .is_gpio = 1,
263 .gpio_data = &mmc_gpio_data[SDCC2],
264 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800265 [SDCC3] = {
266 .pad_data = &mmc_pad_data[SDCC3],
267 },
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530268 [SDCC4] = {
269 .is_gpio = 1,
270 .gpio_data = &mmc_gpio_data[SDCC4],
271 },
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800272};
273
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530274#define MSM_MPM_PIN_SDC1_DAT1 17
275#define MSM_MPM_PIN_SDC3_DAT1 21
276
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800277static unsigned int sdc1_sup_clk_rates[] = {
278 400000, 24000000, 48000000
279};
280
Terence Hampson2e1705f2012-04-11 19:55:29 -0400281#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800282static unsigned int sdc3_sup_clk_rates[] = {
Subhash Jadavani2f64f5a2011-12-06 17:17:23 +0530283 400000, 24000000, 48000000, 96000000, 192000000
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800284};
Terence Hampson2e1705f2012-04-11 19:55:29 -0400285#endif
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800286
287#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
288static struct mmc_platform_data msm8960_sdc1_data = {
289 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
290#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
291 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
292#else
293 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
294#endif
295 .sup_clk_table = sdc1_sup_clk_rates,
296 .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
297 .pclk_src_dfab = 1,
298 .nonremovable = 1,
299 .vreg_data = &mmc_slot_vreg_data[SDCC1],
Subhash Jadavani933e6a62011-12-26 18:05:04 +0530300 .pin_data = &mmc_slot_pin_data[SDCC1],
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530301 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC1_DAT1,
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530302 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800303};
304#endif
305
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530306#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
307static unsigned int sdc2_sup_clk_rates[] = {
308 400000, 24000000, 48000000
309};
310
311static struct mmc_platform_data msm8960_sdc2_data = {
312 .ocr_mask = MMC_VDD_165_195,
313 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
314 .sup_clk_table = sdc2_sup_clk_rates,
315 .sup_clk_cnt = ARRAY_SIZE(sdc2_sup_clk_rates),
316 .pclk_src_dfab = 1,
317 .vreg_data = &mmc_slot_vreg_data[SDCC2],
318 .pin_data = &mmc_slot_pin_data[SDCC2],
319 .sdiowakeup_irq = MSM_GPIO_TO_INT(90),
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530320 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530321};
322#endif
323
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800324#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
325static struct mmc_platform_data msm8960_sdc3_data = {
326 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
327 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
328 .sup_clk_table = sdc3_sup_clk_rates,
329 .sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
330 .pclk_src_dfab = 1,
331#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
332 .wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(16),
333#endif
334 .vreg_data = &mmc_slot_vreg_data[SDCC3],
335 .pin_data = &mmc_slot_pin_data[SDCC3],
336#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
337 .status_gpio = PM8921_GPIO_PM_TO_SYS(26),
338 .status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
339 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
Krishna Konda360aa422011-12-06 18:27:41 -0800340 .is_status_gpio_active_low = true,
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800341#endif
342 .xpc_cap = 1,
343 .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
344 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
Subhash Jadavani2f64f5a2011-12-06 17:17:23 +0530345 MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_600),
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530346 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC3_DAT1,
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530347 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800348};
349#endif
350
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530351#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
352static unsigned int sdc4_sup_clk_rates[] = {
353 400000, 24000000, 48000000
354};
355
356static struct mmc_platform_data msm8960_sdc4_data = {
357 .ocr_mask = MMC_VDD_165_195,
358 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
359 .sup_clk_table = sdc4_sup_clk_rates,
360 .sup_clk_cnt = ARRAY_SIZE(sdc4_sup_clk_rates),
361 .pclk_src_dfab = 1,
362 .vreg_data = &mmc_slot_vreg_data[SDCC4],
363 .pin_data = &mmc_slot_pin_data[SDCC4],
364 .sdiowakeup_irq = MSM_GPIO_TO_INT(85),
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530365 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530366};
367#endif
368
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800369void __init msm8960_init_mmc(void)
370{
371#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
372 /* SDC1 : eMMC card connected */
373 msm_add_sdcc(1, &msm8960_sdc1_data);
374#endif
Pratibhasagar V57c808e2012-01-12 13:47:30 +0530375#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
376 /* SDC2: SDIO slot for WLAN*/
377 msm_add_sdcc(2, &msm8960_sdc2_data);
378#endif
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800379#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800380 /* SDC3: External card slot */
381 msm_add_sdcc(3, &msm8960_sdc3_data);
382#endif
Pratibhasagar V26cf2652012-01-12 17:31:21 +0530383#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
384 /* SDC4: SDIO slot for WLAN */
385 msm_add_sdcc(4, &msm8960_sdc4_data);
386#endif
Stepan Moskovchenko0c547bb2011-11-30 13:29:12 -0800387}