blob: b8cae494de340cd342bc82cd3405f8124ad309a1 [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"
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -080026
27
28/* APQ8064 has 4 SDCC controllers */
29enum sdcc_controllers {
30 SDCC1,
31 SDCC2,
32 SDCC3,
33 SDCC4,
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 },
49 /* SDCC3 : External card slot connected */
50 [SDCC3] = {
51 .name = "sdc_vdd",
52 .high_vol_level = 2950000,
53 .low_vol_level = 2950000,
Oluwafemi Adeyemiaafeeb02012-02-20 21:01:15 -080054 .hpm_uA = 800000, /* 800mA */
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -080055 }
56};
57
58/* Only slots having eMMC card will require VCCQ voltage */
59static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
60 /* SDCC1 : eMMC card connected */
61 [SDCC1] = {
62 .name = "sdc_vccq",
63 .always_on = 1,
64 .high_vol_level = 1800000,
65 .low_vol_level = 1800000,
66 .hpm_uA = 200000, /* 200mA */
67 }
68};
69
70/* All SDCC controllers may require voting for VDD PAD voltage */
71static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
72 /* SDCC3 : External card slot connected */
73 [SDCC3] = {
74 .name = "sdc_vddp",
75 .high_vol_level = 2950000,
76 .low_vol_level = 1850000,
77 .always_on = 1,
78 .lpm_sup = 1,
79 /* Max. Active current required is 16 mA */
80 .hpm_uA = 16000,
81 /*
82 * Sleep current required is ~300 uA. But min. vote can be
83 * in terms of mA (min. 1 mA). So let's vote for 2 mA
84 * during sleep.
85 */
86 .lpm_uA = 2000,
87 }
88};
89
90static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
91 /* SDCC1 : eMMC card connected */
92 [SDCC1] = {
93 .vdd_data = &mmc_vdd_reg_data[SDCC1],
94 .vccq_data = &mmc_vccq_reg_data[SDCC1],
95 },
96 /* SDCC3 : External card slot connected */
97 [SDCC3] = {
98 .vdd_data = &mmc_vdd_reg_data[SDCC3],
99 .vddp_data = &mmc_vddp_reg_data[SDCC3],
100 }
101};
102
103/* SDC1 pad data */
104static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
105 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
106 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
107 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
108};
109
110static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
111 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
112 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
113 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
114};
115
116static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
117 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
118 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
119 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
120};
121
122static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
123 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
Oluwafemi Adeyemi4e196b62012-02-15 14:29:03 -0800124 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
125 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800126};
127
128/* SDC3 pad data */
129static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
130 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
131 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
132 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
133};
134
135static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
136 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
137 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
138 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
139};
140
141static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
142 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
143 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
144 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
145};
146
147static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
148 {TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
Oluwafemi Adeyemi4e196b62012-02-15 14:29:03 -0800149 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
150 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800151};
152
153static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
154 [SDCC1] = {
155 .on = sdc1_pad_pull_on_cfg,
156 .off = sdc1_pad_pull_off_cfg,
157 .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
158 },
159 [SDCC3] = {
160 .on = sdc3_pad_pull_on_cfg,
161 .off = sdc3_pad_pull_off_cfg,
162 .size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
163 },
164};
165
166static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
167 [SDCC1] = {
168 .on = sdc1_pad_drv_on_cfg,
169 .off = sdc1_pad_drv_off_cfg,
170 .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
171 },
172 [SDCC3] = {
173 .on = sdc3_pad_drv_on_cfg,
174 .off = sdc3_pad_drv_off_cfg,
175 .size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
176 },
177};
178
179static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
180 [SDCC1] = {
181 .pull = &mmc_pad_pull_data[SDCC1],
182 .drv = &mmc_pad_drv_data[SDCC1]
183 },
184 [SDCC3] = {
185 .pull = &mmc_pad_pull_data[SDCC3],
186 .drv = &mmc_pad_drv_data[SDCC3]
187 },
188};
189
190static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
191 [SDCC1] = {
192 .pad_data = &mmc_pad_data[SDCC1],
193 },
194 [SDCC3] = {
195 .pad_data = &mmc_pad_data[SDCC3],
196 },
197};
198
199#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
200static unsigned int sdc1_sup_clk_rates[] = {
201 400000, 24000000, 48000000, 96000000
202};
203
204static struct mmc_platform_data sdc1_data = {
205 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
206#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
207 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
208#else
209 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
210#endif
211 .sup_clk_table = sdc1_sup_clk_rates,
212 .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
Oluwafemi Adeyemi89ff2a12012-03-08 16:44:21 -0800213 .pclk_src_dfab = 1,
214 .nonremovable = 1,
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800215 .pin_data = &mmc_slot_pin_data[SDCC1],
216 .vreg_data = &mmc_slot_vreg_data[SDCC1],
217};
218static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
219#else
220static struct mmc_platform_data *apq8064_sdc1_pdata;
221#endif
222
223#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
224static unsigned int sdc3_sup_clk_rates[] = {
Oluwafemi Adeyemi086ef862012-02-07 20:13:50 -0800225 400000, 24000000, 48000000, 96000000, 192000000
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800226};
227
228static struct mmc_platform_data sdc3_data = {
229 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
230 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
231 .sup_clk_table = sdc3_sup_clk_rates,
232 .sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
Oluwafemi Adeyemi89ff2a12012-03-08 16:44:21 -0800233 .pclk_src_dfab = 1,
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800234 .pin_data = &mmc_slot_pin_data[SDCC3],
235 .vreg_data = &mmc_slot_vreg_data[SDCC3],
Oluwafemi Adeyemi787ac482012-02-16 09:50:03 -0800236 .wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(17),
237 .wpswitch_polarity = 1,
Oluwafemi Adeyemi83999672012-02-07 20:01:26 -0800238 .status_gpio = 26,
239 .status_irq = MSM_GPIO_TO_INT(26),
240 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
241 .is_status_gpio_active_low = 1,
Oluwafemi Adeyemi086ef862012-02-07 20:13:50 -0800242 .xpc_cap = 1,
243 .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
244 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
245 MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800246};
247static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
248#else
249static struct mmc_platform_data *apq8064_sdc3_pdata;
250#endif
251
252void __init apq8064_init_mmc(void)
253{
254 if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
255 if (apq8064_sdc1_pdata) {
256 if (machine_is_apq8064_sim())
257 apq8064_sdc1_pdata->disable_bam = true;
258 apq8064_sdc1_pdata->disable_runtime_pm = true;
259 apq8064_sdc1_pdata->disable_cmd23 = true;
260 }
261 if (apq8064_sdc3_pdata) {
262 if (machine_is_apq8064_sim())
263 apq8064_sdc3_pdata->disable_bam = true;
264 apq8064_sdc3_pdata->disable_runtime_pm = true;
265 apq8064_sdc3_pdata->disable_cmd23 = true;
266 }
267 }
Oluwafemi Adeyemif5a31422012-03-08 16:58:45 -0800268 if (apq8064_sdc1_pdata) {
269 apq8064_sdc1_pdata->swfi_latency =
270 apq8064_rpm_get_swfi_latency();
271 apq8064_add_sdcc(1, apq8064_sdc1_pdata);
272 }
273 if (apq8064_sdc3_pdata) {
274 apq8064_sdc3_pdata->swfi_latency =
275 apq8064_rpm_get_swfi_latency();
276 apq8064_add_sdcc(3, apq8064_sdc3_pdata);
277 }
Stepan Moskovchenkoe438b632011-12-06 13:44:03 -0800278}