blob: 15f681dffe9f6dee9737dd508cf998e5e425e265 [file] [log] [blame]
Chintan Pandya250c2e52012-01-19 17:15:49 +05301/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
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#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/platform_device.h>
16#include <linux/bootmem.h>
17#include <linux/regulator/consumer.h>
18#include <asm/mach-types.h>
19#include <asm/io.h>
20#include <mach/msm_bus_board.h>
21#include <mach/msm_memtypes.h>
22#include <mach/board.h>
23#include <mach/gpio.h>
24#include <mach/gpiomux.h>
25#include <mach/socinfo.h>
26#include <mach/rpc_pmapp.h>
27#include "devices.h"
28#include "board-msm7627a.h"
29
30#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
31#define MSM_FB_SIZE 0x260000
32#define MSM7x25A_MSM_FB_SIZE 0xE1000
33#else
34#define MSM_FB_SIZE 0x195000
35#define MSM7x25A_MSM_FB_SIZE 0x96000
36#endif
37
38static unsigned fb_size = MSM_FB_SIZE;
39static int __init fb_size_setup(char *p)
40{
41 fb_size = memparse(p, NULL);
42 return 0;
43}
44
45early_param("fb_size", fb_size_setup);
46
47static struct regulator_bulk_data regs_lcdc[] = {
48 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
49 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
50};
51static uint32_t lcdc_gpio_initialized;
52
53static void lcdc_toshiba_gpio_init(void)
54{
55 int rc = 0;
56 if (!lcdc_gpio_initialized) {
57 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
58 pr_err("failed to request gpio spi_clk\n");
59 return;
60 }
61 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
62 pr_err("failed to request gpio spi_cs0_N\n");
63 goto fail_gpio6;
64 }
65 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
66 pr_err("failed to request gpio spi_mosi\n");
67 goto fail_gpio5;
68 }
69 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
70 pr_err("failed to request gpio spi_miso\n");
71 goto fail_gpio4;
72 }
73 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
74 pr_err("failed to request gpio_disp_pwr\n");
75 goto fail_gpio3;
76 }
77 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
78 pr_err("failed to request gpio_bkl_en\n");
79 goto fail_gpio2;
80 }
81 pmapp_disp_backlight_init();
82
83 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc),
84 regs_lcdc);
85 if (rc) {
86 pr_err("%s: could not get regulators: %d\n",
87 __func__, rc);
88 goto fail_gpio1;
89 }
90
91 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
92 regs_lcdc);
93 if (rc) {
94 pr_err("%s: could not set voltages: %d\n",
95 __func__, rc);
96 goto fail_vreg;
97 }
98 lcdc_gpio_initialized = 1;
99 }
100 return;
101fail_vreg:
102 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
103fail_gpio1:
104 gpio_free(GPIO_BACKLIGHT_EN);
105fail_gpio2:
106 gpio_free(GPIO_DISPLAY_PWR_EN);
107fail_gpio3:
108 gpio_free(GPIO_SPI_MISO);
109fail_gpio4:
110 gpio_free(GPIO_SPI_MOSI);
111fail_gpio5:
112 gpio_free(GPIO_SPI_CS0_N);
113fail_gpio6:
114 gpio_free(GPIO_SPI_CLK);
115 lcdc_gpio_initialized = 0;
116}
117
118static uint32_t lcdc_gpio_table[] = {
119 GPIO_SPI_CLK,
120 GPIO_SPI_CS0_N,
121 GPIO_SPI_MOSI,
122 GPIO_DISPLAY_PWR_EN,
123 GPIO_BACKLIGHT_EN,
124 GPIO_SPI_MISO,
125};
126
127static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
128{
129 int n;
130
131 if (lcdc_gpio_initialized) {
132 /* All are IO Expander GPIOs */
133 for (n = 0; n < (len - 1); n++)
134 gpio_direction_output(table[n], 1);
135 }
136}
137
138static void lcdc_toshiba_config_gpios(int enable)
139{
140 config_lcdc_gpio_table(lcdc_gpio_table,
141 ARRAY_SIZE(lcdc_gpio_table), enable);
142}
143
144static int msm_fb_lcdc_power_save(int on)
145{
146 int rc = 0;
147 /* Doing the init of the LCDC GPIOs very late as they are from
148 an I2C-controlled IO Expander */
149 lcdc_toshiba_gpio_init();
150
151 if (lcdc_gpio_initialized) {
152 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
153 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
154
155 rc = on ? regulator_bulk_enable(
156 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
157 regulator_bulk_disable(
158 ARRAY_SIZE(regs_lcdc), regs_lcdc);
159
160 if (rc)
161 pr_err("%s: could not %sable regulators: %d\n",
162 __func__, on ? "en" : "dis", rc);
163 }
164
165 return rc;
166}
167
168static int lcdc_toshiba_set_bl(int level)
169{
170 int ret;
171
172 ret = pmapp_disp_backlight_set_brightness(level);
173 if (ret)
174 pr_err("%s: can't set lcd backlight!\n", __func__);
175
176 return ret;
177}
178
179static struct lcdc_platform_data lcdc_pdata = {
180 .lcdc_gpio_config = NULL,
181 .lcdc_power_save = msm_fb_lcdc_power_save,
182};
183
184static int lcd_panel_spi_gpio_num[] = {
185 GPIO_SPI_MOSI, /* spi_sdi */
186 GPIO_SPI_MISO, /* spi_sdoi */
187 GPIO_SPI_CLK, /* spi_clk */
188 GPIO_SPI_CS0_N, /* spi_cs */
189};
190
191static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
192 .panel_config_gpio = lcdc_toshiba_config_gpios,
193 .pmic_backlight = lcdc_toshiba_set_bl,
194 .gpio_num = lcd_panel_spi_gpio_num,
195};
196
197static struct platform_device lcdc_toshiba_panel_device = {
198 .name = "lcdc_toshiba_fwvga_pt",
199 .id = 0,
200 .dev = {
201 .platform_data = &lcdc_toshiba_panel_data,
202 }
203};
204
205static struct resource msm_fb_resources[] = {
206 {
207 .flags = IORESOURCE_DMA,
208 }
209};
210
211#define PANEL_NAME_MAX_LEN 30
212#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
213#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
214
215static int msm_fb_detect_panel(const char *name)
216{
217 int ret = -ENODEV;
218
219 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
220 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
221 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
222 ret = 0;
223 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()) {
224 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
225 ret = 0;
226 } else if (machine_is_msm7627a_qrd1()) {
227 if (!strncmp(name, "mipi_video_truly_wvga", 21))
228 ret = 0;
Jeevan Shrirame941df42012-01-23 12:40:21 +0530229 } else if (machine_is_msm7627a_evb()) {
230 if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
231 ret = 0;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530232 }
233
234#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
235 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
236 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
237 if (machine_is_msm7x27a_surf() ||
238 machine_is_msm7625a_surf()) {
239 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
240 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
241 PANEL_NAME_MAX_LEN)))
242 return 0;
243 }
244#endif
245
246 return ret;
247}
248
249static int mipi_truly_set_bl(int on)
250{
251 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
252
253 return 1;
254}
255
256static struct msm_fb_platform_data msm_fb_pdata = {
257 .detect_client = msm_fb_detect_panel,
258};
259
260static struct platform_device msm_fb_device = {
261 .name = "msm_fb",
262 .id = 0,
263 .num_resources = ARRAY_SIZE(msm_fb_resources),
264 .resource = msm_fb_resources,
265 .dev = {
266 .platform_data = &msm_fb_pdata,
267 }
268};
269
270#ifdef CONFIG_FB_MSM_MIPI_DSI
271static int mipi_renesas_set_bl(int level)
272{
273 int ret;
274
275 ret = pmapp_disp_backlight_set_brightness(level);
276
277 if (ret)
278 pr_err("%s: can't set lcd backlight!\n", __func__);
279
280 return ret;
281}
282
283static struct msm_panel_common_pdata mipi_renesas_pdata = {
284 .pmic_backlight = mipi_renesas_set_bl,
285};
286
287
288static struct platform_device mipi_dsi_renesas_panel_device = {
289 .name = "mipi_renesas",
290 .id = 0,
291 .dev = {
292 .platform_data = &mipi_renesas_pdata,
293 }
294};
295#endif
296
297static struct msm_panel_common_pdata mipi_truly_pdata = {
298 .pmic_backlight = mipi_truly_set_bl,
299};
300
301static struct platform_device mipi_dsi_truly_panel_device = {
302 .name = "mipi_truly",
303 .id = 0,
304 .dev = {
305 .platform_data = &mipi_truly_pdata,
306 }
307};
308
Jeevan Shrirame941df42012-01-23 12:40:21 +0530309static struct msm_panel_common_pdata mipi_NT35510_pdata = {
310 .pmic_backlight = NULL,/*mipi_NT35510_set_bl,*/
311};
312
313static struct platform_device mipi_dsi_NT35510_panel_device = {
314 .name = "mipi_NT35510",
315 .id = 0,
316 .dev = {
317 .platform_data = &mipi_NT35510_pdata,
318 }
319};
320
Chintan Pandya250c2e52012-01-19 17:15:49 +0530321static struct platform_device *msm_fb_devices[] __initdata = {
322 &msm_fb_device,
323 &lcdc_toshiba_panel_device,
324#ifdef CONFIG_FB_MSM_MIPI_DSI
325 &mipi_dsi_renesas_panel_device,
326#endif
327};
328
329static struct platform_device *qrd_fb_devices[] __initdata = {
330 &msm_fb_device,
331 &mipi_dsi_truly_panel_device,
332};
333
Taniya Dasc868a2e2012-01-03 10:18:47 +0530334static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530335 &msm_fb_device,
336 &mipi_dsi_NT35510_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530337};
338
Chintan Pandya250c2e52012-01-19 17:15:49 +0530339void __init msm_msm7627a_allocate_memory_regions(void)
340{
341 void *addr;
342 unsigned long fb_size;
343
344 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
345 fb_size = MSM7x25A_MSM_FB_SIZE;
346 else
347 fb_size = MSM_FB_SIZE;
348 addr = alloc_bootmem_align(fb_size, 0x1000);
349 msm_fb_resources[0].start = __pa(addr);
350 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
351 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
352 addr, __pa(addr));
353}
354
355static struct msm_panel_common_pdata mdp_pdata = {
356 .gpio = 97,
357 .mdp_rev = MDP_REV_303,
358};
359
360#define GPIO_LCDC_BRDG_PD 128
361#define GPIO_LCDC_BRDG_RESET_N 129
362#define GPIO_LCD_DSI_SEL 125
363#define LCDC_RESET_PHYS 0x90008014
364
365static void __iomem *lcdc_reset_ptr;
366
367static unsigned mipi_dsi_gpio[] = {
368 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
369 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
370 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
371 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
372};
373
374static unsigned lcd_dsi_sel_gpio[] = {
375 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
376 GPIO_CFG_2MA),
377};
378
379enum {
380 DSI_SINGLE_LANE = 1,
381 DSI_TWO_LANES,
382};
383
384static int msm_fb_get_lane_config(void)
385{
386 /* For MSM7627A SURF/FFA and QRD */
387 int rc = DSI_TWO_LANES;
388 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
389 rc = DSI_SINGLE_LANE;
390 pr_info("DSI_SINGLE_LANES\n");
391 } else {
392 pr_info("DSI_TWO_LANES\n");
393 }
394 return rc;
395}
396
397static int msm_fb_dsi_client_msm_reset(void)
398{
399 int rc = 0;
400
401 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
402 if (rc < 0) {
403 pr_err("failed to request lcd brdg reset_n\n");
404 return rc;
405 }
406
407 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
408 if (rc < 0) {
409 pr_err("failed to request lcd brdg pd\n");
410 return rc;
411 }
412
413 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
414 if (rc) {
415 pr_err("Failed to enable LCDC Bridge reset enable\n");
416 goto gpio_error;
417 }
418
419 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
420 if (rc) {
421 pr_err("Failed to enable LCDC Bridge pd enable\n");
422 goto gpio_error2;
423 }
424
425 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
426 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
427 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
428
429 if (!rc) {
430 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
431 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
432 sizeof(uint32_t));
433
434 if (!lcdc_reset_ptr)
435 return 0;
436 }
437 return rc;
438 } else {
439 goto gpio_error;
440 }
441
442gpio_error2:
443 pr_err("Failed GPIO bridge pd\n");
444 gpio_free(GPIO_LCDC_BRDG_PD);
445
446gpio_error:
447 pr_err("Failed GPIO bridge reset\n");
448 gpio_free(GPIO_LCDC_BRDG_RESET_N);
449 return rc;
450}
451
452static int mipi_truly_sel_mode(int video_mode)
453{
454 int rc = 0;
455
456 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
457 if (rc < 0)
458 goto gpio_error;
459
460 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
461 if (rc)
462 goto gpio_error;
463
464 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
465 if (!rc) {
466 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
467 return rc;
468 } else {
469 goto gpio_error;
470 }
471
472gpio_error:
473 pr_err("mipi_truly_sel_mode failed\n");
474 gpio_free(GPIO_LCD_DSI_SEL);
475 return rc;
476}
477
478static int msm_fb_dsi_client_qrd1_reset(void)
479{
480 int rc = 0;
481
482 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
483 if (rc < 0) {
484 pr_err("failed to request lcd brdg reset_n\n");
485 return rc;
486 }
487
488 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
489 if (rc < 0) {
490 pr_err("Failed to enable LCDC Bridge reset enable\n");
491 return rc;
492 }
493
494 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
495 if (rc < 0) {
496 pr_err("Failed GPIO bridge pd\n");
497 gpio_free(GPIO_LCDC_BRDG_RESET_N);
498 return rc;
499 }
500
501 mipi_truly_sel_mode(1);
502
503 return rc;
504}
505
Jeevan Shrirame941df42012-01-23 12:40:21 +0530506#define GPIO_QRD3_LCD_BRDG_RESET_N 85
507#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
508#define GPIO_QRD3_LCD_EXT_2V85_EN 35
509#define GPIO_QRD3_LCD_EXT_1V8_EN 40
510
511static unsigned qrd3_mipi_dsi_gpio[] = {
512 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
513 GPIO_CFG_NO_PULL,
514 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
515 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
516 GPIO_CFG_NO_PULL,
517 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
518 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
519 GPIO_CFG_NO_PULL,
520 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
521 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
522 GPIO_CFG_NO_PULL,
523 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
524};
525
526static int msm_fb_dsi_client_qrd3_reset(void)
527{
528 int rc = 0;
529
530 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
531 if (rc < 0) {
532 pr_err("failed to request qrd3 lcd brdg reset_n\n");
533 return rc;
534 }
535
536 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
537 if (rc < 0) {
538 pr_err("Failed to enable LCD Bridge reset enable\n");
539 return rc;
540 }
541
542 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
543 if (rc < 0) {
544 pr_err("Failed GPIO bridge Reset\n");
545 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
546 return rc;
547 }
548
549 return rc;
550}
551
Chintan Pandya250c2e52012-01-19 17:15:49 +0530552static int msm_fb_dsi_client_reset(void)
553{
554 int rc = 0;
555
556 if (machine_is_msm7627a_qrd1())
557 rc = msm_fb_dsi_client_qrd1_reset();
Jeevan Shrirame941df42012-01-23 12:40:21 +0530558 else if (machine_is_msm7627a_evb())
559 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +0530560 else
561 rc = msm_fb_dsi_client_msm_reset();
562
563 return rc;
564
565}
566
567static struct regulator_bulk_data regs_dsi[] = {
568 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
569 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
570};
571
572static int dsi_gpio_initialized;
573
574static int mipi_dsi_panel_msm_power(int on)
575{
576 int rc = 0;
577 uint32_t lcdc_reset_cfg;
578
579 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
580 if (unlikely(!dsi_gpio_initialized)) {
581 pmapp_disp_backlight_init();
582
583 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
584 if (rc < 0) {
585 pr_err("failed to request gpio_disp_pwr\n");
586 return rc;
587 }
588
589 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
590 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
591 if (rc < 0) {
592 pr_err("failed to enable display pwr\n");
593 goto fail_gpio1;
594 }
595
596 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
597 if (rc < 0) {
598 pr_err("failed to request gpio_bkl_en\n");
599 goto fail_gpio1;
600 }
601
602 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
603 if (rc < 0) {
604 pr_err("failed to enable backlight\n");
605 goto fail_gpio2;
606 }
607 }
608
609 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
610 if (rc) {
611 pr_err("%s: could not get regulators: %d\n",
612 __func__, rc);
613 goto fail_gpio2;
614 }
615
616 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
617 regs_dsi);
618 if (rc) {
619 pr_err("%s: could not set voltages: %d\n",
620 __func__, rc);
621 goto fail_vreg;
622 }
623 if (pmapp_disp_backlight_set_brightness(100))
624 pr_err("backlight set brightness failed\n");
625
626 dsi_gpio_initialized = 1;
627 }
628 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
629 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
630 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
631 } else if (machine_is_msm7x27a_ffa() ||
632 machine_is_msm7625a_ffa()) {
633 if (on) {
634 /* This line drives an active low pin on FFA */
635 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
636 if (rc < 0)
637 pr_err("failed to set direction for "
638 "display pwr\n");
639 } else {
640 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
641 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
642 if (rc < 0)
643 pr_err("failed to set direction for "
644 "display pwr\n");
645 }
646 }
647
648 if (on) {
649 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
650
651 if (machine_is_msm7x27a_surf() ||
652 machine_is_msm7625a_surf()) {
653 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
654 rmb();
655 lcdc_reset_cfg &= ~1;
656
657 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
658 msleep(20);
659 wmb();
660 lcdc_reset_cfg |= 1;
661 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
662 } else {
663 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
664 msleep(20);
665 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
666 }
667 } else {
668 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +0530669 }
670
671 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
672 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
673
674 if (rc)
675 pr_err("%s: could not %sable regulators: %d\n",
676 __func__, on ? "en" : "dis", rc);
677
678 return rc;
679fail_vreg:
680 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
681fail_gpio2:
682 gpio_free(GPIO_BACKLIGHT_EN);
683fail_gpio1:
684 gpio_free(GPIO_DISPLAY_PWR_EN);
685 dsi_gpio_initialized = 0;
686 return rc;
687}
688
689static int mipi_dsi_panel_qrd1_power(int on)
690{
691 int rc = 0;
692
693 if (!dsi_gpio_initialized) {
694 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
695 if (rc < 0)
696 return rc;
697
698 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
699 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
700 GPIO_CFG_ENABLE);
701 if (rc < 0) {
702 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
703 return rc;
704 }
705
706 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
707 if (rc < 0) {
708 pr_err("failed to enable backlight\n");
709 gpio_free(QRD_GPIO_BACKLIGHT_EN);
710 return rc;
711 }
712 dsi_gpio_initialized = 1;
713 }
714
715 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
716
Jeevan Shrirame941df42012-01-23 12:40:21 +0530717 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530718 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
719 msleep(20);
720 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
721 msleep(20);
722 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
723
724 }
725
726 return rc;
727}
728
Jeevan Shrirame941df42012-01-23 12:40:21 +0530729static int qrd3_dsi_gpio_initialized;
730
731static int mipi_dsi_panel_qrd3_power(int on)
732{
733 int rc = 0;
734
735 if (!qrd3_dsi_gpio_initialized) {
736 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
737 "qrd3_gpio_bkl_en");
738 if (rc < 0)
739 return rc;
740
741 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
742 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
743 GPIO_CFG_ENABLE);
744 if (rc < 0) {
745 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
746 return rc;
747 }
748 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
749 if (rc < 0) {
750 pr_err("failed to enable backlight\n");
751 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
752 return rc;
753 }
754
755 rc = gpio_request(GPIO_QRD3_LCD_EXT_2V85_EN,
756 "qrd3_gpio_ext_2v85_en");
757 if (rc < 0)
758 return rc;
759
760 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0,
761 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
762 GPIO_CFG_ENABLE);
763 if (rc < 0) {
764 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_2V85_EN tlmm config\n");
765 return rc;
766 }
767
768 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_2V85_EN, 1);
769 if (rc < 0) {
770 pr_err("failed to enable external 2V85\n");
771 gpio_free(GPIO_QRD3_LCD_EXT_2V85_EN);
772 return rc;
773 }
774
775 rc = gpio_request(GPIO_QRD3_LCD_EXT_1V8_EN,
776 "qrd3_gpio_ext_1v8_en");
777 if (rc < 0)
778 return rc;
779
780 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0,
781 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
782 GPIO_CFG_ENABLE);
783 if (rc < 0) {
784 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_1V8_EN tlmm config\n");
785 return rc;
786 }
787
788 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_1V8_EN, 1);
789 if (rc < 0) {
790 pr_err("failed to enable external 1v8\n");
791 gpio_free(GPIO_QRD3_LCD_EXT_1V8_EN);
792 return rc;
793 }
794
795 qrd3_dsi_gpio_initialized = 1;
796 }
797
798 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, !!on);
799 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_2V85_EN, !!on);
800 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_1V8_EN, !!on);
801
802 if (on) {
803 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
804 msleep(20);
805 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
806 msleep(20);
807 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
808 msleep(20);
809 }
810
811 return rc;
812}
813
Chintan Pandya250c2e52012-01-19 17:15:49 +0530814static int mipi_dsi_panel_power(int on)
815{
816 int rc = 0;
817
818 if (machine_is_msm7627a_qrd1())
819 rc = mipi_dsi_panel_qrd1_power(on);
Jeevan Shrirame941df42012-01-23 12:40:21 +0530820 else if (machine_is_msm7627a_evb())
821 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +0530822 else
823 rc = mipi_dsi_panel_msm_power(on);
824 return rc;
825}
826
827#define MDP_303_VSYNC_GPIO 97
828
829#ifdef CONFIG_FB_MSM_MDP303
830static struct mipi_dsi_platform_data mipi_dsi_pdata = {
831 .vsync_gpio = MDP_303_VSYNC_GPIO,
832 .dsi_power_save = mipi_dsi_panel_power,
833 .dsi_client_reset = msm_fb_dsi_client_reset,
834 .get_lane_config = msm_fb_get_lane_config,
835};
836#endif
837
838void __init msm_fb_add_devices(void)
839{
840 if (machine_is_msm7627a_qrd1())
841 platform_add_devices(qrd_fb_devices,
842 ARRAY_SIZE(qrd_fb_devices));
Taniya Dasc868a2e2012-01-03 10:18:47 +0530843 else if (machine_is_msm7627a_evb())
844 platform_add_devices(evb_fb_devices,
845 ARRAY_SIZE(evb_fb_devices));
Chintan Pandya250c2e52012-01-19 17:15:49 +0530846 else
847 platform_add_devices(msm_fb_devices,
848 ARRAY_SIZE(msm_fb_devices));
849
850 msm_fb_register_device("mdp", &mdp_pdata);
851 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf())
852 msm_fb_register_device("lcdc", &lcdc_pdata);
853#ifdef CONFIG_FB_MSM_MDP303
854 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
855#endif
856}