ARM: tegra: sdhci: Pass speedo id in platform data
[linux-3.10.git] / arch / arm / mach-tegra / board-loki-sdhci.c
1 /*
2  * arch/arm/mach-tegra/board-loki-sdhci.c
3  *
4  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/resource.h>
20 #include <linux/platform_device.h>
21 #include <linux/wlan_plat.h>
22 #include <linux/fs.h>
23 #include <linux/delay.h>
24 #include <linux/gpio.h>
25 #include <linux/clk.h>
26 #include <linux/err.h>
27 #include <linux/mmc/host.h>
28 #include <linux/wl12xx.h>
29 #include <linux/platform_data/mmc-sdhci-tegra.h>
30 #include <linux/mfd/max77660/max77660-core.h>
31 #include <linux/tegra-fuse.h>
32
33 #include <asm/mach-types.h>
34 #include <mach/irqs.h>
35 #include <mach/gpio-tegra.h>
36
37 #include "gpio-names.h"
38 #include "board.h"
39 #include "board-loki.h"
40 #include "iomap.h"
41 #include "dvfs.h"
42 #include "tegra-board-id.h"
43
44 #define LOKI_WLAN_RST   TEGRA_GPIO_PR3
45 #define LOKI_WLAN_PWR   TEGRA_GPIO_PCC5
46 #define LOKI_WLAN_WOW   TEGRA_GPIO_PU5
47
48 #define LOKI_SD_CD      TEGRA_GPIO_PV2
49
50 #define FUSE_SOC_SPEEDO_0      0x134
51
52 static void (*wifi_status_cb)(int card_present, void *dev_id);
53 static void *wifi_status_cb_devid;
54 static int loki_wifi_status_register(void (*callback)(int , void *), void *);
55
56 static int loki_wifi_reset(int on);
57 static int loki_wifi_power(int on);
58 static int loki_wifi_set_carddetect(int val);
59 static int loki_wifi_get_mac_addr(unsigned char *buf);
60
61 static struct wifi_platform_data loki_wifi_control = {
62         .set_power      = loki_wifi_power,
63         .set_reset      = loki_wifi_reset,
64         .set_carddetect = loki_wifi_set_carddetect,
65         .get_mac_addr   = loki_wifi_get_mac_addr,
66 };
67
68 static struct resource wifi_resource[] = {
69         [0] = {
70                 .name   = "bcm4329_wlan_irq",
71                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
72                                 | IORESOURCE_IRQ_SHAREABLE,
73         },
74 };
75
76 static struct platform_device loki_wifi_device = {
77         .name           = "bcm4329_wlan",
78         .id             = 1,
79         .num_resources  = 1,
80         .resource       = wifi_resource,
81         .dev            = {
82                 .platform_data = &loki_wifi_control,
83         },
84 };
85
86 static struct resource sdhci_resource0[] = {
87         [0] = {
88                 .start  = INT_SDMMC1,
89                 .end    = INT_SDMMC1,
90                 .flags  = IORESOURCE_IRQ,
91         },
92         [1] = {
93                 .start  = TEGRA_SDMMC1_BASE,
94                 .end    = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
95                 .flags  = IORESOURCE_MEM,
96         },
97 };
98
99 static struct resource sdhci_resource2[] = {
100         [0] = {
101                 .start  = INT_SDMMC3,
102                 .end    = INT_SDMMC3,
103                 .flags  = IORESOURCE_IRQ,
104         },
105         [1] = {
106                 .start  = TEGRA_SDMMC3_BASE,
107                 .end    = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
108                 .flags  = IORESOURCE_MEM,
109         },
110 };
111
112 static struct resource sdhci_resource3[] = {
113         [0] = {
114                 .start  = INT_SDMMC4,
115                 .end    = INT_SDMMC4,
116                 .flags  = IORESOURCE_IRQ,
117         },
118         [1] = {
119                 .start  = TEGRA_SDMMC4_BASE,
120                 .end    = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
121                 .flags  = IORESOURCE_MEM,
122         },
123 };
124
125 #ifdef CONFIG_MMC_EMBEDDED_SDIO
126 static struct embedded_sdio_data embedded_sdio_data0 = {
127         .cccr   = {
128                 .sdio_vsn       = 2,
129                 .multi_block    = 1,
130                 .low_speed      = 0,
131                 .wide_bus       = 0,
132                 .high_power     = 1,
133                 .high_speed     = 1,
134         },
135         .cis  = {
136                 .vendor  = 0x02d0,
137                 .device  = 0x4329,
138         },
139 };
140 #endif
141
142 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
143         .mmc_data = {
144                 .register_status_notify = loki_wifi_status_register,
145 #ifdef CONFIG_MMC_EMBEDDED_SDIO
146                 .embedded_sdio = &embedded_sdio_data0,
147 #endif
148                 .built_in = 0,
149                 .ocr_mask = MMC_OCR_1V8_MASK,
150         },
151         .cd_gpio = -1,
152         .wp_gpio = -1,
153         .power_gpio = -1,
154         .tap_delay = 0,
155         .trim_delay = 0x2,
156         .ddr_clk_limit = 41000000,
157         .uhs_mask = MMC_UHS_MASK_DDR50 | MMC_UHS_MASK_SDR50,
158         .calib_3v3_offsets = 0x7676,
159         .calib_1v8_offsets = 0x7676,
160 };
161
162 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
163         .cd_gpio = LOKI_SD_CD,
164         .wp_gpio = -1,
165         .power_gpio = -1,
166         .tap_delay = 0,
167         .trim_delay = 0x3,
168         .uhs_mask = MMC_UHS_MASK_DDR50 | MMC_UHS_MASK_SDR50,
169         .max_clk_limit = 204000000,
170         .calib_3v3_offsets = 0x7676,
171         .calib_1v8_offsets = 0x7676,
172 };
173
174 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
175         .cd_gpio = -1,
176         .wp_gpio = -1,
177         .power_gpio = -1,
178         .is_8bit = 1,
179         .tap_delay = 0x4,
180         .trim_delay = 0x3,
181         .ddr_trim_delay = 0x0,
182         .mmc_data = {
183                 .built_in = 1,
184                 .ocr_mask = MMC_OCR_1V8_MASK,
185         },
186         .ddr_clk_limit = 51000000,
187         .max_clk_limit = 200000000,
188         .calib_3v3_offsets = 0x0202,
189         .calib_1v8_offsets = 0x0202,
190 };
191
192 static struct platform_device tegra_sdhci_device0 = {
193         .name           = "sdhci-tegra",
194         .id             = 0,
195         .resource       = sdhci_resource0,
196         .num_resources  = ARRAY_SIZE(sdhci_resource0),
197         .dev = {
198                 .platform_data = &tegra_sdhci_platform_data0,
199         },
200 };
201
202 static struct platform_device tegra_sdhci_device2 = {
203         .name           = "sdhci-tegra",
204         .id             = 2,
205         .resource       = sdhci_resource2,
206         .num_resources  = ARRAY_SIZE(sdhci_resource2),
207         .dev = {
208                 .platform_data = &tegra_sdhci_platform_data2,
209         },
210 };
211
212 static struct platform_device tegra_sdhci_device3 = {
213         .name           = "sdhci-tegra",
214         .id             = 3,
215         .resource       = sdhci_resource3,
216         .num_resources  = ARRAY_SIZE(sdhci_resource3),
217         .dev = {
218                 .platform_data = &tegra_sdhci_platform_data3,
219         },
220 };
221
222 static int loki_wifi_status_register(
223                 void (*callback)(int card_present, void *dev_id),
224                 void *dev_id)
225 {
226         if (wifi_status_cb)
227                 return -EAGAIN;
228         wifi_status_cb = callback;
229         wifi_status_cb_devid = dev_id;
230         return 0;
231 }
232
233 static int loki_wifi_set_carddetect(int val)
234 {
235         pr_debug("%s: %d\n", __func__, val);
236         if (wifi_status_cb)
237                 wifi_status_cb(val, wifi_status_cb_devid);
238         else
239                 pr_warn("%s: Nobody to notify\n", __func__);
240         return 0;
241 }
242
243 static struct regulator *loki_vdd_com_3v3;
244 static struct regulator *loki_vddio_com_1v8;
245
246 #define LOKI_VDD_WIFI_3V3 "avdd"
247 #define LOKI_VDD_WIFI_1V8 "dvdd"
248
249 static int loki_wifi_regulator_enable(void)
250 {
251         int ret = 0;
252
253         /* Enable COM's vdd_com_3v3 regulator*/
254         if (IS_ERR_OR_NULL(loki_vdd_com_3v3)) {
255                 loki_vdd_com_3v3 = regulator_get(&loki_wifi_device.dev,
256                                         LOKI_VDD_WIFI_3V3);
257                 if (IS_ERR(loki_vdd_com_3v3)) {
258                         pr_err("Couldn't get regulator "
259                                 LOKI_VDD_WIFI_3V3 "\n");
260                         return PTR_ERR(loki_vdd_com_3v3);
261                 }
262
263                 ret = regulator_enable(loki_vdd_com_3v3);
264                 if (ret < 0) {
265                         pr_err("Couldn't enable regulator "
266                                 LOKI_VDD_WIFI_3V3 "\n");
267                         regulator_put(loki_vdd_com_3v3);
268                         loki_vdd_com_3v3 = NULL;
269                         return ret;
270                 }
271         }
272
273         /* Enable COM's vddio_com_1v8 regulator*/
274         if (IS_ERR_OR_NULL(loki_vddio_com_1v8)) {
275                 loki_vddio_com_1v8 = regulator_get(&loki_wifi_device.dev,
276                         LOKI_VDD_WIFI_1V8);
277                 if (IS_ERR(loki_vddio_com_1v8)) {
278                         pr_err("Couldn't get regulator "
279                                 LOKI_VDD_WIFI_1V8 "\n");
280                         regulator_disable(loki_vdd_com_3v3);
281
282                         regulator_put(loki_vdd_com_3v3);
283                         loki_vdd_com_3v3 = NULL;
284                         return PTR_ERR(loki_vddio_com_1v8);
285                 }
286
287                 ret = regulator_enable(loki_vddio_com_1v8);
288                 if (ret < 0) {
289                         pr_err("Couldn't enable regulator "
290                                 LOKI_VDD_WIFI_1V8 "\n");
291                         regulator_put(loki_vddio_com_1v8);
292                         loki_vddio_com_1v8 = NULL;
293
294                         regulator_disable(loki_vdd_com_3v3);
295                         regulator_put(loki_vdd_com_3v3);
296                         loki_vdd_com_3v3 = NULL;
297                         return ret;
298                 }
299         }
300
301         return ret;
302 }
303
304 static void loki_wifi_regulator_disable(void)
305 {
306         /* Disable COM's vdd_com_3v3 regulator*/
307         if (!IS_ERR_OR_NULL(loki_vdd_com_3v3)) {
308                 regulator_disable(loki_vdd_com_3v3);
309                 regulator_put(loki_vdd_com_3v3);
310                 loki_vdd_com_3v3 = NULL;
311         }
312
313         /* Disable COM's vddio_com_1v8 regulator*/
314         if (!IS_ERR_OR_NULL(loki_vddio_com_1v8)) {
315                 regulator_disable(loki_vddio_com_1v8);
316                 regulator_put(loki_vddio_com_1v8);
317                 loki_vddio_com_1v8 = NULL;
318         }
319 }
320
321 static int loki_wifi_power(int on)
322 {
323         int ret = 0;
324
325         pr_err("%s: %d\n", __func__, on);
326
327         /* Enable COM's regulators on wi-fi poer on*/
328         if (on == 1) {
329                 ret = loki_wifi_regulator_enable();
330                 if (ret < 0) {
331                         pr_err("Failed to enable COM regulators\n");
332                         return ret;
333                 }
334         }
335
336         gpio_set_value(LOKI_WLAN_PWR, on);
337         gpio_set_value(LOKI_WLAN_RST, on);
338         mdelay(100);
339
340         /* Disable COM's regulators on wi-fi poer off*/
341         if (on != 1) {
342                 pr_debug("Disabling COM regulators\n");
343                 loki_wifi_regulator_disable();
344         }
345
346         return 0;
347 }
348
349 static int loki_wifi_reset(int on)
350 {
351         pr_debug("%s: do nothing\n", __func__);
352         return 0;
353 }
354
355 #define LOKI_WIFI_MAC_ADDR_FILE "/mnt/factory/wifi/wifi_mac.txt"
356
357 static int loki_wifi_get_mac_addr(unsigned char *buf)
358 {
359         struct file *fp;
360         int rdlen;
361         char str[32];
362         int mac[6];
363         int ret = 0;
364
365         pr_debug("%s\n", __func__);
366
367         /* open wifi mac address file */
368         fp = filp_open(LOKI_WIFI_MAC_ADDR_FILE, O_RDONLY, 0);
369         if (IS_ERR(fp)) {
370                 pr_err("%s: cannot open %s\n",
371                         __func__, LOKI_WIFI_MAC_ADDR_FILE);
372                 return -ENOENT;
373         }
374
375         /* read wifi mac address file */
376         memset(str, 0, sizeof(str));
377         rdlen = kernel_read(fp, fp->f_pos, str, 17);
378         if (rdlen > 0)
379                 fp->f_pos += rdlen;
380         if (rdlen != 17) {
381                 pr_err("%s: bad mac address file"
382                         " - len %d < 17",
383                         __func__, rdlen);
384                 ret = -ENOENT;
385         } else if (sscanf(str, "%x:%x:%x:%x:%x:%x",
386                 &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 6) {
387                 pr_err("%s: bad mac address file"
388                         " - must contain xx:xx:xx:xx:xx:xx\n",
389                         __func__);
390                 ret = -ENOENT;
391         } else {
392                 pr_info("%s: using wifi mac %02x:%02x:%02x:%02x:%02x:%02x\n",
393                         __func__,
394                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
395                 buf[0] = (unsigned char) mac[0];
396                 buf[1] = (unsigned char) mac[1];
397                 buf[2] = (unsigned char) mac[2];
398                 buf[3] = (unsigned char) mac[3];
399                 buf[4] = (unsigned char) mac[4];
400                 buf[5] = (unsigned char) mac[5];
401         }
402
403         /* close wifi mac address file */
404         filp_close(fp, NULL);
405
406         return ret;
407 }
408
409 static int __init loki_wifi_init(void)
410 {
411         int rc;
412
413         rc = gpio_request(LOKI_WLAN_PWR, "wlan_power");
414         if (rc)
415                 pr_err("WLAN_PWR gpio request failed:%d\n", rc);
416         rc = gpio_request(LOKI_WLAN_RST, "wlan_rst");
417         if (rc)
418                 pr_err("WLAN_RST gpio request failed:%d\n", rc);
419         rc = gpio_request(LOKI_WLAN_WOW, "bcmsdh_sdmmc");
420         if (rc)
421                 pr_err("WLAN_WOW gpio request failed:%d\n", rc);
422
423         rc = gpio_direction_output(LOKI_WLAN_PWR, 0);
424         if (rc)
425                 pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
426         rc = gpio_direction_output(LOKI_WLAN_RST, 0);
427         if (rc)
428                 pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
429
430         rc = gpio_direction_input(LOKI_WLAN_WOW);
431         if (rc)
432                 pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
433
434         wifi_resource[0].start = wifi_resource[0].end =
435                 gpio_to_irq(LOKI_WLAN_WOW);
436
437         platform_device_register(&loki_wifi_device);
438         return 0;
439 }
440
441 #ifdef CONFIG_TEGRA_PREPOWER_WIFI
442 static int __init loki_wifi_prepower(void)
443 {
444         if (!of_machine_is_compatible("nvidia,loki"))
445                 return 0;
446         loki_wifi_power(1);
447
448         return 0;
449 }
450
451 subsys_initcall_sync(loki_wifi_prepower);
452 #endif
453
454 int __init loki_sdhci_init(void)
455 {
456         int nominal_core_mv;
457         int min_vcore_override_mv;
458         int boot_vcore_mv;
459         u32 speedo;
460         struct board_info bi;
461
462         tegra_get_board_info(&bi);
463
464         if (bi.board_id == BOARD_E2548 && bi.sku == 0x0 && bi.fab == 0x0) {
465                 tegra_sdhci_platform_data3.uhs_mask |= MMC_MASK_HS200;
466                 tegra_sdhci_platform_data3.max_clk_limit = 102000000;
467         }
468
469         nominal_core_mv =
470                 tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail);
471         if (nominal_core_mv) {
472                 tegra_sdhci_platform_data0.nominal_vcore_mv = nominal_core_mv;
473                 tegra_sdhci_platform_data2.nominal_vcore_mv = nominal_core_mv;
474                 tegra_sdhci_platform_data3.nominal_vcore_mv = nominal_core_mv;
475         }
476         min_vcore_override_mv =
477                 tegra_dvfs_rail_get_override_floor(tegra_core_rail);
478         if (min_vcore_override_mv) {
479                 tegra_sdhci_platform_data0.min_vcore_override_mv =
480                         min_vcore_override_mv;
481                 tegra_sdhci_platform_data2.min_vcore_override_mv =
482                         min_vcore_override_mv;
483                 tegra_sdhci_platform_data3.min_vcore_override_mv =
484                         min_vcore_override_mv;
485         }
486         boot_vcore_mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail);
487         if (boot_vcore_mv) {
488                 tegra_sdhci_platform_data0.boot_vcore_mv = boot_vcore_mv;
489                 tegra_sdhci_platform_data2.boot_vcore_mv = boot_vcore_mv;
490                 tegra_sdhci_platform_data3.boot_vcore_mv = boot_vcore_mv;
491         }
492
493         tegra_sdhci_platform_data0.max_clk_limit = 204000000;
494
495         speedo = tegra_fuse_readl(FUSE_SOC_SPEEDO_0);
496         tegra_sdhci_platform_data0.cpu_speedo = speedo;
497         tegra_sdhci_platform_data2.cpu_speedo = speedo;
498         tegra_sdhci_platform_data3.cpu_speedo = speedo;
499
500
501         platform_device_register(&tegra_sdhci_device3);
502
503         if (!is_uart_over_sd_enabled())
504                 platform_device_register(&tegra_sdhci_device2);
505
506         platform_device_register(&tegra_sdhci_device0);
507         loki_wifi_init();
508
509         return 0;
510 }