blob: 52ab97dbc63685cec1c77591cb27f7737079c2d0 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Chintan Pandya250c2e52012-01-19 17:15:49 +05302 *
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>
Steve Mucklef132c6c2012-06-06 18:30:57 -070018#include <linux/gpio.h>
Chintan Pandya250c2e52012-01-19 17:15:49 +053019#include <asm/mach-types.h>
20#include <asm/io.h>
21#include <mach/msm_bus_board.h>
22#include <mach/msm_memtypes.h>
23#include <mach/board.h>
Chintan Pandya250c2e52012-01-19 17:15:49 +053024#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
Jeevan Shriram8c23e072012-03-14 11:35:49 +053031#define MSM_FB_SIZE 0x4BF000
32#define MSM7x25A_MSM_FB_SIZE 0x1C2000
33#define MSM8x25_MSM_FB_SIZE 0x5FA000
Chintan Pandya250c2e52012-01-19 17:15:49 +053034#else
Jeevan Shriram8c23e072012-03-14 11:35:49 +053035#define MSM_FB_SIZE 0x32A000
36#define MSM7x25A_MSM_FB_SIZE 0x12C000
37#define MSM8x25_MSM_FB_SIZE 0x3FC000
Chintan Pandya250c2e52012-01-19 17:15:49 +053038#endif
39
Alhad Purnapatrec55856c2012-02-28 13:24:57 -080040/*
41 * Reserve enough v4l2 space for a double buffered full screen
42 * res image (864x480x1.5x2)
43 */
44#define MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE 1244160
45
Chintan Pandya250c2e52012-01-19 17:15:49 +053046static unsigned fb_size = MSM_FB_SIZE;
47static int __init fb_size_setup(char *p)
48{
49 fb_size = memparse(p, NULL);
50 return 0;
51}
52
53early_param("fb_size", fb_size_setup);
54
Jeevan Shriram901a15f2012-03-09 11:53:23 +053055static uint32_t lcdc_truly_gpio_initialized;
56static struct regulator_bulk_data regs_truly_lcdc[] = {
57 { .supply = "rfrx1", .min_uV = 1800000, .max_uV = 1800000 },
58};
59
60#define SKU3_LCDC_GPIO_DISPLAY_RESET 90
61#define SKU3_LCDC_GPIO_SPI_MOSI 19
62#define SKU3_LCDC_GPIO_SPI_CLK 20
63#define SKU3_LCDC_GPIO_SPI_CS0_N 21
64#define SKU3_LCDC_LCD_CAMERA_LDO_2V8 35 /*LCD_CAMERA_LDO_2V8*/
65#define SKU3_LCDC_LCD_CAMERA_LDO_1V8 34 /*LCD_CAMERA_LDO_1V8*/
66#define SKU3_1_LCDC_LCD_CAMERA_LDO_1V8 58 /*LCD_CAMERA_LDO_1V8*/
67
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +053068static struct regulator *gpio_reg_2p85v_sku3, *gpio_reg_1p8v_sku3;
69
Jeevan Shriram901a15f2012-03-09 11:53:23 +053070static uint32_t lcdc_truly_gpio_table[] = {
71 19,
72 20,
73 21,
74 89,
75 90,
76};
77
78static char *lcdc_gpio_name_table[5] = {
79 "spi_mosi",
80 "spi_clk",
81 "spi_cs",
82 "gpio_bkl_en",
83 "gpio_disp_reset",
84};
85
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +053086static char lcdc_splash_is_enabled(void);
Jeevan Shriram901a15f2012-03-09 11:53:23 +053087static int lcdc_truly_gpio_init(void)
88{
89 int i;
90 int rc = 0;
91
92 if (!lcdc_truly_gpio_initialized) {
93 for (i = 0; i < ARRAY_SIZE(lcdc_truly_gpio_table); i++) {
94 rc = gpio_request(lcdc_truly_gpio_table[i],
95 lcdc_gpio_name_table[i]);
96 if (rc < 0) {
97 pr_err("Error request gpio %s\n",
98 lcdc_gpio_name_table[i]);
99 goto truly_gpio_fail;
100 }
101 rc = gpio_tlmm_config(GPIO_CFG(lcdc_truly_gpio_table[i],
102 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
103 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
104 if (rc < 0) {
105 pr_err("Error config lcdc gpio:%d\n",
106 lcdc_truly_gpio_table[i]);
107 goto truly_gpio_fail;
108 }
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530109 if (lcdc_splash_is_enabled())
110 rc = gpio_direction_output(
111 lcdc_truly_gpio_table[i], 1);
112 else
113 rc = gpio_direction_output(
114 lcdc_truly_gpio_table[i], 0);
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530115 if (rc < 0) {
116 pr_err("Error direct lcdc gpio:%d\n",
117 lcdc_truly_gpio_table[i]);
118 goto truly_gpio_fail;
119 }
120 }
121
122 lcdc_truly_gpio_initialized = 1;
123 }
124
125 return rc;
126
127truly_gpio_fail:
128 for (; i >= 0; i--) {
129 pr_err("Freeing GPIO: %d", lcdc_truly_gpio_table[i]);
130 gpio_free(lcdc_truly_gpio_table[i]);
131 }
132
133 lcdc_truly_gpio_initialized = 0;
134 return rc;
135}
136
137
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530138void sku3_lcdc_power_init(void)
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530139{
140 int rc = 0;
141 u32 socinfo = socinfo_get_platform_type();
142
143 /* LDO_EXT2V8 */
144 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
145 pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
146 return;
147 }
148
149 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0,
150 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
151 GPIO_CFG_ENABLE);
152
153 if (rc < 0) {
154 pr_err("%s:unable to enable lcd_camera_ldo_2v8!\n", __func__);
155 goto fail_gpio2;
156 }
157
158 /* LDO_EVT1V8 */
159 if (socinfo == 0x0B) {
160 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
161 "lcd_camera_ldo_1v8")) {
162 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
163 goto fail_gpio1;
164 }
165
166 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_1V8, 0,
167 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
168 GPIO_CFG_ENABLE);
169
170 if (rc < 0) {
171 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
172 __func__);
173 goto fail_gpio1;
174 }
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530175 } else if (socinfo == 0x0F || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530176 if (gpio_request(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
177 "lcd_camera_ldo_1v8")) {
178 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
179 goto fail_gpio1;
180 }
181
182 rc = gpio_tlmm_config(GPIO_CFG(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
183 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
184 GPIO_CFG_ENABLE);
185
186 if (rc < 0) {
187 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
188 __func__);
189 goto fail_gpio1;
190 }
191 }
192
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530193 if (socinfo == 0x0B)
194 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
195 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
196 gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
197
198 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
199
200 gpio_reg_2p85v_sku3 = regulator_get(&msm_lcdc_device.dev,
201 "lcd_vdd_sku3");
202 if (IS_ERR(gpio_reg_2p85v_sku3)) {
203 pr_err("%s:ext_2p85v regulator get failed", __func__);
204 regulator_put(gpio_reg_2p85v_sku3);
205 return;
206 }
207
208 gpio_reg_1p8v_sku3 = regulator_get(&msm_lcdc_device.dev,
209 "lcd_vddi_sku3");
210 if (IS_ERR(gpio_reg_1p8v_sku3)) {
211 pr_err("%s:ext_1p8v regulator get failed", __func__);
212 regulator_put(gpio_reg_1p8v_sku3);
213 return;
214 }
215
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530216 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_truly_lcdc),
217 regs_truly_lcdc);
218 if (rc)
219 pr_err("%s: could not get regulators: %d\n", __func__, rc);
220
221 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_truly_lcdc),
222 regs_truly_lcdc);
223 if (rc)
224 pr_err("%s: could not set voltages: %d\n", __func__, rc);
225
226 return;
227
228fail_gpio1:
229 if (socinfo == 0x0B)
230 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530231 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530232 gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
233fail_gpio2:
234 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
235 return;
236}
237
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530238int sku3_lcdc_power_onoff(int on)
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530239{
240 int rc = 0;
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530241
242 if (on) {
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530243 rc = regulator_enable(gpio_reg_2p85v_sku3);
244 if (rc < 0) {
245 pr_err("%s: reg enable failed\n", __func__);
246 return -EINVAL;
247 }
248 rc = regulator_enable(gpio_reg_1p8v_sku3);
249 if (rc < 0) {
250 pr_err("%s: reg enable failed\n", __func__);
251 return -EINVAL;
252 }
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530253
254 rc = regulator_bulk_enable(ARRAY_SIZE(regs_truly_lcdc),
255 regs_truly_lcdc);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530256 if (rc) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530257 pr_err("%s: could not enable regulators: %d\n",
258 __func__, rc);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530259 return -EINVAL;
260 }
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530261 } else {
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530262 rc = regulator_disable(gpio_reg_2p85v_sku3);
263 if (rc < 0) {
264 pr_err("%s: reg disable failed\n", __func__);
265 return -EINVAL;
266 }
267 rc = regulator_disable(gpio_reg_1p8v_sku3);
268 if (rc < 0) {
269 pr_err("%s: reg disable failed\n", __func__);
270 return -EINVAL;
271 }
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530272
273 rc = regulator_bulk_disable(ARRAY_SIZE(regs_truly_lcdc),
274 regs_truly_lcdc);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530275 if (rc) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530276 pr_err("%s: could not disable regulators: %d\n",
277 __func__, rc);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530278 return -EINVAL;
279 }
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530280 }
281
282 return rc;
283}
284
285static int sku3_lcdc_power_save(int on)
286{
287 int rc = 0;
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530288 static int cont_splash_done;
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530289
290 if (on) {
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530291 sku3_lcdc_power_onoff(1);
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530292 rc = lcdc_truly_gpio_init();
293 if (rc < 0) {
294 pr_err("%s(): Truly GPIO initializations failed",
295 __func__);
296 return rc;
297 }
298
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530299 if (lcdc_splash_is_enabled() && !cont_splash_done) {
300 cont_splash_done = 1;
301 return rc;
302 }
303
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530304 if (lcdc_truly_gpio_initialized) {
305 /*LCD reset*/
306 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
307 msleep(20);
308 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
309 msleep(20);
310 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
311 msleep(20);
312 }
313 } else {
314 /* pull down LCD IO to avoid current leakage */
315 gpio_set_value(SKU3_LCDC_GPIO_SPI_MOSI, 0);
316 gpio_set_value(SKU3_LCDC_GPIO_SPI_CLK, 0);
317 gpio_set_value(SKU3_LCDC_GPIO_SPI_CS0_N, 0);
318 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
319
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +0530320 sku3_lcdc_power_onoff(0);
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530321 }
322 return rc;
323}
324
325static struct msm_panel_common_pdata lcdc_truly_panel_data = {
326 .panel_config_gpio = NULL,
327 .gpio_num = lcdc_truly_gpio_table,
328};
329
330static struct platform_device lcdc_truly_panel_device = {
331 .name = "lcdc_truly_hvga_ips3p2335_pt",
332 .id = 0,
333 .dev = {
334 .platform_data = &lcdc_truly_panel_data,
335 }
336};
337
Chintan Pandya250c2e52012-01-19 17:15:49 +0530338static struct regulator_bulk_data regs_lcdc[] = {
339 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
340 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
341};
342static uint32_t lcdc_gpio_initialized;
343
344static void lcdc_toshiba_gpio_init(void)
345{
346 int rc = 0;
347 if (!lcdc_gpio_initialized) {
348 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
349 pr_err("failed to request gpio spi_clk\n");
350 return;
351 }
352 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
353 pr_err("failed to request gpio spi_cs0_N\n");
354 goto fail_gpio6;
355 }
356 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
357 pr_err("failed to request gpio spi_mosi\n");
358 goto fail_gpio5;
359 }
360 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
361 pr_err("failed to request gpio spi_miso\n");
362 goto fail_gpio4;
363 }
364 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
365 pr_err("failed to request gpio_disp_pwr\n");
366 goto fail_gpio3;
367 }
368 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
369 pr_err("failed to request gpio_bkl_en\n");
370 goto fail_gpio2;
371 }
372 pmapp_disp_backlight_init();
373
374 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc),
375 regs_lcdc);
376 if (rc) {
377 pr_err("%s: could not get regulators: %d\n",
378 __func__, rc);
379 goto fail_gpio1;
380 }
381
382 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
383 regs_lcdc);
384 if (rc) {
385 pr_err("%s: could not set voltages: %d\n",
386 __func__, rc);
387 goto fail_vreg;
388 }
389 lcdc_gpio_initialized = 1;
390 }
391 return;
392fail_vreg:
393 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
394fail_gpio1:
395 gpio_free(GPIO_BACKLIGHT_EN);
396fail_gpio2:
397 gpio_free(GPIO_DISPLAY_PWR_EN);
398fail_gpio3:
399 gpio_free(GPIO_SPI_MISO);
400fail_gpio4:
401 gpio_free(GPIO_SPI_MOSI);
402fail_gpio5:
403 gpio_free(GPIO_SPI_CS0_N);
404fail_gpio6:
405 gpio_free(GPIO_SPI_CLK);
406 lcdc_gpio_initialized = 0;
407}
408
409static uint32_t lcdc_gpio_table[] = {
410 GPIO_SPI_CLK,
411 GPIO_SPI_CS0_N,
412 GPIO_SPI_MOSI,
413 GPIO_DISPLAY_PWR_EN,
414 GPIO_BACKLIGHT_EN,
415 GPIO_SPI_MISO,
416};
417
418static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
419{
420 int n;
421
422 if (lcdc_gpio_initialized) {
423 /* All are IO Expander GPIOs */
424 for (n = 0; n < (len - 1); n++)
425 gpio_direction_output(table[n], 1);
426 }
427}
428
429static void lcdc_toshiba_config_gpios(int enable)
430{
431 config_lcdc_gpio_table(lcdc_gpio_table,
432 ARRAY_SIZE(lcdc_gpio_table), enable);
433}
434
435static int msm_fb_lcdc_power_save(int on)
436{
437 int rc = 0;
438 /* Doing the init of the LCDC GPIOs very late as they are from
439 an I2C-controlled IO Expander */
440 lcdc_toshiba_gpio_init();
441
442 if (lcdc_gpio_initialized) {
443 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
444 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
445
446 rc = on ? regulator_bulk_enable(
447 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
448 regulator_bulk_disable(
449 ARRAY_SIZE(regs_lcdc), regs_lcdc);
450
451 if (rc)
452 pr_err("%s: could not %sable regulators: %d\n",
453 __func__, on ? "en" : "dis", rc);
454 }
455
456 return rc;
457}
458
459static int lcdc_toshiba_set_bl(int level)
460{
461 int ret;
462
463 ret = pmapp_disp_backlight_set_brightness(level);
464 if (ret)
465 pr_err("%s: can't set lcd backlight!\n", __func__);
466
467 return ret;
468}
469
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530470
471static int msm_lcdc_power_save(int on)
472{
473 int rc = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530474 if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530475 rc = sku3_lcdc_power_save(on);
476 else
477 rc = msm_fb_lcdc_power_save(on);
478
479 return rc;
480}
481
Chintan Pandya250c2e52012-01-19 17:15:49 +0530482static struct lcdc_platform_data lcdc_pdata = {
483 .lcdc_gpio_config = NULL,
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530484 .lcdc_power_save = msm_lcdc_power_save,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530485};
486
487static int lcd_panel_spi_gpio_num[] = {
488 GPIO_SPI_MOSI, /* spi_sdi */
489 GPIO_SPI_MISO, /* spi_sdoi */
490 GPIO_SPI_CLK, /* spi_clk */
491 GPIO_SPI_CS0_N, /* spi_cs */
492};
493
494static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
495 .panel_config_gpio = lcdc_toshiba_config_gpios,
496 .pmic_backlight = lcdc_toshiba_set_bl,
497 .gpio_num = lcd_panel_spi_gpio_num,
498};
499
500static struct platform_device lcdc_toshiba_panel_device = {
501 .name = "lcdc_toshiba_fwvga_pt",
502 .id = 0,
503 .dev = {
504 .platform_data = &lcdc_toshiba_panel_data,
505 }
506};
507
508static struct resource msm_fb_resources[] = {
509 {
510 .flags = IORESOURCE_DMA,
511 }
512};
513
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800514#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
515static struct resource msm_v4l2_video_overlay_resources[] = {
516 {
517 .flags = IORESOURCE_DMA,
518 }
519};
520#endif
521
Chintan Pandya250c2e52012-01-19 17:15:49 +0530522#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
523#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
524
525static int msm_fb_detect_panel(const char *name)
526{
527 int ret = -ENODEV;
528
Taniya Dase3027e22012-02-27 16:32:27 +0530529 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
530 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530531 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
532 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
533 ret = 0;
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +0530534 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
535 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530536 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
537 ret = 0;
538 } else if (machine_is_msm7627a_qrd1()) {
539 if (!strncmp(name, "mipi_video_truly_wvga", 21))
540 ret = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530541 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530542 if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
543 ret = 0;
Jeevan Shriram66c3c2d2012-06-12 17:46:53 +0530544 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
Channagoud Kadabi2bd65c82012-10-12 15:14:23 +0530545 machine_is_msm8625_evt() ||
546 machine_is_qrd_skud_prime()) {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530547 if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
548 ret = 0;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530549 }
550
551#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
552 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
553 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
554 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530555 machine_is_msm7625a_surf() ||
556 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530557 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
558 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
559 PANEL_NAME_MAX_LEN)))
560 return 0;
561 }
562#endif
563
564 return ret;
565}
566
567static int mipi_truly_set_bl(int on)
568{
569 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
570
571 return 1;
572}
573
574static struct msm_fb_platform_data msm_fb_pdata = {
575 .detect_client = msm_fb_detect_panel,
576};
577
578static struct platform_device msm_fb_device = {
579 .name = "msm_fb",
580 .id = 0,
581 .num_resources = ARRAY_SIZE(msm_fb_resources),
582 .resource = msm_fb_resources,
583 .dev = {
584 .platform_data = &msm_fb_pdata,
585 }
586};
587
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800588#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
589static struct platform_device msm_v4l2_video_overlay_device = {
590 .name = "msm_v4l2_overlay_pd",
591 .id = 0,
592 .num_resources = ARRAY_SIZE(msm_v4l2_video_overlay_resources),
593 .resource = msm_v4l2_video_overlay_resources,
594 };
595#endif
596
597
Chintan Pandya250c2e52012-01-19 17:15:49 +0530598#ifdef CONFIG_FB_MSM_MIPI_DSI
599static int mipi_renesas_set_bl(int level)
600{
601 int ret;
602
603 ret = pmapp_disp_backlight_set_brightness(level);
604
605 if (ret)
606 pr_err("%s: can't set lcd backlight!\n", __func__);
607
608 return ret;
609}
610
611static struct msm_panel_common_pdata mipi_renesas_pdata = {
612 .pmic_backlight = mipi_renesas_set_bl,
613};
614
615
616static struct platform_device mipi_dsi_renesas_panel_device = {
617 .name = "mipi_renesas",
618 .id = 0,
619 .dev = {
620 .platform_data = &mipi_renesas_pdata,
621 }
622};
623#endif
624
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530625static int evb_backlight_control(int level, int mode)
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530626{
627
628 int i = 0;
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530629 int remainder, ret = 0;
630
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530631 /* device address byte = 0x72 */
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530632 if (!mode) {
633 gpio_set_value(96, 0);
634 udelay(67);
635 gpio_set_value(96, 1);
636 udelay(33);
637 gpio_set_value(96, 0);
638 udelay(33);
639 gpio_set_value(96, 1);
640 udelay(67);
641 gpio_set_value(96, 0);
642 udelay(33);
643 gpio_set_value(96, 1);
644 udelay(67);
645 gpio_set_value(96, 0);
646 udelay(33);
647 gpio_set_value(96, 1);
648 udelay(67);
649 gpio_set_value(96, 0);
650 udelay(67);
651 gpio_set_value(96, 1);
652 udelay(33);
653 gpio_set_value(96, 0);
654 udelay(67);
655 gpio_set_value(96, 1);
656 udelay(33);
657 gpio_set_value(96, 0);
658 udelay(33);
659 gpio_set_value(96, 1);
660 udelay(67);
661 gpio_set_value(96, 0);
662 udelay(67);
663 gpio_set_value(96, 1);
664 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530665
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530666 /* t-EOS and t-start */
667 gpio_set_value(96, 0);
668 ndelay(4200);
669 gpio_set_value(96, 1);
670 ndelay(9000);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530671
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530672 /* data byte */
673 /* RFA = 0 */
674 gpio_set_value(96, 0);
675 udelay(67);
676 gpio_set_value(96, 1);
677 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530678
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530679 /* Address bits */
680 gpio_set_value(96, 0);
681 udelay(67);
682 gpio_set_value(96, 1);
683 udelay(33);
684 gpio_set_value(96, 0);
685 udelay(67);
686 gpio_set_value(96, 1);
687 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530688
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530689 /* Data bits */
690 for (i = 0; i < 5; i++) {
691 remainder = (level) & (16);
692 if (remainder) {
693 gpio_set_value(96, 0);
694 udelay(33);
695 gpio_set_value(96, 1);
696 udelay(67);
697 } else {
698 gpio_set_value(96, 0);
699 udelay(67);
700 gpio_set_value(96, 1);
701 udelay(33);
702 }
703 level = level << 1;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530704 }
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530705
706 /* t-EOS */
707 gpio_set_value(96, 0);
708 ndelay(12000);
709 gpio_set_value(96, 1);
710 } else {
711 ret = pmapp_disp_backlight_set_brightness(level);
712 if (ret)
713 pr_err("%s: can't set lcd backlight!\n", __func__);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530714 }
715
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530716 return ret;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530717}
718
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530719static int mipi_NT35510_rotate_panel(void)
720{
721 int rotate = 0;
722 if (machine_is_msm8625_evt())
723 rotate = 1;
724
725 return rotate;
726}
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530727
Chintan Pandya250c2e52012-01-19 17:15:49 +0530728static struct msm_panel_common_pdata mipi_truly_pdata = {
729 .pmic_backlight = mipi_truly_set_bl,
730};
731
732static struct platform_device mipi_dsi_truly_panel_device = {
733 .name = "mipi_truly",
734 .id = 0,
735 .dev = {
736 .platform_data = &mipi_truly_pdata,
737 }
738};
739
Jeevan Shrirame941df42012-01-23 12:40:21 +0530740static struct msm_panel_common_pdata mipi_NT35510_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530741 .backlight = evb_backlight_control,
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530742 .rotate_panel = mipi_NT35510_rotate_panel,
Jeevan Shrirame941df42012-01-23 12:40:21 +0530743};
744
745static struct platform_device mipi_dsi_NT35510_panel_device = {
746 .name = "mipi_NT35510",
747 .id = 0,
748 .dev = {
749 .platform_data = &mipi_NT35510_pdata,
750 }
751};
752
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530753static struct msm_panel_common_pdata mipi_NT35516_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530754 .backlight = evb_backlight_control,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530755};
756
757static struct platform_device mipi_dsi_NT35516_panel_device = {
758 .name = "mipi_truly_tft540960_1_e",
759 .id = 0,
760 .dev = {
761 .platform_data = &mipi_NT35516_pdata,
762 }
763};
764
Chintan Pandya250c2e52012-01-19 17:15:49 +0530765static struct platform_device *msm_fb_devices[] __initdata = {
766 &msm_fb_device,
767 &lcdc_toshiba_panel_device,
768#ifdef CONFIG_FB_MSM_MIPI_DSI
769 &mipi_dsi_renesas_panel_device,
770#endif
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800771#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
772 &msm_v4l2_video_overlay_device,
773#endif
Chintan Pandya250c2e52012-01-19 17:15:49 +0530774};
775
776static struct platform_device *qrd_fb_devices[] __initdata = {
777 &msm_fb_device,
778 &mipi_dsi_truly_panel_device,
779};
780
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530781static struct platform_device *qrd3_fb_devices[] __initdata = {
782 &msm_fb_device,
783 &lcdc_truly_panel_device,
784};
785
Taniya Dasc868a2e2012-01-03 10:18:47 +0530786static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530787 &msm_fb_device,
788 &mipi_dsi_NT35510_panel_device,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530789 &mipi_dsi_NT35516_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530790};
791
Chintan Pandya250c2e52012-01-19 17:15:49 +0530792void __init msm_msm7627a_allocate_memory_regions(void)
793{
794 void *addr;
795 unsigned long fb_size;
796
797 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
798 fb_size = MSM7x25A_MSM_FB_SIZE;
Aparna Mallavarapu5a326242012-05-09 19:49:02 +0530799 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
Channagoud Kadabi2bd65c82012-10-12 15:14:23 +0530800 || machine_is_msm8625_evt()
801 || machine_is_qrd_skud_prime())
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530802 fb_size = MSM8x25_MSM_FB_SIZE;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530803 else
804 fb_size = MSM_FB_SIZE;
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530805
Chintan Pandya250c2e52012-01-19 17:15:49 +0530806 addr = alloc_bootmem_align(fb_size, 0x1000);
807 msm_fb_resources[0].start = __pa(addr);
808 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
809 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
810 addr, __pa(addr));
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800811
812#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
813 fb_size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE;
814 addr = alloc_bootmem_align(fb_size, 0x1000);
815 msm_v4l2_video_overlay_resources[0].start = __pa(addr);
816 msm_v4l2_video_overlay_resources[0].end =
817 msm_v4l2_video_overlay_resources[0].start + fb_size - 1;
818 pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n",
819 fb_size, addr, __pa(addr));
820#endif
821
Chintan Pandya250c2e52012-01-19 17:15:49 +0530822}
823
824static struct msm_panel_common_pdata mdp_pdata = {
825 .gpio = 97,
826 .mdp_rev = MDP_REV_303,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +0530827 .cont_splash_enabled = 0x1,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530828};
829
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530830static char lcdc_splash_is_enabled()
831{
832 return mdp_pdata.cont_splash_enabled;
833}
834
Chintan Pandya250c2e52012-01-19 17:15:49 +0530835#define GPIO_LCDC_BRDG_PD 128
836#define GPIO_LCDC_BRDG_RESET_N 129
837#define GPIO_LCD_DSI_SEL 125
838#define LCDC_RESET_PHYS 0x90008014
839
840static void __iomem *lcdc_reset_ptr;
841
842static unsigned mipi_dsi_gpio[] = {
843 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
844 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
845 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
846 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
847};
848
849static unsigned lcd_dsi_sel_gpio[] = {
850 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
851 GPIO_CFG_2MA),
852};
853
854enum {
855 DSI_SINGLE_LANE = 1,
856 DSI_TWO_LANES,
857};
858
859static int msm_fb_get_lane_config(void)
860{
861 /* For MSM7627A SURF/FFA and QRD */
862 int rc = DSI_TWO_LANES;
863 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
864 rc = DSI_SINGLE_LANE;
865 pr_info("DSI_SINGLE_LANES\n");
866 } else {
867 pr_info("DSI_TWO_LANES\n");
868 }
869 return rc;
870}
871
872static int msm_fb_dsi_client_msm_reset(void)
873{
874 int rc = 0;
875
876 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
877 if (rc < 0) {
878 pr_err("failed to request lcd brdg reset_n\n");
879 return rc;
880 }
881
882 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
883 if (rc < 0) {
884 pr_err("failed to request lcd brdg pd\n");
885 return rc;
886 }
887
888 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
889 if (rc) {
890 pr_err("Failed to enable LCDC Bridge reset enable\n");
891 goto gpio_error;
892 }
893
894 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
895 if (rc) {
896 pr_err("Failed to enable LCDC Bridge pd enable\n");
897 goto gpio_error2;
898 }
899
900 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
901 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
902 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
903
904 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530905 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
906 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530907 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
908 sizeof(uint32_t));
909
910 if (!lcdc_reset_ptr)
911 return 0;
912 }
913 return rc;
914 } else {
915 goto gpio_error;
916 }
917
918gpio_error2:
919 pr_err("Failed GPIO bridge pd\n");
920 gpio_free(GPIO_LCDC_BRDG_PD);
921
922gpio_error:
923 pr_err("Failed GPIO bridge reset\n");
924 gpio_free(GPIO_LCDC_BRDG_RESET_N);
925 return rc;
926}
927
928static int mipi_truly_sel_mode(int video_mode)
929{
930 int rc = 0;
931
932 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
933 if (rc < 0)
934 goto gpio_error;
935
936 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
937 if (rc)
938 goto gpio_error;
939
940 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
941 if (!rc) {
942 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
943 return rc;
944 } else {
945 goto gpio_error;
946 }
947
948gpio_error:
949 pr_err("mipi_truly_sel_mode failed\n");
950 gpio_free(GPIO_LCD_DSI_SEL);
951 return rc;
952}
953
954static int msm_fb_dsi_client_qrd1_reset(void)
955{
956 int rc = 0;
957
958 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
959 if (rc < 0) {
960 pr_err("failed to request lcd brdg reset_n\n");
961 return rc;
962 }
963
964 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
965 if (rc < 0) {
966 pr_err("Failed to enable LCDC Bridge reset enable\n");
967 return rc;
968 }
969
970 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
971 if (rc < 0) {
972 pr_err("Failed GPIO bridge pd\n");
973 gpio_free(GPIO_LCDC_BRDG_RESET_N);
974 return rc;
975 }
976
977 mipi_truly_sel_mode(1);
978
979 return rc;
980}
981
Jeevan Shrirame941df42012-01-23 12:40:21 +0530982#define GPIO_QRD3_LCD_BRDG_RESET_N 85
983#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
984#define GPIO_QRD3_LCD_EXT_2V85_EN 35
985#define GPIO_QRD3_LCD_EXT_1V8_EN 40
986
987static unsigned qrd3_mipi_dsi_gpio[] = {
988 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
989 GPIO_CFG_NO_PULL,
990 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
991 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
992 GPIO_CFG_NO_PULL,
993 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
994 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
995 GPIO_CFG_NO_PULL,
996 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
997 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
998 GPIO_CFG_NO_PULL,
999 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
1000};
1001
1002static int msm_fb_dsi_client_qrd3_reset(void)
1003{
1004 int rc = 0;
1005
1006 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
1007 if (rc < 0) {
1008 pr_err("failed to request qrd3 lcd brdg reset_n\n");
1009 return rc;
1010 }
1011
Jeevan Shrirame941df42012-01-23 12:40:21 +05301012 return rc;
1013}
1014
Chintan Pandya250c2e52012-01-19 17:15:49 +05301015static int msm_fb_dsi_client_reset(void)
1016{
1017 int rc = 0;
1018
1019 if (machine_is_msm7627a_qrd1())
1020 rc = msm_fb_dsi_client_qrd1_reset();
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301021 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
Channagoud Kadabi2bd65c82012-10-12 15:14:23 +05301022 || machine_is_msm8625_evt()
1023 || machine_is_qrd_skud_prime())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301024 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +05301025 else
1026 rc = msm_fb_dsi_client_msm_reset();
1027
1028 return rc;
1029
1030}
1031
1032static struct regulator_bulk_data regs_dsi[] = {
1033 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
1034 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
1035};
1036
1037static int dsi_gpio_initialized;
1038
1039static int mipi_dsi_panel_msm_power(int on)
1040{
1041 int rc = 0;
1042 uint32_t lcdc_reset_cfg;
1043
1044 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
1045 if (unlikely(!dsi_gpio_initialized)) {
1046 pmapp_disp_backlight_init();
1047
1048 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
1049 if (rc < 0) {
1050 pr_err("failed to request gpio_disp_pwr\n");
1051 return rc;
1052 }
1053
Taniya Dase3027e22012-02-27 16:32:27 +05301054 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
1055 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301056 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
1057 if (rc < 0) {
1058 pr_err("failed to enable display pwr\n");
1059 goto fail_gpio1;
1060 }
1061
1062 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1063 if (rc < 0) {
1064 pr_err("failed to request gpio_bkl_en\n");
1065 goto fail_gpio1;
1066 }
1067
1068 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
1069 if (rc < 0) {
1070 pr_err("failed to enable backlight\n");
1071 goto fail_gpio2;
1072 }
1073 }
1074
1075 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
1076 if (rc) {
1077 pr_err("%s: could not get regulators: %d\n",
1078 __func__, rc);
1079 goto fail_gpio2;
1080 }
1081
1082 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
1083 regs_dsi);
1084 if (rc) {
1085 pr_err("%s: could not set voltages: %d\n",
1086 __func__, rc);
1087 goto fail_vreg;
1088 }
1089 if (pmapp_disp_backlight_set_brightness(100))
1090 pr_err("backlight set brightness failed\n");
1091
1092 dsi_gpio_initialized = 1;
1093 }
Taniya Dase3027e22012-02-27 16:32:27 +05301094 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
1095 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301096 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1097 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +05301098 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
1099 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301100 if (on) {
1101 /* This line drives an active low pin on FFA */
1102 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
1103 if (rc < 0)
1104 pr_err("failed to set direction for "
1105 "display pwr\n");
1106 } else {
1107 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
1108 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
1109 if (rc < 0)
1110 pr_err("failed to set direction for "
1111 "display pwr\n");
1112 }
1113 }
1114
1115 if (on) {
1116 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
1117
1118 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +05301119 machine_is_msm7625a_surf() ||
1120 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301121 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
1122 rmb();
1123 lcdc_reset_cfg &= ~1;
1124
1125 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1126 msleep(20);
1127 wmb();
1128 lcdc_reset_cfg |= 1;
1129 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
Padmanabhan Komanduru0fab90e2012-09-28 14:15:17 +05301130 msleep(20);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301131 } else {
1132 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1133 msleep(20);
1134 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
Padmanabhan Komanduru0fab90e2012-09-28 14:15:17 +05301135 msleep(20);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301136 }
1137 } else {
1138 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301139 }
1140
1141 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
1142 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
1143
1144 if (rc)
1145 pr_err("%s: could not %sable regulators: %d\n",
1146 __func__, on ? "en" : "dis", rc);
1147
1148 return rc;
1149fail_vreg:
1150 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
1151fail_gpio2:
1152 gpio_free(GPIO_BACKLIGHT_EN);
1153fail_gpio1:
1154 gpio_free(GPIO_DISPLAY_PWR_EN);
1155 dsi_gpio_initialized = 0;
1156 return rc;
1157}
1158
1159static int mipi_dsi_panel_qrd1_power(int on)
1160{
1161 int rc = 0;
1162
1163 if (!dsi_gpio_initialized) {
1164 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1165 if (rc < 0)
1166 return rc;
1167
1168 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
1169 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1170 GPIO_CFG_ENABLE);
1171 if (rc < 0) {
1172 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
1173 return rc;
1174 }
1175
1176 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
1177 if (rc < 0) {
1178 pr_err("failed to enable backlight\n");
1179 gpio_free(QRD_GPIO_BACKLIGHT_EN);
1180 return rc;
1181 }
1182 dsi_gpio_initialized = 1;
1183 }
1184
1185 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
1186
Jeevan Shrirame941df42012-01-23 12:40:21 +05301187 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301188 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1189 msleep(20);
1190 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1191 msleep(20);
1192 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1193
1194 }
1195
1196 return rc;
1197}
1198
Jeevan Shrirame941df42012-01-23 12:40:21 +05301199static int qrd3_dsi_gpio_initialized;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301200static struct regulator *gpio_reg_2p85v, *gpio_reg_1p8v;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301201
1202static int mipi_dsi_panel_qrd3_power(int on)
1203{
1204 int rc = 0;
1205
1206 if (!qrd3_dsi_gpio_initialized) {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +05301207 pmapp_disp_backlight_init();
Jeevan Shrirame941df42012-01-23 12:40:21 +05301208 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
1209 "qrd3_gpio_bkl_en");
1210 if (rc < 0)
1211 return rc;
1212
Jeevan Shriram4461a112012-06-01 22:08:47 +05301213 qrd3_dsi_gpio_initialized = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301214
1215 if (mdp_pdata.cont_splash_enabled) {
1216 rc = gpio_tlmm_config(GPIO_CFG(
1217 GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
1218 GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
1219 if (rc < 0) {
1220 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1221 return rc;
1222 }
1223 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN,
1224 1);
1225 if (rc < 0) {
1226 pr_err("failed to enable backlight\n");
1227 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1228 return rc;
1229 }
1230
1231 /*Configure LCD Bridge reset*/
1232 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0],
1233 GPIO_CFG_ENABLE);
1234 if (rc < 0) {
1235 pr_err("Failed to enable LCD Bridge reset enable\n");
1236 return rc;
1237 }
1238
1239 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N,
1240 1);
1241
1242 if (rc < 0) {
1243 pr_err("Failed GPIO bridge Reset\n");
1244 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1245 return rc;
1246 }
1247 return 0;
1248 }
Jeevan Shrirame941df42012-01-23 12:40:21 +05301249 }
1250
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301251 if (on) {
Padmanabhan Komanduru6dadd872012-04-12 12:20:12 +05301252 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1253 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
1254 GPIO_CFG_ENABLE);
1255 if (rc < 0) {
1256 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1257 return rc;
1258 }
1259 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1260 if (rc < 0) {
1261 pr_err("failed to enable backlight\n");
1262 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1263 return rc;
1264 }
Jeevan Shriram4461a112012-06-01 22:08:47 +05301265 /*Toggle Backlight GPIO*/
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301266 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301267 udelay(100);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301268 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301269 udelay(430);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301270 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1271 /* 1 wire mode starts from this low to high transition */
1272 udelay(50);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301273
Jeevan Shriram4461a112012-06-01 22:08:47 +05301274 /*Enable EXT_2.85 and 1.8 regulators*/
1275 rc = regulator_enable(gpio_reg_2p85v);
1276 if (rc < 0)
1277 pr_err("%s: reg enable failed\n", __func__);
1278 rc = regulator_enable(gpio_reg_1p8v);
1279 if (rc < 0)
1280 pr_err("%s: reg enable failed\n", __func__);
Jeevan Shrirame941df42012-01-23 12:40:21 +05301281
Jeevan Shriram4461a112012-06-01 22:08:47 +05301282 /*Configure LCD Bridge reset*/
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301283 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301284 if (rc < 0) {
1285 pr_err("Failed to enable LCD Bridge reset enable\n");
1286 return rc;
1287 }
1288
1289 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1290
1291 if (rc < 0) {
1292 pr_err("Failed GPIO bridge Reset\n");
1293 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1294 return rc;
1295 }
1296
Jeevan Shriram4461a112012-06-01 22:08:47 +05301297 /*Toggle Bridge Reset GPIO*/
Jeevan Shrirame941df42012-01-23 12:40:21 +05301298 msleep(20);
1299 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
1300 msleep(20);
1301 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1302 msleep(20);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301303
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301304 } else {
Jeevan Shriram4461a112012-06-01 22:08:47 +05301305 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1306 GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
1307 GPIO_CFG_DISABLE);
1308
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301309 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
1310 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1311 GPIO_CFG_DISABLE);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301312
1313 rc = regulator_disable(gpio_reg_2p85v);
1314 if (rc < 0)
1315 pr_err("%s: reg disable failed\n", __func__);
1316 rc = regulator_disable(gpio_reg_1p8v);
1317 if (rc < 0)
1318 pr_err("%s: reg disable failed\n", __func__);
1319
Jeevan Shrirame941df42012-01-23 12:40:21 +05301320 }
1321
Jeevan Shriram4461a112012-06-01 22:08:47 +05301322 return rc;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301323}
1324
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301325static char mipi_dsi_splash_is_enabled(void);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301326static int mipi_dsi_panel_power(int on)
1327{
1328 int rc = 0;
1329
1330 if (machine_is_msm7627a_qrd1())
1331 rc = mipi_dsi_panel_qrd1_power(on);
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301332 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
Channagoud Kadabi2bd65c82012-10-12 15:14:23 +05301333 || machine_is_msm8625_evt()
1334 || machine_is_qrd_skud_prime())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301335 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301336 else
1337 rc = mipi_dsi_panel_msm_power(on);
1338 return rc;
1339}
1340
1341#define MDP_303_VSYNC_GPIO 97
1342
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301343#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301344static struct mipi_dsi_platform_data mipi_dsi_pdata = {
1345 .vsync_gpio = MDP_303_VSYNC_GPIO,
1346 .dsi_power_save = mipi_dsi_panel_power,
1347 .dsi_client_reset = msm_fb_dsi_client_reset,
1348 .get_lane_config = msm_fb_get_lane_config,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301349 .splash_is_enabled = mipi_dsi_splash_is_enabled,
Chintan Pandya250c2e52012-01-19 17:15:49 +05301350};
1351#endif
1352
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301353static char mipi_dsi_splash_is_enabled(void)
1354{
1355 return mdp_pdata.cont_splash_enabled;
1356}
1357
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301358static char prim_panel_name[PANEL_NAME_MAX_LEN];
1359static int __init prim_display_setup(char *param)
1360{
1361 if (strnlen(param, PANEL_NAME_MAX_LEN))
1362 strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
1363 return 0;
1364}
1365early_param("prim_display", prim_display_setup);
1366
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301367static int disable_splash;
1368
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301369void msm7x27a_set_display_params(char *prim_panel)
1370{
1371 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1372 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1373 PANEL_NAME_MAX_LEN);
1374 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1375 msm_fb_pdata.prim_panel_name);
1376 }
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301377 if (strnlen(msm_fb_pdata.prim_panel_name, PANEL_NAME_MAX_LEN)) {
1378 if (strncmp((char *)msm_fb_pdata.prim_panel_name,
1379 "mipi_cmd_nt35510_wvga",
1380 strnlen("mipi_cmd_nt35510_wvga",
1381 PANEL_NAME_MAX_LEN)) &&
1382 strncmp((char *)msm_fb_pdata.prim_panel_name,
1383 "mipi_video_nt35510_wvga",
1384 strnlen("mipi_video_nt35510_wvga",
1385 PANEL_NAME_MAX_LEN)))
1386 disable_splash = 1;
1387 }
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301388}
1389
Chintan Pandya250c2e52012-01-19 17:15:49 +05301390void __init msm_fb_add_devices(void)
1391{
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301392 int rc = 0;
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301393 msm7x27a_set_display_params(prim_panel_name);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +05301394 if (machine_is_msm7627a_qrd1()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301395 platform_add_devices(qrd_fb_devices,
1396 ARRAY_SIZE(qrd_fb_devices));
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +05301397 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
Channagoud Kadabi2bd65c82012-10-12 15:14:23 +05301398 || machine_is_msm8625_evt()
1399 || machine_is_qrd_skud_prime()) {
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301400 mipi_NT35510_pdata.bl_lock = 1;
Padmanabhan Komanduru0f0000a2012-04-12 10:23:02 +05301401 mipi_NT35516_pdata.bl_lock = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301402 if (disable_splash)
1403 mdp_pdata.cont_splash_enabled = 0x0;
1404
Taniya Dasc868a2e2012-01-03 10:18:47 +05301405 platform_add_devices(evb_fb_devices,
1406 ARRAY_SIZE(evb_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301407 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Padmanabhan Komandurue2d78c52012-09-20 18:28:55 +05301408 if (machine_is_msm7627a_qrd3())
1409 mdp_pdata.cont_splash_enabled = 0x0;
1410 else
1411 mdp_pdata.cont_splash_enabled = 0x1;
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301412 platform_add_devices(qrd3_fb_devices,
1413 ARRAY_SIZE(qrd3_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301414 } else {
1415 mdp_pdata.cont_splash_enabled = 0x0;
Chintan Pandya250c2e52012-01-19 17:15:49 +05301416 platform_add_devices(msm_fb_devices,
1417 ARRAY_SIZE(msm_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301418 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301419
1420 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +05301421 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
Jeevan Shriram045cdc72012-03-27 07:04:15 +05301422 machine_is_msm8625_surf() || machine_is_msm7627a_qrd3()
1423 || machine_is_msm8625_qrd7())
Chintan Pandya250c2e52012-01-19 17:15:49 +05301424 msm_fb_register_device("lcdc", &lcdc_pdata);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +05301425 if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
1426 sku3_lcdc_power_init();
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301427#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301428 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1429#endif
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301430 if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
Channagoud Kadabi2bd65c82012-10-12 15:14:23 +05301431 || machine_is_msm8625_evt()
1432 || machine_is_qrd_skud_prime()) {
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301433 gpio_reg_2p85v = regulator_get(&mipi_dsi_device.dev,
1434 "lcd_vdd");
1435 if (IS_ERR(gpio_reg_2p85v))
1436 pr_err("%s:ext_2p85v regulator get failed", __func__);
1437
1438 gpio_reg_1p8v = regulator_get(&mipi_dsi_device.dev,
1439 "lcd_vddi");
1440 if (IS_ERR(gpio_reg_1p8v))
1441 pr_err("%s:ext_1p8v regulator get failed", __func__);
1442
1443 if (mdp_pdata.cont_splash_enabled) {
1444 /*Enable EXT_2.85 and 1.8 regulators*/
1445 rc = regulator_enable(gpio_reg_2p85v);
1446 if (rc < 0)
1447 pr_err("%s: reg enable failed\n", __func__);
1448 rc = regulator_enable(gpio_reg_1p8v);
1449 if (rc < 0)
1450 pr_err("%s: reg enable failed\n", __func__);
1451 }
1452 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301453}