blob: 96e54b655dd37f065bd2f64e04817b162165ede3 [file] [log] [blame]
Oluwafemi Adeyemif5a31422012-03-08 16:58:45 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -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-8064.h"
Subhash Jadavanibcd435f2012-04-24 18:26:49 +053026#include "board-storage-common-a.h"
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -080027
28
29/* APQ8064 has 4 SDCC controllers */
30enum sdcc_controllers {
31 SDCC1,
32 SDCC2,
33 SDCC3,
34 SDCC4,
35 MAX_SDCC_CONTROLLER
36};
37
38/* All SDCC controllers require VDD/VCC voltage */
39static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
40 /* SDCC1 : eMMC card connected */
41 [SDCC1] = {
42 .name = "sdc_vdd",
43 .high_vol_level = 2950000,
44 .low_vol_level = 2950000,
45 .always_on = 1,
46 .lpm_sup = 1,
47 .lpm_uA = 9000,
48 .hpm_uA = 200000, /* 200mA */
49 },
50 /* SDCC3 : External card slot connected */
51 [SDCC3] = {
52 .name = "sdc_vdd",
53 .high_vol_level = 2950000,
54 .low_vol_level = 2950000,
Oluwafemi Adeyemiaafeeb02012-02-20 21:01:15 -080055 .hpm_uA = 800000, /* 800mA */
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -080056 }
57};
58
59/* Only slots having eMMC card will require VCCQ voltage */
60static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
61 /* SDCC1 : eMMC card connected */
62 [SDCC1] = {
63 .name = "sdc_vccq",
64 .always_on = 1,
65 .high_vol_level = 1800000,
66 .low_vol_level = 1800000,
67 .hpm_uA = 200000, /* 200mA */
68 }
69};
70
71/* All SDCC controllers may require voting for VDD PAD voltage */
72static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
73 /* SDCC3 : External card slot connected */
74 [SDCC3] = {
75 .name = "sdc_vddp",
76 .high_vol_level = 2950000,
77 .low_vol_level = 1850000,
78 .always_on = 1,
79 .lpm_sup = 1,
80 /* Max. Active current required is 16 mA */
81 .hpm_uA = 16000,
82 /*
83 * Sleep current required is ~300 uA. But min. vote can be
84 * in terms of mA (min. 1 mA). So let's vote for 2 mA
85 * during sleep.
86 */
87 .lpm_uA = 2000,
88 }
89};
90
91static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
92 /* SDCC1 : eMMC card connected */
93 [SDCC1] = {
94 .vdd_data = &mmc_vdd_reg_data[SDCC1],
95 .vccq_data = &mmc_vccq_reg_data[SDCC1],
96 },
97 /* SDCC3 : External card slot connected */
98 [SDCC3] = {
99 .vdd_data = &mmc_vdd_reg_data[SDCC3],
100 .vddp_data = &mmc_vddp_reg_data[SDCC3],
101 }
102};
103
104/* SDC1 pad data */
105static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
106 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
107 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
108 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
109};
110
111static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
112 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
113 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
114 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
115};
116
117static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
118 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
119 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
120 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
121};
122
123static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
124 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
Oluwafemi Adeyemi4e196b62012-02-15 14:29:03 -0800125 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
126 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800127};
128
129/* SDC3 pad data */
130static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
131 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
132 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
133 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
134};
135
136static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
137 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
138 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
139 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
140};
141
142static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
143 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
144 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
145 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
146};
147
148static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
149 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
Oluwafemi Adeyemi4e196b62012-02-15 14:29:03 -0800150 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
151 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800152};
153
154static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
155 [SDCC1] = {
156 .on = sdc1_pad_pull_on_cfg,
157 .off = sdc1_pad_pull_off_cfg,
158 .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
159 },
160 [SDCC3] = {
161 .on = sdc3_pad_pull_on_cfg,
162 .off = sdc3_pad_pull_off_cfg,
163 .size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
164 },
165};
166
167static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
168 [SDCC1] = {
169 .on = sdc1_pad_drv_on_cfg,
170 .off = sdc1_pad_drv_off_cfg,
171 .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
172 },
173 [SDCC3] = {
174 .on = sdc3_pad_drv_on_cfg,
175 .off = sdc3_pad_drv_off_cfg,
176 .size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
177 },
178};
179
180static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
181 [SDCC1] = {
182 .pull = &mmc_pad_pull_data[SDCC1],
183 .drv = &mmc_pad_drv_data[SDCC1]
184 },
185 [SDCC3] = {
186 .pull = &mmc_pad_pull_data[SDCC3],
187 .drv = &mmc_pad_drv_data[SDCC3]
188 },
189};
190
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700191static struct msm_mmc_gpio sdc2_gpio[] = {
192 {59, "sdc2_clk"},
193 {57, "sdc2_cmd"},
194 {62, "sdc2_dat_0"},
195 {61, "sdc2_dat_1"},
196 {60, "sdc2_dat_2"},
197 {58, "sdc2_dat_3"},
198};
199
200static struct msm_mmc_gpio sdc4_gpio[] = {
201 {68, "sdc4_clk"},
202 {67, "sdc4_cmd"},
203 {66, "sdc4_dat_0"},
204 {65, "sdc4_dat_1"},
205 {64, "sdc4_dat_2"},
206 {63, "sdc4_dat_3"},
207};
208
209static struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
210 [SDCC2] = {
211 .gpio = sdc2_gpio,
212 .size = ARRAY_SIZE(sdc2_gpio),
213 },
214 [SDCC4] = {
215 .gpio = sdc4_gpio,
216 .size = ARRAY_SIZE(sdc4_gpio),
217 }
218};
219
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800220static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
221 [SDCC1] = {
222 .pad_data = &mmc_pad_data[SDCC1],
223 },
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700224 [SDCC2] = {
225 .is_gpio = 1,
226 .gpio_data = &mmc_gpio_data[SDCC2],
227 },
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800228 [SDCC3] = {
229 .pad_data = &mmc_pad_data[SDCC3],
230 },
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700231 [SDCC4] = {
232 .is_gpio = 1,
233 .gpio_data = &mmc_gpio_data[SDCC4],
234 },
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800235};
236
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530237#define MSM_MPM_PIN_SDC1_DAT1 17
238#define MSM_MPM_PIN_SDC3_DAT1 21
239
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800240#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
241static unsigned int sdc1_sup_clk_rates[] = {
242 400000, 24000000, 48000000, 96000000
243};
244
245static struct mmc_platform_data sdc1_data = {
246 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
247#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
248 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
249#else
250 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
251#endif
252 .sup_clk_table = sdc1_sup_clk_rates,
253 .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
Oluwafemi Adeyemi89ff2a12012-03-08 16:44:21 -0800254 .pclk_src_dfab = 1,
255 .nonremovable = 1,
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800256 .pin_data = &mmc_slot_pin_data[SDCC1],
257 .vreg_data = &mmc_slot_vreg_data[SDCC1],
Oluwafemi Adeyemi1e770962012-03-23 13:08:11 -0700258 .uhs_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530259 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC1_DAT1,
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530260 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800261};
262static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
263#else
264static struct mmc_platform_data *apq8064_sdc1_pdata;
265#endif
266
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700267#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
268static unsigned int sdc2_sup_clk_rates[] = {
269 400000, 24000000, 48000000
270};
271
272static struct mmc_platform_data sdc2_data = {
273 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
274 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
275 .sup_clk_table = sdc2_sup_clk_rates,
276 .sup_clk_cnt = ARRAY_SIZE(sdc2_sup_clk_rates),
277 .pclk_src_dfab = 1,
278 .pin_data = &mmc_slot_pin_data[SDCC2],
279 .sdiowakeup_irq = MSM_GPIO_TO_INT(61),
280 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
281};
282static struct mmc_platform_data *apq8064_sdc2_pdata = &sdc2_data;
283#else
284static struct mmc_platform_data *apq8064_sdc2_pdata;
285#endif
286
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800287#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
288static unsigned int sdc3_sup_clk_rates[] = {
Oluwafemi Adeyemi086ef862012-02-07 20:13:50 -0800289 400000, 24000000, 48000000, 96000000, 192000000
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800290};
291
292static struct mmc_platform_data 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),
Oluwafemi Adeyemi89ff2a12012-03-08 16:44:21 -0800297 .pclk_src_dfab = 1,
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800298 .pin_data = &mmc_slot_pin_data[SDCC3],
299 .vreg_data = &mmc_slot_vreg_data[SDCC3],
Oluwafemi Adeyemi787ac482012-02-16 09:50:03 -0800300 .wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(17),
301 .wpswitch_polarity = 1,
Oluwafemi Adeyemi83999672012-02-07 20:01:26 -0800302 .status_gpio = 26,
303 .status_irq = MSM_GPIO_TO_INT(26),
304 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
305 .is_status_gpio_active_low = 1,
Oluwafemi Adeyemi086ef862012-02-07 20:13:50 -0800306 .xpc_cap = 1,
307 .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
308 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
309 MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530310 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC3_DAT1,
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530311 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800312};
313static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
314#else
315static struct mmc_platform_data *apq8064_sdc3_pdata;
316#endif
317
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700318
319#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
320static unsigned int sdc4_sup_clk_rates[] = {
321 400000, 24000000, 48000000
322};
323
324static struct mmc_platform_data sdc4_data = {
325 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
326 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
327 .sup_clk_table = sdc4_sup_clk_rates,
328 .sup_clk_cnt = ARRAY_SIZE(sdc4_sup_clk_rates),
329 .pclk_src_dfab = 1,
330 .pin_data = &mmc_slot_pin_data[SDCC4],
331 .sdiowakeup_irq = MSM_GPIO_TO_INT(65),
332 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
333};
334static struct mmc_platform_data *apq8064_sdc4_pdata = &sdc4_data;
335#else
336static struct mmc_platform_data *apq8064_sdc4_pdata;
337#endif
338
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800339void __init apq8064_init_mmc(void)
340{
341 if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
342 if (apq8064_sdc1_pdata) {
343 if (machine_is_apq8064_sim())
344 apq8064_sdc1_pdata->disable_bam = true;
345 apq8064_sdc1_pdata->disable_runtime_pm = true;
346 apq8064_sdc1_pdata->disable_cmd23 = true;
347 }
348 if (apq8064_sdc3_pdata) {
349 if (machine_is_apq8064_sim())
350 apq8064_sdc3_pdata->disable_bam = true;
351 apq8064_sdc3_pdata->disable_runtime_pm = true;
352 apq8064_sdc3_pdata->disable_cmd23 = true;
353 }
354 }
Oluwafemi Adeyemi784b4392012-04-10 13:49:38 -0700355
356 if (apq8064_sdc1_pdata)
Oluwafemi Adeyemif5a31422012-03-08 16:58:45 -0800357 apq8064_add_sdcc(1, apq8064_sdc1_pdata);
Oluwafemi Adeyemi784b4392012-04-10 13:49:38 -0700358
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700359 if (apq8064_sdc2_pdata)
360 apq8064_add_sdcc(2, apq8064_sdc2_pdata);
361
Oluwafemi Adeyemif5a31422012-03-08 16:58:45 -0800362 if (apq8064_sdc3_pdata) {
Oluwafemi Adeyemi48fc3262012-03-19 13:26:52 -0700363 if (!machine_is_apq8064_cdp()) {
364 apq8064_sdc3_pdata->wpswitch_gpio = 0;
365 apq8064_sdc3_pdata->wpswitch_polarity = 0;
366 }
Oluwafemi Adeyemi0d469ce2012-05-10 18:04:25 -0700367 if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
368 machine_is_mpq8064_dtv()) {
369 apq8064_sdc3_pdata->status_gpio =
370 PM8921_GPIO_PM_TO_SYS(31);
371 apq8064_sdc3_pdata->status_irq =
372 PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 31);
373 }
Oluwafemi Adeyemif5a31422012-03-08 16:58:45 -0800374 apq8064_add_sdcc(3, apq8064_sdc3_pdata);
375 }
Oluwafemi Adeyemia46d0322012-05-16 18:27:44 -0700376
377 if (apq8064_sdc4_pdata)
378 apq8064_add_sdcc(4, apq8064_sdc4_pdata);
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800379}