blob: 2db074d1e90d0cd5849cb9ffb8d81750c89c16e2 [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>
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() ||
545 machine_is_msm8625_evt()) {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530546 if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
547 ret = 0;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530548 }
549
550#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
551 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
552 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
553 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530554 machine_is_msm7625a_surf() ||
555 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530556 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
557 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
558 PANEL_NAME_MAX_LEN)))
559 return 0;
560 }
561#endif
562
563 return ret;
564}
565
566static int mipi_truly_set_bl(int on)
567{
568 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
569
570 return 1;
571}
572
573static struct msm_fb_platform_data msm_fb_pdata = {
574 .detect_client = msm_fb_detect_panel,
575};
576
577static struct platform_device msm_fb_device = {
578 .name = "msm_fb",
579 .id = 0,
580 .num_resources = ARRAY_SIZE(msm_fb_resources),
581 .resource = msm_fb_resources,
582 .dev = {
583 .platform_data = &msm_fb_pdata,
584 }
585};
586
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800587#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
588static struct platform_device msm_v4l2_video_overlay_device = {
589 .name = "msm_v4l2_overlay_pd",
590 .id = 0,
591 .num_resources = ARRAY_SIZE(msm_v4l2_video_overlay_resources),
592 .resource = msm_v4l2_video_overlay_resources,
593 };
594#endif
595
596
Chintan Pandya250c2e52012-01-19 17:15:49 +0530597#ifdef CONFIG_FB_MSM_MIPI_DSI
598static int mipi_renesas_set_bl(int level)
599{
600 int ret;
601
602 ret = pmapp_disp_backlight_set_brightness(level);
603
604 if (ret)
605 pr_err("%s: can't set lcd backlight!\n", __func__);
606
607 return ret;
608}
609
610static struct msm_panel_common_pdata mipi_renesas_pdata = {
611 .pmic_backlight = mipi_renesas_set_bl,
612};
613
614
615static struct platform_device mipi_dsi_renesas_panel_device = {
616 .name = "mipi_renesas",
617 .id = 0,
618 .dev = {
619 .platform_data = &mipi_renesas_pdata,
620 }
621};
622#endif
623
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530624static int evb_backlight_control(int level, int mode)
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530625{
626
627 int i = 0;
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530628 int remainder, ret = 0;
629
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530630 /* device address byte = 0x72 */
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530631 if (!mode) {
632 gpio_set_value(96, 0);
633 udelay(67);
634 gpio_set_value(96, 1);
635 udelay(33);
636 gpio_set_value(96, 0);
637 udelay(33);
638 gpio_set_value(96, 1);
639 udelay(67);
640 gpio_set_value(96, 0);
641 udelay(33);
642 gpio_set_value(96, 1);
643 udelay(67);
644 gpio_set_value(96, 0);
645 udelay(33);
646 gpio_set_value(96, 1);
647 udelay(67);
648 gpio_set_value(96, 0);
649 udelay(67);
650 gpio_set_value(96, 1);
651 udelay(33);
652 gpio_set_value(96, 0);
653 udelay(67);
654 gpio_set_value(96, 1);
655 udelay(33);
656 gpio_set_value(96, 0);
657 udelay(33);
658 gpio_set_value(96, 1);
659 udelay(67);
660 gpio_set_value(96, 0);
661 udelay(67);
662 gpio_set_value(96, 1);
663 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530664
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530665 /* t-EOS and t-start */
666 gpio_set_value(96, 0);
667 ndelay(4200);
668 gpio_set_value(96, 1);
669 ndelay(9000);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530670
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530671 /* data byte */
672 /* RFA = 0 */
673 gpio_set_value(96, 0);
674 udelay(67);
675 gpio_set_value(96, 1);
676 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530677
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530678 /* Address bits */
679 gpio_set_value(96, 0);
680 udelay(67);
681 gpio_set_value(96, 1);
682 udelay(33);
683 gpio_set_value(96, 0);
684 udelay(67);
685 gpio_set_value(96, 1);
686 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530687
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530688 /* Data bits */
689 for (i = 0; i < 5; i++) {
690 remainder = (level) & (16);
691 if (remainder) {
692 gpio_set_value(96, 0);
693 udelay(33);
694 gpio_set_value(96, 1);
695 udelay(67);
696 } else {
697 gpio_set_value(96, 0);
698 udelay(67);
699 gpio_set_value(96, 1);
700 udelay(33);
701 }
702 level = level << 1;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530703 }
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530704
705 /* t-EOS */
706 gpio_set_value(96, 0);
707 ndelay(12000);
708 gpio_set_value(96, 1);
709 } else {
710 ret = pmapp_disp_backlight_set_brightness(level);
711 if (ret)
712 pr_err("%s: can't set lcd backlight!\n", __func__);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530713 }
714
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530715 return ret;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530716}
717
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530718static int mipi_NT35510_rotate_panel(void)
719{
720 int rotate = 0;
721 if (machine_is_msm8625_evt())
722 rotate = 1;
723
724 return rotate;
725}
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530726
Chintan Pandya250c2e52012-01-19 17:15:49 +0530727static struct msm_panel_common_pdata mipi_truly_pdata = {
728 .pmic_backlight = mipi_truly_set_bl,
729};
730
731static struct platform_device mipi_dsi_truly_panel_device = {
732 .name = "mipi_truly",
733 .id = 0,
734 .dev = {
735 .platform_data = &mipi_truly_pdata,
736 }
737};
738
Jeevan Shrirame941df42012-01-23 12:40:21 +0530739static struct msm_panel_common_pdata mipi_NT35510_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530740 .backlight = evb_backlight_control,
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530741 .rotate_panel = mipi_NT35510_rotate_panel,
Jeevan Shrirame941df42012-01-23 12:40:21 +0530742};
743
744static struct platform_device mipi_dsi_NT35510_panel_device = {
745 .name = "mipi_NT35510",
746 .id = 0,
747 .dev = {
748 .platform_data = &mipi_NT35510_pdata,
749 }
750};
751
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530752static struct msm_panel_common_pdata mipi_NT35516_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530753 .backlight = evb_backlight_control,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530754};
755
756static struct platform_device mipi_dsi_NT35516_panel_device = {
757 .name = "mipi_truly_tft540960_1_e",
758 .id = 0,
759 .dev = {
760 .platform_data = &mipi_NT35516_pdata,
761 }
762};
763
Chintan Pandya250c2e52012-01-19 17:15:49 +0530764static struct platform_device *msm_fb_devices[] __initdata = {
765 &msm_fb_device,
766 &lcdc_toshiba_panel_device,
767#ifdef CONFIG_FB_MSM_MIPI_DSI
768 &mipi_dsi_renesas_panel_device,
769#endif
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800770#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
771 &msm_v4l2_video_overlay_device,
772#endif
Chintan Pandya250c2e52012-01-19 17:15:49 +0530773};
774
775static struct platform_device *qrd_fb_devices[] __initdata = {
776 &msm_fb_device,
777 &mipi_dsi_truly_panel_device,
778};
779
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530780static struct platform_device *qrd3_fb_devices[] __initdata = {
781 &msm_fb_device,
782 &lcdc_truly_panel_device,
783};
784
Taniya Dasc868a2e2012-01-03 10:18:47 +0530785static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530786 &msm_fb_device,
787 &mipi_dsi_NT35510_panel_device,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530788 &mipi_dsi_NT35516_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530789};
790
Chintan Pandya250c2e52012-01-19 17:15:49 +0530791void __init msm_msm7627a_allocate_memory_regions(void)
792{
793 void *addr;
794 unsigned long fb_size;
795
796 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
797 fb_size = MSM7x25A_MSM_FB_SIZE;
Aparna Mallavarapu5a326242012-05-09 19:49:02 +0530798 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
799 || machine_is_msm8625_evt())
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530800 fb_size = MSM8x25_MSM_FB_SIZE;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530801 else
802 fb_size = MSM_FB_SIZE;
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530803
Chintan Pandya250c2e52012-01-19 17:15:49 +0530804 addr = alloc_bootmem_align(fb_size, 0x1000);
805 msm_fb_resources[0].start = __pa(addr);
806 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
807 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
808 addr, __pa(addr));
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800809
810#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
811 fb_size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE;
812 addr = alloc_bootmem_align(fb_size, 0x1000);
813 msm_v4l2_video_overlay_resources[0].start = __pa(addr);
814 msm_v4l2_video_overlay_resources[0].end =
815 msm_v4l2_video_overlay_resources[0].start + fb_size - 1;
816 pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n",
817 fb_size, addr, __pa(addr));
818#endif
819
Chintan Pandya250c2e52012-01-19 17:15:49 +0530820}
821
822static struct msm_panel_common_pdata mdp_pdata = {
823 .gpio = 97,
824 .mdp_rev = MDP_REV_303,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +0530825 .cont_splash_enabled = 0x1,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530826};
827
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530828static char lcdc_splash_is_enabled()
829{
830 return mdp_pdata.cont_splash_enabled;
831}
832
Chintan Pandya250c2e52012-01-19 17:15:49 +0530833#define GPIO_LCDC_BRDG_PD 128
834#define GPIO_LCDC_BRDG_RESET_N 129
835#define GPIO_LCD_DSI_SEL 125
836#define LCDC_RESET_PHYS 0x90008014
837
838static void __iomem *lcdc_reset_ptr;
839
840static unsigned mipi_dsi_gpio[] = {
841 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
842 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
843 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
844 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
845};
846
847static unsigned lcd_dsi_sel_gpio[] = {
848 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
849 GPIO_CFG_2MA),
850};
851
852enum {
853 DSI_SINGLE_LANE = 1,
854 DSI_TWO_LANES,
855};
856
857static int msm_fb_get_lane_config(void)
858{
859 /* For MSM7627A SURF/FFA and QRD */
860 int rc = DSI_TWO_LANES;
861 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
862 rc = DSI_SINGLE_LANE;
863 pr_info("DSI_SINGLE_LANES\n");
864 } else {
865 pr_info("DSI_TWO_LANES\n");
866 }
867 return rc;
868}
869
870static int msm_fb_dsi_client_msm_reset(void)
871{
872 int rc = 0;
873
874 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
875 if (rc < 0) {
876 pr_err("failed to request lcd brdg reset_n\n");
877 return rc;
878 }
879
880 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
881 if (rc < 0) {
882 pr_err("failed to request lcd brdg pd\n");
883 return rc;
884 }
885
886 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
887 if (rc) {
888 pr_err("Failed to enable LCDC Bridge reset enable\n");
889 goto gpio_error;
890 }
891
892 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
893 if (rc) {
894 pr_err("Failed to enable LCDC Bridge pd enable\n");
895 goto gpio_error2;
896 }
897
898 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
899 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
900 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
901
902 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530903 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
904 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530905 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
906 sizeof(uint32_t));
907
908 if (!lcdc_reset_ptr)
909 return 0;
910 }
911 return rc;
912 } else {
913 goto gpio_error;
914 }
915
916gpio_error2:
917 pr_err("Failed GPIO bridge pd\n");
918 gpio_free(GPIO_LCDC_BRDG_PD);
919
920gpio_error:
921 pr_err("Failed GPIO bridge reset\n");
922 gpio_free(GPIO_LCDC_BRDG_RESET_N);
923 return rc;
924}
925
926static int mipi_truly_sel_mode(int video_mode)
927{
928 int rc = 0;
929
930 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
931 if (rc < 0)
932 goto gpio_error;
933
934 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
935 if (rc)
936 goto gpio_error;
937
938 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
939 if (!rc) {
940 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
941 return rc;
942 } else {
943 goto gpio_error;
944 }
945
946gpio_error:
947 pr_err("mipi_truly_sel_mode failed\n");
948 gpio_free(GPIO_LCD_DSI_SEL);
949 return rc;
950}
951
952static int msm_fb_dsi_client_qrd1_reset(void)
953{
954 int rc = 0;
955
956 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
957 if (rc < 0) {
958 pr_err("failed to request lcd brdg reset_n\n");
959 return rc;
960 }
961
962 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
963 if (rc < 0) {
964 pr_err("Failed to enable LCDC Bridge reset enable\n");
965 return rc;
966 }
967
968 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
969 if (rc < 0) {
970 pr_err("Failed GPIO bridge pd\n");
971 gpio_free(GPIO_LCDC_BRDG_RESET_N);
972 return rc;
973 }
974
975 mipi_truly_sel_mode(1);
976
977 return rc;
978}
979
Jeevan Shrirame941df42012-01-23 12:40:21 +0530980#define GPIO_QRD3_LCD_BRDG_RESET_N 85
981#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
982#define GPIO_QRD3_LCD_EXT_2V85_EN 35
983#define GPIO_QRD3_LCD_EXT_1V8_EN 40
984
985static unsigned qrd3_mipi_dsi_gpio[] = {
986 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
987 GPIO_CFG_NO_PULL,
988 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
989 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
990 GPIO_CFG_NO_PULL,
991 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
992 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
993 GPIO_CFG_NO_PULL,
994 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
995 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
996 GPIO_CFG_NO_PULL,
997 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
998};
999
1000static int msm_fb_dsi_client_qrd3_reset(void)
1001{
1002 int rc = 0;
1003
1004 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
1005 if (rc < 0) {
1006 pr_err("failed to request qrd3 lcd brdg reset_n\n");
1007 return rc;
1008 }
1009
Jeevan Shrirame941df42012-01-23 12:40:21 +05301010 return rc;
1011}
1012
Chintan Pandya250c2e52012-01-19 17:15:49 +05301013static int msm_fb_dsi_client_reset(void)
1014{
1015 int rc = 0;
1016
1017 if (machine_is_msm7627a_qrd1())
1018 rc = msm_fb_dsi_client_qrd1_reset();
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301019 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1020 || machine_is_msm8625_evt())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301021 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +05301022 else
1023 rc = msm_fb_dsi_client_msm_reset();
1024
1025 return rc;
1026
1027}
1028
1029static struct regulator_bulk_data regs_dsi[] = {
1030 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
1031 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
1032};
1033
1034static int dsi_gpio_initialized;
1035
1036static int mipi_dsi_panel_msm_power(int on)
1037{
1038 int rc = 0;
1039 uint32_t lcdc_reset_cfg;
1040
1041 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
1042 if (unlikely(!dsi_gpio_initialized)) {
1043 pmapp_disp_backlight_init();
1044
1045 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
1046 if (rc < 0) {
1047 pr_err("failed to request gpio_disp_pwr\n");
1048 return rc;
1049 }
1050
Taniya Dase3027e22012-02-27 16:32:27 +05301051 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
1052 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301053 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
1054 if (rc < 0) {
1055 pr_err("failed to enable display pwr\n");
1056 goto fail_gpio1;
1057 }
1058
1059 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1060 if (rc < 0) {
1061 pr_err("failed to request gpio_bkl_en\n");
1062 goto fail_gpio1;
1063 }
1064
1065 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
1066 if (rc < 0) {
1067 pr_err("failed to enable backlight\n");
1068 goto fail_gpio2;
1069 }
1070 }
1071
1072 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
1073 if (rc) {
1074 pr_err("%s: could not get regulators: %d\n",
1075 __func__, rc);
1076 goto fail_gpio2;
1077 }
1078
1079 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
1080 regs_dsi);
1081 if (rc) {
1082 pr_err("%s: could not set voltages: %d\n",
1083 __func__, rc);
1084 goto fail_vreg;
1085 }
1086 if (pmapp_disp_backlight_set_brightness(100))
1087 pr_err("backlight set brightness failed\n");
1088
1089 dsi_gpio_initialized = 1;
1090 }
Taniya Dase3027e22012-02-27 16:32:27 +05301091 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
1092 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301093 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1094 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +05301095 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
1096 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301097 if (on) {
1098 /* This line drives an active low pin on FFA */
1099 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
1100 if (rc < 0)
1101 pr_err("failed to set direction for "
1102 "display pwr\n");
1103 } else {
1104 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
1105 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
1106 if (rc < 0)
1107 pr_err("failed to set direction for "
1108 "display pwr\n");
1109 }
1110 }
1111
1112 if (on) {
1113 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
1114
1115 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +05301116 machine_is_msm7625a_surf() ||
1117 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301118 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
1119 rmb();
1120 lcdc_reset_cfg &= ~1;
1121
1122 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1123 msleep(20);
1124 wmb();
1125 lcdc_reset_cfg |= 1;
1126 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
Padmanabhan Komanduru0fab90e2012-09-28 14:15:17 +05301127 msleep(20);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301128 } else {
1129 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1130 msleep(20);
1131 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
Padmanabhan Komanduru0fab90e2012-09-28 14:15:17 +05301132 msleep(20);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301133 }
1134 } else {
1135 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301136 }
1137
1138 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
1139 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
1140
1141 if (rc)
1142 pr_err("%s: could not %sable regulators: %d\n",
1143 __func__, on ? "en" : "dis", rc);
1144
1145 return rc;
1146fail_vreg:
1147 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
1148fail_gpio2:
1149 gpio_free(GPIO_BACKLIGHT_EN);
1150fail_gpio1:
1151 gpio_free(GPIO_DISPLAY_PWR_EN);
1152 dsi_gpio_initialized = 0;
1153 return rc;
1154}
1155
1156static int mipi_dsi_panel_qrd1_power(int on)
1157{
1158 int rc = 0;
1159
1160 if (!dsi_gpio_initialized) {
1161 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1162 if (rc < 0)
1163 return rc;
1164
1165 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
1166 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1167 GPIO_CFG_ENABLE);
1168 if (rc < 0) {
1169 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
1170 return rc;
1171 }
1172
1173 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
1174 if (rc < 0) {
1175 pr_err("failed to enable backlight\n");
1176 gpio_free(QRD_GPIO_BACKLIGHT_EN);
1177 return rc;
1178 }
1179 dsi_gpio_initialized = 1;
1180 }
1181
1182 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
1183
Jeevan Shrirame941df42012-01-23 12:40:21 +05301184 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301185 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1186 msleep(20);
1187 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1188 msleep(20);
1189 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1190
1191 }
1192
1193 return rc;
1194}
1195
Jeevan Shrirame941df42012-01-23 12:40:21 +05301196static int qrd3_dsi_gpio_initialized;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301197static struct regulator *gpio_reg_2p85v, *gpio_reg_1p8v;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301198
1199static int mipi_dsi_panel_qrd3_power(int on)
1200{
1201 int rc = 0;
1202
1203 if (!qrd3_dsi_gpio_initialized) {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +05301204 pmapp_disp_backlight_init();
Jeevan Shrirame941df42012-01-23 12:40:21 +05301205 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
1206 "qrd3_gpio_bkl_en");
1207 if (rc < 0)
1208 return rc;
1209
Jeevan Shriram4461a112012-06-01 22:08:47 +05301210 qrd3_dsi_gpio_initialized = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301211
1212 if (mdp_pdata.cont_splash_enabled) {
1213 rc = gpio_tlmm_config(GPIO_CFG(
1214 GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
1215 GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
1216 if (rc < 0) {
1217 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1218 return rc;
1219 }
1220 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN,
1221 1);
1222 if (rc < 0) {
1223 pr_err("failed to enable backlight\n");
1224 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1225 return rc;
1226 }
1227
1228 /*Configure LCD Bridge reset*/
1229 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0],
1230 GPIO_CFG_ENABLE);
1231 if (rc < 0) {
1232 pr_err("Failed to enable LCD Bridge reset enable\n");
1233 return rc;
1234 }
1235
1236 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N,
1237 1);
1238
1239 if (rc < 0) {
1240 pr_err("Failed GPIO bridge Reset\n");
1241 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1242 return rc;
1243 }
1244 return 0;
1245 }
Jeevan Shrirame941df42012-01-23 12:40:21 +05301246 }
1247
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301248 if (on) {
Padmanabhan Komanduru6dadd872012-04-12 12:20:12 +05301249 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1250 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
1251 GPIO_CFG_ENABLE);
1252 if (rc < 0) {
1253 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1254 return rc;
1255 }
1256 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1257 if (rc < 0) {
1258 pr_err("failed to enable backlight\n");
1259 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1260 return rc;
1261 }
Jeevan Shriram4461a112012-06-01 22:08:47 +05301262 /*Toggle Backlight GPIO*/
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301263 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301264 udelay(100);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301265 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301266 udelay(430);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301267 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1268 /* 1 wire mode starts from this low to high transition */
1269 udelay(50);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301270
Jeevan Shriram4461a112012-06-01 22:08:47 +05301271 /*Enable EXT_2.85 and 1.8 regulators*/
1272 rc = regulator_enable(gpio_reg_2p85v);
1273 if (rc < 0)
1274 pr_err("%s: reg enable failed\n", __func__);
1275 rc = regulator_enable(gpio_reg_1p8v);
1276 if (rc < 0)
1277 pr_err("%s: reg enable failed\n", __func__);
Jeevan Shrirame941df42012-01-23 12:40:21 +05301278
Jeevan Shriram4461a112012-06-01 22:08:47 +05301279 /*Configure LCD Bridge reset*/
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301280 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301281 if (rc < 0) {
1282 pr_err("Failed to enable LCD Bridge reset enable\n");
1283 return rc;
1284 }
1285
1286 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1287
1288 if (rc < 0) {
1289 pr_err("Failed GPIO bridge Reset\n");
1290 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1291 return rc;
1292 }
1293
Jeevan Shriram4461a112012-06-01 22:08:47 +05301294 /*Toggle Bridge Reset GPIO*/
Jeevan Shrirame941df42012-01-23 12:40:21 +05301295 msleep(20);
1296 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
1297 msleep(20);
1298 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1299 msleep(20);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301300
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301301 } else {
Jeevan Shriram4461a112012-06-01 22:08:47 +05301302 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1303 GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
1304 GPIO_CFG_DISABLE);
1305
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301306 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
1307 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1308 GPIO_CFG_DISABLE);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301309
1310 rc = regulator_disable(gpio_reg_2p85v);
1311 if (rc < 0)
1312 pr_err("%s: reg disable failed\n", __func__);
1313 rc = regulator_disable(gpio_reg_1p8v);
1314 if (rc < 0)
1315 pr_err("%s: reg disable failed\n", __func__);
1316
Jeevan Shrirame941df42012-01-23 12:40:21 +05301317 }
1318
Jeevan Shriram4461a112012-06-01 22:08:47 +05301319 return rc;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301320}
1321
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301322static char mipi_dsi_splash_is_enabled(void);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301323static int mipi_dsi_panel_power(int on)
1324{
1325 int rc = 0;
1326
1327 if (machine_is_msm7627a_qrd1())
1328 rc = mipi_dsi_panel_qrd1_power(on);
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301329 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1330 || machine_is_msm8625_evt())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301331 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301332 else
1333 rc = mipi_dsi_panel_msm_power(on);
1334 return rc;
1335}
1336
1337#define MDP_303_VSYNC_GPIO 97
1338
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301339#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301340static struct mipi_dsi_platform_data mipi_dsi_pdata = {
1341 .vsync_gpio = MDP_303_VSYNC_GPIO,
1342 .dsi_power_save = mipi_dsi_panel_power,
1343 .dsi_client_reset = msm_fb_dsi_client_reset,
1344 .get_lane_config = msm_fb_get_lane_config,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301345 .splash_is_enabled = mipi_dsi_splash_is_enabled,
Chintan Pandya250c2e52012-01-19 17:15:49 +05301346};
1347#endif
1348
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301349static char mipi_dsi_splash_is_enabled(void)
1350{
1351 return mdp_pdata.cont_splash_enabled;
1352}
1353
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301354static char prim_panel_name[PANEL_NAME_MAX_LEN];
1355static int __init prim_display_setup(char *param)
1356{
1357 if (strnlen(param, PANEL_NAME_MAX_LEN))
1358 strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
1359 return 0;
1360}
1361early_param("prim_display", prim_display_setup);
1362
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301363static int disable_splash;
1364
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301365void msm7x27a_set_display_params(char *prim_panel)
1366{
1367 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1368 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1369 PANEL_NAME_MAX_LEN);
1370 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1371 msm_fb_pdata.prim_panel_name);
1372 }
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301373 if (strnlen(msm_fb_pdata.prim_panel_name, PANEL_NAME_MAX_LEN)) {
1374 if (strncmp((char *)msm_fb_pdata.prim_panel_name,
1375 "mipi_cmd_nt35510_wvga",
1376 strnlen("mipi_cmd_nt35510_wvga",
1377 PANEL_NAME_MAX_LEN)) &&
1378 strncmp((char *)msm_fb_pdata.prim_panel_name,
1379 "mipi_video_nt35510_wvga",
1380 strnlen("mipi_video_nt35510_wvga",
1381 PANEL_NAME_MAX_LEN)))
1382 disable_splash = 1;
1383 }
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301384}
1385
Chintan Pandya250c2e52012-01-19 17:15:49 +05301386void __init msm_fb_add_devices(void)
1387{
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301388 int rc = 0;
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301389 msm7x27a_set_display_params(prim_panel_name);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +05301390 if (machine_is_msm7627a_qrd1()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301391 platform_add_devices(qrd_fb_devices,
1392 ARRAY_SIZE(qrd_fb_devices));
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +05301393 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301394 || machine_is_msm8625_evt()) {
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301395 mipi_NT35510_pdata.bl_lock = 1;
Padmanabhan Komanduru0f0000a2012-04-12 10:23:02 +05301396 mipi_NT35516_pdata.bl_lock = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301397 if (disable_splash)
1398 mdp_pdata.cont_splash_enabled = 0x0;
1399
Taniya Dasc868a2e2012-01-03 10:18:47 +05301400 platform_add_devices(evb_fb_devices,
1401 ARRAY_SIZE(evb_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301402 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Padmanabhan Komandurue2d78c52012-09-20 18:28:55 +05301403 if (machine_is_msm7627a_qrd3())
1404 mdp_pdata.cont_splash_enabled = 0x0;
1405 else
1406 mdp_pdata.cont_splash_enabled = 0x1;
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301407 platform_add_devices(qrd3_fb_devices,
1408 ARRAY_SIZE(qrd3_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301409 } else {
1410 mdp_pdata.cont_splash_enabled = 0x0;
Chintan Pandya250c2e52012-01-19 17:15:49 +05301411 platform_add_devices(msm_fb_devices,
1412 ARRAY_SIZE(msm_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301413 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301414
1415 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +05301416 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
Jeevan Shriram045cdc72012-03-27 07:04:15 +05301417 machine_is_msm8625_surf() || machine_is_msm7627a_qrd3()
1418 || machine_is_msm8625_qrd7())
Chintan Pandya250c2e52012-01-19 17:15:49 +05301419 msm_fb_register_device("lcdc", &lcdc_pdata);
Padmanabhan Komandurue77bcf52012-07-26 12:43:39 +05301420 if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
1421 sku3_lcdc_power_init();
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301422#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301423 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1424#endif
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301425 if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1426 || machine_is_msm8625_evt()) {
1427 gpio_reg_2p85v = regulator_get(&mipi_dsi_device.dev,
1428 "lcd_vdd");
1429 if (IS_ERR(gpio_reg_2p85v))
1430 pr_err("%s:ext_2p85v regulator get failed", __func__);
1431
1432 gpio_reg_1p8v = regulator_get(&mipi_dsi_device.dev,
1433 "lcd_vddi");
1434 if (IS_ERR(gpio_reg_1p8v))
1435 pr_err("%s:ext_1p8v regulator get failed", __func__);
1436
1437 if (mdp_pdata.cont_splash_enabled) {
1438 /*Enable EXT_2.85 and 1.8 regulators*/
1439 rc = regulator_enable(gpio_reg_2p85v);
1440 if (rc < 0)
1441 pr_err("%s: reg enable failed\n", __func__);
1442 rc = regulator_enable(gpio_reg_1p8v);
1443 if (rc < 0)
1444 pr_err("%s: reg enable failed\n", __func__);
1445 }
1446 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301447}