blob: bf1a4c5d2b870ca833b3faecf8dcf8470240e8b9 [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
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053031#define MSM_FB_SIZE 0x261000
Chintan Pandya250c2e52012-01-19 17:15:49 +053032#define MSM7x25A_MSM_FB_SIZE 0xE1000
33#else
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053034#define MSM_FB_SIZE 0x196000
Chintan Pandya250c2e52012-01-19 17:15:49 +053035#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
Chintan Pandya250c2e52012-01-19 17:15:49 +0530211#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
212#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
213
214static int msm_fb_detect_panel(const char *name)
215{
216 int ret = -ENODEV;
217
Taniya Dase3027e22012-02-27 16:32:27 +0530218 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
219 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530220 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;
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530229 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530230 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() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530238 machine_is_msm7625a_surf() ||
239 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530240 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
241 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
242 PANEL_NAME_MAX_LEN)))
243 return 0;
244 }
245#endif
246
247 return ret;
248}
249
250static int mipi_truly_set_bl(int on)
251{
252 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
253
254 return 1;
255}
256
257static struct msm_fb_platform_data msm_fb_pdata = {
258 .detect_client = msm_fb_detect_panel,
259};
260
261static struct platform_device msm_fb_device = {
262 .name = "msm_fb",
263 .id = 0,
264 .num_resources = ARRAY_SIZE(msm_fb_resources),
265 .resource = msm_fb_resources,
266 .dev = {
267 .platform_data = &msm_fb_pdata,
268 }
269};
270
271#ifdef CONFIG_FB_MSM_MIPI_DSI
272static int mipi_renesas_set_bl(int level)
273{
274 int ret;
275
276 ret = pmapp_disp_backlight_set_brightness(level);
277
278 if (ret)
279 pr_err("%s: can't set lcd backlight!\n", __func__);
280
281 return ret;
282}
283
284static struct msm_panel_common_pdata mipi_renesas_pdata = {
285 .pmic_backlight = mipi_renesas_set_bl,
286};
287
288
289static struct platform_device mipi_dsi_renesas_panel_device = {
290 .name = "mipi_renesas",
291 .id = 0,
292 .dev = {
293 .platform_data = &mipi_renesas_pdata,
294 }
295};
296#endif
297
298static struct msm_panel_common_pdata mipi_truly_pdata = {
299 .pmic_backlight = mipi_truly_set_bl,
300};
301
302static struct platform_device mipi_dsi_truly_panel_device = {
303 .name = "mipi_truly",
304 .id = 0,
305 .dev = {
306 .platform_data = &mipi_truly_pdata,
307 }
308};
309
Jeevan Shrirame941df42012-01-23 12:40:21 +0530310static struct msm_panel_common_pdata mipi_NT35510_pdata = {
311 .pmic_backlight = NULL,/*mipi_NT35510_set_bl,*/
312};
313
314static struct platform_device mipi_dsi_NT35510_panel_device = {
315 .name = "mipi_NT35510",
316 .id = 0,
317 .dev = {
318 .platform_data = &mipi_NT35510_pdata,
319 }
320};
321
Chintan Pandya250c2e52012-01-19 17:15:49 +0530322static struct platform_device *msm_fb_devices[] __initdata = {
323 &msm_fb_device,
324 &lcdc_toshiba_panel_device,
325#ifdef CONFIG_FB_MSM_MIPI_DSI
326 &mipi_dsi_renesas_panel_device,
327#endif
328};
329
330static struct platform_device *qrd_fb_devices[] __initdata = {
331 &msm_fb_device,
332 &mipi_dsi_truly_panel_device,
333};
334
Taniya Dasc868a2e2012-01-03 10:18:47 +0530335static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530336 &msm_fb_device,
337 &mipi_dsi_NT35510_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530338};
339
Chintan Pandya250c2e52012-01-19 17:15:49 +0530340void __init msm_msm7627a_allocate_memory_regions(void)
341{
342 void *addr;
343 unsigned long fb_size;
344
345 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
346 fb_size = MSM7x25A_MSM_FB_SIZE;
347 else
348 fb_size = MSM_FB_SIZE;
349 addr = alloc_bootmem_align(fb_size, 0x1000);
350 msm_fb_resources[0].start = __pa(addr);
351 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
352 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
353 addr, __pa(addr));
354}
355
356static struct msm_panel_common_pdata mdp_pdata = {
357 .gpio = 97,
358 .mdp_rev = MDP_REV_303,
359};
360
361#define GPIO_LCDC_BRDG_PD 128
362#define GPIO_LCDC_BRDG_RESET_N 129
363#define GPIO_LCD_DSI_SEL 125
364#define LCDC_RESET_PHYS 0x90008014
365
366static void __iomem *lcdc_reset_ptr;
367
368static unsigned mipi_dsi_gpio[] = {
369 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
370 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
371 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
372 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
373};
374
375static unsigned lcd_dsi_sel_gpio[] = {
376 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
377 GPIO_CFG_2MA),
378};
379
380enum {
381 DSI_SINGLE_LANE = 1,
382 DSI_TWO_LANES,
383};
384
385static int msm_fb_get_lane_config(void)
386{
387 /* For MSM7627A SURF/FFA and QRD */
388 int rc = DSI_TWO_LANES;
389 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
390 rc = DSI_SINGLE_LANE;
391 pr_info("DSI_SINGLE_LANES\n");
392 } else {
393 pr_info("DSI_TWO_LANES\n");
394 }
395 return rc;
396}
397
398static int msm_fb_dsi_client_msm_reset(void)
399{
400 int rc = 0;
401
402 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
403 if (rc < 0) {
404 pr_err("failed to request lcd brdg reset_n\n");
405 return rc;
406 }
407
408 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
409 if (rc < 0) {
410 pr_err("failed to request lcd brdg pd\n");
411 return rc;
412 }
413
414 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
415 if (rc) {
416 pr_err("Failed to enable LCDC Bridge reset enable\n");
417 goto gpio_error;
418 }
419
420 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
421 if (rc) {
422 pr_err("Failed to enable LCDC Bridge pd enable\n");
423 goto gpio_error2;
424 }
425
426 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
427 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
428 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
429
430 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530431 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
432 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530433 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
434 sizeof(uint32_t));
435
436 if (!lcdc_reset_ptr)
437 return 0;
438 }
439 return rc;
440 } else {
441 goto gpio_error;
442 }
443
444gpio_error2:
445 pr_err("Failed GPIO bridge pd\n");
446 gpio_free(GPIO_LCDC_BRDG_PD);
447
448gpio_error:
449 pr_err("Failed GPIO bridge reset\n");
450 gpio_free(GPIO_LCDC_BRDG_RESET_N);
451 return rc;
452}
453
454static int mipi_truly_sel_mode(int video_mode)
455{
456 int rc = 0;
457
458 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
459 if (rc < 0)
460 goto gpio_error;
461
462 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
463 if (rc)
464 goto gpio_error;
465
466 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
467 if (!rc) {
468 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
469 return rc;
470 } else {
471 goto gpio_error;
472 }
473
474gpio_error:
475 pr_err("mipi_truly_sel_mode failed\n");
476 gpio_free(GPIO_LCD_DSI_SEL);
477 return rc;
478}
479
480static int msm_fb_dsi_client_qrd1_reset(void)
481{
482 int rc = 0;
483
484 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
485 if (rc < 0) {
486 pr_err("failed to request lcd brdg reset_n\n");
487 return rc;
488 }
489
490 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
491 if (rc < 0) {
492 pr_err("Failed to enable LCDC Bridge reset enable\n");
493 return rc;
494 }
495
496 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
497 if (rc < 0) {
498 pr_err("Failed GPIO bridge pd\n");
499 gpio_free(GPIO_LCDC_BRDG_RESET_N);
500 return rc;
501 }
502
503 mipi_truly_sel_mode(1);
504
505 return rc;
506}
507
Jeevan Shrirame941df42012-01-23 12:40:21 +0530508#define GPIO_QRD3_LCD_BRDG_RESET_N 85
509#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
510#define GPIO_QRD3_LCD_EXT_2V85_EN 35
511#define GPIO_QRD3_LCD_EXT_1V8_EN 40
512
513static unsigned qrd3_mipi_dsi_gpio[] = {
514 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
515 GPIO_CFG_NO_PULL,
516 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
517 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
518 GPIO_CFG_NO_PULL,
519 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
520 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
521 GPIO_CFG_NO_PULL,
522 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
523 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
524 GPIO_CFG_NO_PULL,
525 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
526};
527
528static int msm_fb_dsi_client_qrd3_reset(void)
529{
530 int rc = 0;
531
532 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
533 if (rc < 0) {
534 pr_err("failed to request qrd3 lcd brdg reset_n\n");
535 return rc;
536 }
537
Jeevan Shrirame941df42012-01-23 12:40:21 +0530538 return rc;
539}
540
Chintan Pandya250c2e52012-01-19 17:15:49 +0530541static int msm_fb_dsi_client_reset(void)
542{
543 int rc = 0;
544
545 if (machine_is_msm7627a_qrd1())
546 rc = msm_fb_dsi_client_qrd1_reset();
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530547 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Jeevan Shrirame941df42012-01-23 12:40:21 +0530548 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +0530549 else
550 rc = msm_fb_dsi_client_msm_reset();
551
552 return rc;
553
554}
555
556static struct regulator_bulk_data regs_dsi[] = {
557 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
558 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
559};
560
561static int dsi_gpio_initialized;
562
563static int mipi_dsi_panel_msm_power(int on)
564{
565 int rc = 0;
566 uint32_t lcdc_reset_cfg;
567
568 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
569 if (unlikely(!dsi_gpio_initialized)) {
570 pmapp_disp_backlight_init();
571
572 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
573 if (rc < 0) {
574 pr_err("failed to request gpio_disp_pwr\n");
575 return rc;
576 }
577
Taniya Dase3027e22012-02-27 16:32:27 +0530578 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
579 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530580 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
581 if (rc < 0) {
582 pr_err("failed to enable display pwr\n");
583 goto fail_gpio1;
584 }
585
586 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
587 if (rc < 0) {
588 pr_err("failed to request gpio_bkl_en\n");
589 goto fail_gpio1;
590 }
591
592 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
593 if (rc < 0) {
594 pr_err("failed to enable backlight\n");
595 goto fail_gpio2;
596 }
597 }
598
599 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
600 if (rc) {
601 pr_err("%s: could not get regulators: %d\n",
602 __func__, rc);
603 goto fail_gpio2;
604 }
605
606 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
607 regs_dsi);
608 if (rc) {
609 pr_err("%s: could not set voltages: %d\n",
610 __func__, rc);
611 goto fail_vreg;
612 }
613 if (pmapp_disp_backlight_set_brightness(100))
614 pr_err("backlight set brightness failed\n");
615
616 dsi_gpio_initialized = 1;
617 }
Taniya Dase3027e22012-02-27 16:32:27 +0530618 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
619 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530620 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
621 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
622 } else if (machine_is_msm7x27a_ffa() ||
623 machine_is_msm7625a_ffa()) {
624 if (on) {
625 /* This line drives an active low pin on FFA */
626 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
627 if (rc < 0)
628 pr_err("failed to set direction for "
629 "display pwr\n");
630 } else {
631 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
632 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
633 if (rc < 0)
634 pr_err("failed to set direction for "
635 "display pwr\n");
636 }
637 }
638
639 if (on) {
640 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
641
642 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530643 machine_is_msm7625a_surf() ||
644 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530645 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
646 rmb();
647 lcdc_reset_cfg &= ~1;
648
649 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
650 msleep(20);
651 wmb();
652 lcdc_reset_cfg |= 1;
653 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
654 } else {
655 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
656 msleep(20);
657 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
658 }
659 } else {
660 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +0530661 }
662
663 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
664 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
665
666 if (rc)
667 pr_err("%s: could not %sable regulators: %d\n",
668 __func__, on ? "en" : "dis", rc);
669
670 return rc;
671fail_vreg:
672 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
673fail_gpio2:
674 gpio_free(GPIO_BACKLIGHT_EN);
675fail_gpio1:
676 gpio_free(GPIO_DISPLAY_PWR_EN);
677 dsi_gpio_initialized = 0;
678 return rc;
679}
680
681static int mipi_dsi_panel_qrd1_power(int on)
682{
683 int rc = 0;
684
685 if (!dsi_gpio_initialized) {
686 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
687 if (rc < 0)
688 return rc;
689
690 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
691 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
692 GPIO_CFG_ENABLE);
693 if (rc < 0) {
694 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
695 return rc;
696 }
697
698 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
699 if (rc < 0) {
700 pr_err("failed to enable backlight\n");
701 gpio_free(QRD_GPIO_BACKLIGHT_EN);
702 return rc;
703 }
704 dsi_gpio_initialized = 1;
705 }
706
707 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
708
Jeevan Shrirame941df42012-01-23 12:40:21 +0530709 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530710 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
711 msleep(20);
712 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
713 msleep(20);
714 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
715
716 }
717
718 return rc;
719}
720
Jeevan Shrirame941df42012-01-23 12:40:21 +0530721static int qrd3_dsi_gpio_initialized;
722
723static int mipi_dsi_panel_qrd3_power(int on)
724{
725 int rc = 0;
726
727 if (!qrd3_dsi_gpio_initialized) {
728 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
729 "qrd3_gpio_bkl_en");
730 if (rc < 0)
731 return rc;
732
733 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
734 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
735 GPIO_CFG_ENABLE);
736 if (rc < 0) {
737 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
738 return rc;
739 }
740 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
741 if (rc < 0) {
742 pr_err("failed to enable backlight\n");
743 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
744 return rc;
745 }
746
747 rc = gpio_request(GPIO_QRD3_LCD_EXT_2V85_EN,
748 "qrd3_gpio_ext_2v85_en");
749 if (rc < 0)
750 return rc;
751
752 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0,
753 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
754 GPIO_CFG_ENABLE);
755 if (rc < 0) {
756 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_2V85_EN tlmm config\n");
757 return rc;
758 }
759
760 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_2V85_EN, 1);
761 if (rc < 0) {
762 pr_err("failed to enable external 2V85\n");
763 gpio_free(GPIO_QRD3_LCD_EXT_2V85_EN);
764 return rc;
765 }
766
767 rc = gpio_request(GPIO_QRD3_LCD_EXT_1V8_EN,
768 "qrd3_gpio_ext_1v8_en");
769 if (rc < 0)
770 return rc;
771
772 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0,
773 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
774 GPIO_CFG_ENABLE);
775 if (rc < 0) {
776 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_1V8_EN tlmm config\n");
777 return rc;
778 }
779
780 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_1V8_EN, 1);
781 if (rc < 0) {
782 pr_err("failed to enable external 1v8\n");
783 gpio_free(GPIO_QRD3_LCD_EXT_1V8_EN);
784 return rc;
785 }
786
787 qrd3_dsi_gpio_initialized = 1;
788 }
789
790 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, !!on);
791 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_2V85_EN, !!on);
792 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_1V8_EN, !!on);
793
794 if (on) {
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +0530795 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
796
797 if (rc < 0) {
798 pr_err("Failed to enable LCD Bridge reset enable\n");
799 return rc;
800 }
801
802 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
803
804 if (rc < 0) {
805 pr_err("Failed GPIO bridge Reset\n");
806 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
807 return rc;
808 }
809
Jeevan Shrirame941df42012-01-23 12:40:21 +0530810 msleep(20);
811 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
812 msleep(20);
813 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
814 msleep(20);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +0530815 } else {
816 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
817 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
818 GPIO_CFG_DISABLE);
Jeevan Shrirame941df42012-01-23 12:40:21 +0530819 }
820
821 return rc;
822}
823
Chintan Pandya250c2e52012-01-19 17:15:49 +0530824static int mipi_dsi_panel_power(int on)
825{
826 int rc = 0;
827
828 if (machine_is_msm7627a_qrd1())
829 rc = mipi_dsi_panel_qrd1_power(on);
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530830 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Jeevan Shrirame941df42012-01-23 12:40:21 +0530831 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +0530832 else
833 rc = mipi_dsi_panel_msm_power(on);
834 return rc;
835}
836
837#define MDP_303_VSYNC_GPIO 97
838
839#ifdef CONFIG_FB_MSM_MDP303
840static struct mipi_dsi_platform_data mipi_dsi_pdata = {
841 .vsync_gpio = MDP_303_VSYNC_GPIO,
842 .dsi_power_save = mipi_dsi_panel_power,
843 .dsi_client_reset = msm_fb_dsi_client_reset,
844 .get_lane_config = msm_fb_get_lane_config,
845};
846#endif
847
848void __init msm_fb_add_devices(void)
849{
850 if (machine_is_msm7627a_qrd1())
851 platform_add_devices(qrd_fb_devices,
852 ARRAY_SIZE(qrd_fb_devices));
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530853 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Taniya Dasc868a2e2012-01-03 10:18:47 +0530854 platform_add_devices(evb_fb_devices,
855 ARRAY_SIZE(evb_fb_devices));
Chintan Pandyab1bad0e2012-02-06 19:04:51 +0530856 else if (machine_is_msm7627a_qrd3())
857 return;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530858 else
859 platform_add_devices(msm_fb_devices,
860 ARRAY_SIZE(msm_fb_devices));
861
862 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +0530863 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
864 machine_is_msm8625_surf())
Chintan Pandya250c2e52012-01-19 17:15:49 +0530865 msm_fb_register_device("lcdc", &lcdc_pdata);
866#ifdef CONFIG_FB_MSM_MDP303
867 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
868#endif
869}