blob: 35ea4924987bbac200c021ed17f365aecdf983f3 [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
68static uint32_t lcdc_truly_gpio_table[] = {
69 19,
70 20,
71 21,
72 89,
73 90,
74};
75
76static char *lcdc_gpio_name_table[5] = {
77 "spi_mosi",
78 "spi_clk",
79 "spi_cs",
80 "gpio_bkl_en",
81 "gpio_disp_reset",
82};
83
84static int lcdc_truly_gpio_init(void)
85{
86 int i;
87 int rc = 0;
88
89 if (!lcdc_truly_gpio_initialized) {
90 for (i = 0; i < ARRAY_SIZE(lcdc_truly_gpio_table); i++) {
91 rc = gpio_request(lcdc_truly_gpio_table[i],
92 lcdc_gpio_name_table[i]);
93 if (rc < 0) {
94 pr_err("Error request gpio %s\n",
95 lcdc_gpio_name_table[i]);
96 goto truly_gpio_fail;
97 }
98 rc = gpio_tlmm_config(GPIO_CFG(lcdc_truly_gpio_table[i],
99 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
100 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
101 if (rc < 0) {
102 pr_err("Error config lcdc gpio:%d\n",
103 lcdc_truly_gpio_table[i]);
104 goto truly_gpio_fail;
105 }
106 rc = gpio_direction_output(lcdc_truly_gpio_table[i], 0);
107 if (rc < 0) {
108 pr_err("Error direct lcdc gpio:%d\n",
109 lcdc_truly_gpio_table[i]);
110 goto truly_gpio_fail;
111 }
112 }
113
114 lcdc_truly_gpio_initialized = 1;
115 }
116
117 return rc;
118
119truly_gpio_fail:
120 for (; i >= 0; i--) {
121 pr_err("Freeing GPIO: %d", lcdc_truly_gpio_table[i]);
122 gpio_free(lcdc_truly_gpio_table[i]);
123 }
124
125 lcdc_truly_gpio_initialized = 0;
126 return rc;
127}
128
129
130void sku3_lcdc_lcd_camera_power_init(void)
131{
132 int rc = 0;
133 u32 socinfo = socinfo_get_platform_type();
134
135 /* LDO_EXT2V8 */
136 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
137 pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
138 return;
139 }
140
141 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0,
142 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
143 GPIO_CFG_ENABLE);
144
145 if (rc < 0) {
146 pr_err("%s:unable to enable lcd_camera_ldo_2v8!\n", __func__);
147 goto fail_gpio2;
148 }
149
150 /* LDO_EVT1V8 */
151 if (socinfo == 0x0B) {
152 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
153 "lcd_camera_ldo_1v8")) {
154 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
155 goto fail_gpio1;
156 }
157
158 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_1V8, 0,
159 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
160 GPIO_CFG_ENABLE);
161
162 if (rc < 0) {
163 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
164 __func__);
165 goto fail_gpio1;
166 }
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530167 } else if (socinfo == 0x0F || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530168 if (gpio_request(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
169 "lcd_camera_ldo_1v8")) {
170 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
171 goto fail_gpio1;
172 }
173
174 rc = gpio_tlmm_config(GPIO_CFG(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
175 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
176 GPIO_CFG_ENABLE);
177
178 if (rc < 0) {
179 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
180 __func__);
181 goto fail_gpio1;
182 }
183 }
184
185 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_truly_lcdc),
186 regs_truly_lcdc);
187 if (rc)
188 pr_err("%s: could not get regulators: %d\n", __func__, rc);
189
190 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_truly_lcdc),
191 regs_truly_lcdc);
192 if (rc)
193 pr_err("%s: could not set voltages: %d\n", __func__, rc);
194
195 return;
196
197fail_gpio1:
198 if (socinfo == 0x0B)
199 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530200 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530201 gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
202fail_gpio2:
203 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
204 return;
205}
206
207int sku3_lcdc_lcd_camera_power_onoff(int on)
208{
209 int rc = 0;
210 u32 socinfo = socinfo_get_platform_type();
211
212 if (on) {
213 if (socinfo == 0x0B)
214 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
215 1);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530216 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530217 gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
218 1);
219
220 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 1);
221
222 rc = regulator_bulk_enable(ARRAY_SIZE(regs_truly_lcdc),
223 regs_truly_lcdc);
224 if (rc)
225 pr_err("%s: could not enable regulators: %d\n",
226 __func__, rc);
227 } else {
228 if (socinfo == 0x0B)
229 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
230 0);
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_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
233 0);
234
235 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0);
236
237 rc = regulator_bulk_disable(ARRAY_SIZE(regs_truly_lcdc),
238 regs_truly_lcdc);
239 if (rc)
240 pr_err("%s: could not disable regulators: %d\n",
241 __func__, rc);
242 }
243
244 return rc;
245}
246
247static int sku3_lcdc_power_save(int on)
248{
249 int rc = 0;
250
251 if (on) {
252 sku3_lcdc_lcd_camera_power_onoff(1);
253 rc = lcdc_truly_gpio_init();
254 if (rc < 0) {
255 pr_err("%s(): Truly GPIO initializations failed",
256 __func__);
257 return rc;
258 }
259
260 if (lcdc_truly_gpio_initialized) {
261 /*LCD reset*/
262 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
263 msleep(20);
264 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
265 msleep(20);
266 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
267 msleep(20);
268 }
269 } else {
270 /* pull down LCD IO to avoid current leakage */
271 gpio_set_value(SKU3_LCDC_GPIO_SPI_MOSI, 0);
272 gpio_set_value(SKU3_LCDC_GPIO_SPI_CLK, 0);
273 gpio_set_value(SKU3_LCDC_GPIO_SPI_CS0_N, 0);
274 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
275
276 sku3_lcdc_lcd_camera_power_onoff(0);
277 }
278 return rc;
279}
280
281static struct msm_panel_common_pdata lcdc_truly_panel_data = {
282 .panel_config_gpio = NULL,
283 .gpio_num = lcdc_truly_gpio_table,
284};
285
286static struct platform_device lcdc_truly_panel_device = {
287 .name = "lcdc_truly_hvga_ips3p2335_pt",
288 .id = 0,
289 .dev = {
290 .platform_data = &lcdc_truly_panel_data,
291 }
292};
293
Chintan Pandya250c2e52012-01-19 17:15:49 +0530294static struct regulator_bulk_data regs_lcdc[] = {
295 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
296 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
297};
298static uint32_t lcdc_gpio_initialized;
299
300static void lcdc_toshiba_gpio_init(void)
301{
302 int rc = 0;
303 if (!lcdc_gpio_initialized) {
304 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
305 pr_err("failed to request gpio spi_clk\n");
306 return;
307 }
308 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
309 pr_err("failed to request gpio spi_cs0_N\n");
310 goto fail_gpio6;
311 }
312 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
313 pr_err("failed to request gpio spi_mosi\n");
314 goto fail_gpio5;
315 }
316 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
317 pr_err("failed to request gpio spi_miso\n");
318 goto fail_gpio4;
319 }
320 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
321 pr_err("failed to request gpio_disp_pwr\n");
322 goto fail_gpio3;
323 }
324 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
325 pr_err("failed to request gpio_bkl_en\n");
326 goto fail_gpio2;
327 }
328 pmapp_disp_backlight_init();
329
330 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc),
331 regs_lcdc);
332 if (rc) {
333 pr_err("%s: could not get regulators: %d\n",
334 __func__, rc);
335 goto fail_gpio1;
336 }
337
338 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
339 regs_lcdc);
340 if (rc) {
341 pr_err("%s: could not set voltages: %d\n",
342 __func__, rc);
343 goto fail_vreg;
344 }
345 lcdc_gpio_initialized = 1;
346 }
347 return;
348fail_vreg:
349 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
350fail_gpio1:
351 gpio_free(GPIO_BACKLIGHT_EN);
352fail_gpio2:
353 gpio_free(GPIO_DISPLAY_PWR_EN);
354fail_gpio3:
355 gpio_free(GPIO_SPI_MISO);
356fail_gpio4:
357 gpio_free(GPIO_SPI_MOSI);
358fail_gpio5:
359 gpio_free(GPIO_SPI_CS0_N);
360fail_gpio6:
361 gpio_free(GPIO_SPI_CLK);
362 lcdc_gpio_initialized = 0;
363}
364
365static uint32_t lcdc_gpio_table[] = {
366 GPIO_SPI_CLK,
367 GPIO_SPI_CS0_N,
368 GPIO_SPI_MOSI,
369 GPIO_DISPLAY_PWR_EN,
370 GPIO_BACKLIGHT_EN,
371 GPIO_SPI_MISO,
372};
373
374static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
375{
376 int n;
377
378 if (lcdc_gpio_initialized) {
379 /* All are IO Expander GPIOs */
380 for (n = 0; n < (len - 1); n++)
381 gpio_direction_output(table[n], 1);
382 }
383}
384
385static void lcdc_toshiba_config_gpios(int enable)
386{
387 config_lcdc_gpio_table(lcdc_gpio_table,
388 ARRAY_SIZE(lcdc_gpio_table), enable);
389}
390
391static int msm_fb_lcdc_power_save(int on)
392{
393 int rc = 0;
394 /* Doing the init of the LCDC GPIOs very late as they are from
395 an I2C-controlled IO Expander */
396 lcdc_toshiba_gpio_init();
397
398 if (lcdc_gpio_initialized) {
399 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
400 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
401
402 rc = on ? regulator_bulk_enable(
403 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
404 regulator_bulk_disable(
405 ARRAY_SIZE(regs_lcdc), regs_lcdc);
406
407 if (rc)
408 pr_err("%s: could not %sable regulators: %d\n",
409 __func__, on ? "en" : "dis", rc);
410 }
411
412 return rc;
413}
414
415static int lcdc_toshiba_set_bl(int level)
416{
417 int ret;
418
419 ret = pmapp_disp_backlight_set_brightness(level);
420 if (ret)
421 pr_err("%s: can't set lcd backlight!\n", __func__);
422
423 return ret;
424}
425
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530426
427static int msm_lcdc_power_save(int on)
428{
429 int rc = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530430 if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530431 rc = sku3_lcdc_power_save(on);
432 else
433 rc = msm_fb_lcdc_power_save(on);
434
435 return rc;
436}
437
Chintan Pandya250c2e52012-01-19 17:15:49 +0530438static struct lcdc_platform_data lcdc_pdata = {
439 .lcdc_gpio_config = NULL,
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530440 .lcdc_power_save = msm_lcdc_power_save,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530441};
442
443static int lcd_panel_spi_gpio_num[] = {
444 GPIO_SPI_MOSI, /* spi_sdi */
445 GPIO_SPI_MISO, /* spi_sdoi */
446 GPIO_SPI_CLK, /* spi_clk */
447 GPIO_SPI_CS0_N, /* spi_cs */
448};
449
450static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
451 .panel_config_gpio = lcdc_toshiba_config_gpios,
452 .pmic_backlight = lcdc_toshiba_set_bl,
453 .gpio_num = lcd_panel_spi_gpio_num,
454};
455
456static struct platform_device lcdc_toshiba_panel_device = {
457 .name = "lcdc_toshiba_fwvga_pt",
458 .id = 0,
459 .dev = {
460 .platform_data = &lcdc_toshiba_panel_data,
461 }
462};
463
464static struct resource msm_fb_resources[] = {
465 {
466 .flags = IORESOURCE_DMA,
467 }
468};
469
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800470#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
471static struct resource msm_v4l2_video_overlay_resources[] = {
472 {
473 .flags = IORESOURCE_DMA,
474 }
475};
476#endif
477
Chintan Pandya250c2e52012-01-19 17:15:49 +0530478#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
479#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
480
481static int msm_fb_detect_panel(const char *name)
482{
483 int ret = -ENODEV;
484
Taniya Dase3027e22012-02-27 16:32:27 +0530485 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
486 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530487 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
488 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
489 ret = 0;
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +0530490 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
491 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530492 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
493 ret = 0;
494 } else if (machine_is_msm7627a_qrd1()) {
495 if (!strncmp(name, "mipi_video_truly_wvga", 21))
496 ret = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530497 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530498 if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
499 ret = 0;
Jeevan Shriram66c3c2d2012-06-12 17:46:53 +0530500 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
501 machine_is_msm8625_evt()) {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530502 if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
503 ret = 0;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530504 }
505
506#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
507 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
508 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
509 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530510 machine_is_msm7625a_surf() ||
511 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530512 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
513 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
514 PANEL_NAME_MAX_LEN)))
515 return 0;
516 }
517#endif
518
519 return ret;
520}
521
522static int mipi_truly_set_bl(int on)
523{
524 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
525
526 return 1;
527}
528
529static struct msm_fb_platform_data msm_fb_pdata = {
530 .detect_client = msm_fb_detect_panel,
531};
532
533static struct platform_device msm_fb_device = {
534 .name = "msm_fb",
535 .id = 0,
536 .num_resources = ARRAY_SIZE(msm_fb_resources),
537 .resource = msm_fb_resources,
538 .dev = {
539 .platform_data = &msm_fb_pdata,
540 }
541};
542
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800543#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
544static struct platform_device msm_v4l2_video_overlay_device = {
545 .name = "msm_v4l2_overlay_pd",
546 .id = 0,
547 .num_resources = ARRAY_SIZE(msm_v4l2_video_overlay_resources),
548 .resource = msm_v4l2_video_overlay_resources,
549 };
550#endif
551
552
Chintan Pandya250c2e52012-01-19 17:15:49 +0530553#ifdef CONFIG_FB_MSM_MIPI_DSI
554static int mipi_renesas_set_bl(int level)
555{
556 int ret;
557
558 ret = pmapp_disp_backlight_set_brightness(level);
559
560 if (ret)
561 pr_err("%s: can't set lcd backlight!\n", __func__);
562
563 return ret;
564}
565
566static struct msm_panel_common_pdata mipi_renesas_pdata = {
567 .pmic_backlight = mipi_renesas_set_bl,
568};
569
570
571static struct platform_device mipi_dsi_renesas_panel_device = {
572 .name = "mipi_renesas",
573 .id = 0,
574 .dev = {
575 .platform_data = &mipi_renesas_pdata,
576 }
577};
578#endif
579
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530580static int evb_backlight_control(int level, int mode)
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530581{
582
583 int i = 0;
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530584 int remainder, ret = 0;
585
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530586 /* device address byte = 0x72 */
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530587 if (!mode) {
588 gpio_set_value(96, 0);
589 udelay(67);
590 gpio_set_value(96, 1);
591 udelay(33);
592 gpio_set_value(96, 0);
593 udelay(33);
594 gpio_set_value(96, 1);
595 udelay(67);
596 gpio_set_value(96, 0);
597 udelay(33);
598 gpio_set_value(96, 1);
599 udelay(67);
600 gpio_set_value(96, 0);
601 udelay(33);
602 gpio_set_value(96, 1);
603 udelay(67);
604 gpio_set_value(96, 0);
605 udelay(67);
606 gpio_set_value(96, 1);
607 udelay(33);
608 gpio_set_value(96, 0);
609 udelay(67);
610 gpio_set_value(96, 1);
611 udelay(33);
612 gpio_set_value(96, 0);
613 udelay(33);
614 gpio_set_value(96, 1);
615 udelay(67);
616 gpio_set_value(96, 0);
617 udelay(67);
618 gpio_set_value(96, 1);
619 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530620
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530621 /* t-EOS and t-start */
622 gpio_set_value(96, 0);
623 ndelay(4200);
624 gpio_set_value(96, 1);
625 ndelay(9000);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530626
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530627 /* data byte */
628 /* RFA = 0 */
629 gpio_set_value(96, 0);
630 udelay(67);
631 gpio_set_value(96, 1);
632 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530633
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530634 /* Address bits */
635 gpio_set_value(96, 0);
636 udelay(67);
637 gpio_set_value(96, 1);
638 udelay(33);
639 gpio_set_value(96, 0);
640 udelay(67);
641 gpio_set_value(96, 1);
642 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530643
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530644 /* Data bits */
645 for (i = 0; i < 5; i++) {
646 remainder = (level) & (16);
647 if (remainder) {
648 gpio_set_value(96, 0);
649 udelay(33);
650 gpio_set_value(96, 1);
651 udelay(67);
652 } else {
653 gpio_set_value(96, 0);
654 udelay(67);
655 gpio_set_value(96, 1);
656 udelay(33);
657 }
658 level = level << 1;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530659 }
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530660
661 /* t-EOS */
662 gpio_set_value(96, 0);
663 ndelay(12000);
664 gpio_set_value(96, 1);
665 } else {
666 ret = pmapp_disp_backlight_set_brightness(level);
667 if (ret)
668 pr_err("%s: can't set lcd backlight!\n", __func__);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530669 }
670
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530671 return ret;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530672}
673
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530674static int mipi_NT35510_rotate_panel(void)
675{
676 int rotate = 0;
677 if (machine_is_msm8625_evt())
678 rotate = 1;
679
680 return rotate;
681}
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530682
Chintan Pandya250c2e52012-01-19 17:15:49 +0530683static struct msm_panel_common_pdata mipi_truly_pdata = {
684 .pmic_backlight = mipi_truly_set_bl,
685};
686
687static struct platform_device mipi_dsi_truly_panel_device = {
688 .name = "mipi_truly",
689 .id = 0,
690 .dev = {
691 .platform_data = &mipi_truly_pdata,
692 }
693};
694
Jeevan Shrirame941df42012-01-23 12:40:21 +0530695static struct msm_panel_common_pdata mipi_NT35510_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530696 .backlight = evb_backlight_control,
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530697 .rotate_panel = mipi_NT35510_rotate_panel,
Jeevan Shrirame941df42012-01-23 12:40:21 +0530698};
699
700static struct platform_device mipi_dsi_NT35510_panel_device = {
701 .name = "mipi_NT35510",
702 .id = 0,
703 .dev = {
704 .platform_data = &mipi_NT35510_pdata,
705 }
706};
707
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530708static struct msm_panel_common_pdata mipi_NT35516_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530709 .backlight = evb_backlight_control,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530710};
711
712static struct platform_device mipi_dsi_NT35516_panel_device = {
713 .name = "mipi_truly_tft540960_1_e",
714 .id = 0,
715 .dev = {
716 .platform_data = &mipi_NT35516_pdata,
717 }
718};
719
Chintan Pandya250c2e52012-01-19 17:15:49 +0530720static struct platform_device *msm_fb_devices[] __initdata = {
721 &msm_fb_device,
722 &lcdc_toshiba_panel_device,
723#ifdef CONFIG_FB_MSM_MIPI_DSI
724 &mipi_dsi_renesas_panel_device,
725#endif
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800726#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
727 &msm_v4l2_video_overlay_device,
728#endif
Chintan Pandya250c2e52012-01-19 17:15:49 +0530729};
730
731static struct platform_device *qrd_fb_devices[] __initdata = {
732 &msm_fb_device,
733 &mipi_dsi_truly_panel_device,
734};
735
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530736static struct platform_device *qrd3_fb_devices[] __initdata = {
737 &msm_fb_device,
738 &lcdc_truly_panel_device,
739};
740
Taniya Dasc868a2e2012-01-03 10:18:47 +0530741static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530742 &msm_fb_device,
743 &mipi_dsi_NT35510_panel_device,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530744 &mipi_dsi_NT35516_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530745};
746
Chintan Pandya250c2e52012-01-19 17:15:49 +0530747void __init msm_msm7627a_allocate_memory_regions(void)
748{
749 void *addr;
750 unsigned long fb_size;
751
752 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
753 fb_size = MSM7x25A_MSM_FB_SIZE;
Aparna Mallavarapu5a326242012-05-09 19:49:02 +0530754 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
755 || machine_is_msm8625_evt())
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530756 fb_size = MSM8x25_MSM_FB_SIZE;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530757 else
758 fb_size = MSM_FB_SIZE;
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530759
Chintan Pandya250c2e52012-01-19 17:15:49 +0530760 addr = alloc_bootmem_align(fb_size, 0x1000);
761 msm_fb_resources[0].start = __pa(addr);
762 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
763 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
764 addr, __pa(addr));
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800765
766#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
767 fb_size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE;
768 addr = alloc_bootmem_align(fb_size, 0x1000);
769 msm_v4l2_video_overlay_resources[0].start = __pa(addr);
770 msm_v4l2_video_overlay_resources[0].end =
771 msm_v4l2_video_overlay_resources[0].start + fb_size - 1;
772 pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n",
773 fb_size, addr, __pa(addr));
774#endif
775
Chintan Pandya250c2e52012-01-19 17:15:49 +0530776}
777
778static struct msm_panel_common_pdata mdp_pdata = {
779 .gpio = 97,
780 .mdp_rev = MDP_REV_303,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +0530781 .cont_splash_enabled = 0x1,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530782};
783
784#define GPIO_LCDC_BRDG_PD 128
785#define GPIO_LCDC_BRDG_RESET_N 129
786#define GPIO_LCD_DSI_SEL 125
787#define LCDC_RESET_PHYS 0x90008014
788
789static void __iomem *lcdc_reset_ptr;
790
791static unsigned mipi_dsi_gpio[] = {
792 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
793 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
794 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
795 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
796};
797
798static unsigned lcd_dsi_sel_gpio[] = {
799 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
800 GPIO_CFG_2MA),
801};
802
803enum {
804 DSI_SINGLE_LANE = 1,
805 DSI_TWO_LANES,
806};
807
808static int msm_fb_get_lane_config(void)
809{
810 /* For MSM7627A SURF/FFA and QRD */
811 int rc = DSI_TWO_LANES;
812 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
813 rc = DSI_SINGLE_LANE;
814 pr_info("DSI_SINGLE_LANES\n");
815 } else {
816 pr_info("DSI_TWO_LANES\n");
817 }
818 return rc;
819}
820
821static int msm_fb_dsi_client_msm_reset(void)
822{
823 int rc = 0;
824
825 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
826 if (rc < 0) {
827 pr_err("failed to request lcd brdg reset_n\n");
828 return rc;
829 }
830
831 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
832 if (rc < 0) {
833 pr_err("failed to request lcd brdg pd\n");
834 return rc;
835 }
836
837 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
838 if (rc) {
839 pr_err("Failed to enable LCDC Bridge reset enable\n");
840 goto gpio_error;
841 }
842
843 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
844 if (rc) {
845 pr_err("Failed to enable LCDC Bridge pd enable\n");
846 goto gpio_error2;
847 }
848
849 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
850 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
851 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
852
853 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530854 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
855 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530856 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
857 sizeof(uint32_t));
858
859 if (!lcdc_reset_ptr)
860 return 0;
861 }
862 return rc;
863 } else {
864 goto gpio_error;
865 }
866
867gpio_error2:
868 pr_err("Failed GPIO bridge pd\n");
869 gpio_free(GPIO_LCDC_BRDG_PD);
870
871gpio_error:
872 pr_err("Failed GPIO bridge reset\n");
873 gpio_free(GPIO_LCDC_BRDG_RESET_N);
874 return rc;
875}
876
877static int mipi_truly_sel_mode(int video_mode)
878{
879 int rc = 0;
880
881 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
882 if (rc < 0)
883 goto gpio_error;
884
885 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
886 if (rc)
887 goto gpio_error;
888
889 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
890 if (!rc) {
891 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
892 return rc;
893 } else {
894 goto gpio_error;
895 }
896
897gpio_error:
898 pr_err("mipi_truly_sel_mode failed\n");
899 gpio_free(GPIO_LCD_DSI_SEL);
900 return rc;
901}
902
903static int msm_fb_dsi_client_qrd1_reset(void)
904{
905 int rc = 0;
906
907 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
908 if (rc < 0) {
909 pr_err("failed to request lcd brdg reset_n\n");
910 return rc;
911 }
912
913 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
914 if (rc < 0) {
915 pr_err("Failed to enable LCDC Bridge reset enable\n");
916 return rc;
917 }
918
919 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
920 if (rc < 0) {
921 pr_err("Failed GPIO bridge pd\n");
922 gpio_free(GPIO_LCDC_BRDG_RESET_N);
923 return rc;
924 }
925
926 mipi_truly_sel_mode(1);
927
928 return rc;
929}
930
Jeevan Shrirame941df42012-01-23 12:40:21 +0530931#define GPIO_QRD3_LCD_BRDG_RESET_N 85
932#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
933#define GPIO_QRD3_LCD_EXT_2V85_EN 35
934#define GPIO_QRD3_LCD_EXT_1V8_EN 40
935
936static unsigned qrd3_mipi_dsi_gpio[] = {
937 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
938 GPIO_CFG_NO_PULL,
939 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
940 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
941 GPIO_CFG_NO_PULL,
942 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
943 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
944 GPIO_CFG_NO_PULL,
945 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
946 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
947 GPIO_CFG_NO_PULL,
948 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
949};
950
951static int msm_fb_dsi_client_qrd3_reset(void)
952{
953 int rc = 0;
954
955 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
956 if (rc < 0) {
957 pr_err("failed to request qrd3 lcd brdg reset_n\n");
958 return rc;
959 }
960
Jeevan Shrirame941df42012-01-23 12:40:21 +0530961 return rc;
962}
963
Chintan Pandya250c2e52012-01-19 17:15:49 +0530964static int msm_fb_dsi_client_reset(void)
965{
966 int rc = 0;
967
968 if (machine_is_msm7627a_qrd1())
969 rc = msm_fb_dsi_client_qrd1_reset();
Aparna Mallavarapu5a326242012-05-09 19:49:02 +0530970 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
971 || machine_is_msm8625_evt())
Jeevan Shrirame941df42012-01-23 12:40:21 +0530972 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +0530973 else
974 rc = msm_fb_dsi_client_msm_reset();
975
976 return rc;
977
978}
979
980static struct regulator_bulk_data regs_dsi[] = {
981 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
982 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
983};
984
985static int dsi_gpio_initialized;
986
987static int mipi_dsi_panel_msm_power(int on)
988{
989 int rc = 0;
990 uint32_t lcdc_reset_cfg;
991
992 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
993 if (unlikely(!dsi_gpio_initialized)) {
994 pmapp_disp_backlight_init();
995
996 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
997 if (rc < 0) {
998 pr_err("failed to request gpio_disp_pwr\n");
999 return rc;
1000 }
1001
Taniya Dase3027e22012-02-27 16:32:27 +05301002 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
1003 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301004 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
1005 if (rc < 0) {
1006 pr_err("failed to enable display pwr\n");
1007 goto fail_gpio1;
1008 }
1009
1010 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1011 if (rc < 0) {
1012 pr_err("failed to request gpio_bkl_en\n");
1013 goto fail_gpio1;
1014 }
1015
1016 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
1017 if (rc < 0) {
1018 pr_err("failed to enable backlight\n");
1019 goto fail_gpio2;
1020 }
1021 }
1022
1023 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
1024 if (rc) {
1025 pr_err("%s: could not get regulators: %d\n",
1026 __func__, rc);
1027 goto fail_gpio2;
1028 }
1029
1030 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
1031 regs_dsi);
1032 if (rc) {
1033 pr_err("%s: could not set voltages: %d\n",
1034 __func__, rc);
1035 goto fail_vreg;
1036 }
1037 if (pmapp_disp_backlight_set_brightness(100))
1038 pr_err("backlight set brightness failed\n");
1039
1040 dsi_gpio_initialized = 1;
1041 }
Taniya Dase3027e22012-02-27 16:32:27 +05301042 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
1043 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301044 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1045 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +05301046 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
1047 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301048 if (on) {
1049 /* This line drives an active low pin on FFA */
1050 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
1051 if (rc < 0)
1052 pr_err("failed to set direction for "
1053 "display pwr\n");
1054 } else {
1055 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
1056 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
1057 if (rc < 0)
1058 pr_err("failed to set direction for "
1059 "display pwr\n");
1060 }
1061 }
1062
1063 if (on) {
1064 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
1065
1066 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +05301067 machine_is_msm7625a_surf() ||
1068 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301069 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
1070 rmb();
1071 lcdc_reset_cfg &= ~1;
1072
1073 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1074 msleep(20);
1075 wmb();
1076 lcdc_reset_cfg |= 1;
1077 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1078 } else {
1079 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1080 msleep(20);
1081 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1082 }
1083 } else {
1084 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301085 }
1086
1087 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
1088 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
1089
1090 if (rc)
1091 pr_err("%s: could not %sable regulators: %d\n",
1092 __func__, on ? "en" : "dis", rc);
1093
1094 return rc;
1095fail_vreg:
1096 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
1097fail_gpio2:
1098 gpio_free(GPIO_BACKLIGHT_EN);
1099fail_gpio1:
1100 gpio_free(GPIO_DISPLAY_PWR_EN);
1101 dsi_gpio_initialized = 0;
1102 return rc;
1103}
1104
1105static int mipi_dsi_panel_qrd1_power(int on)
1106{
1107 int rc = 0;
1108
1109 if (!dsi_gpio_initialized) {
1110 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1111 if (rc < 0)
1112 return rc;
1113
1114 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
1115 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1116 GPIO_CFG_ENABLE);
1117 if (rc < 0) {
1118 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
1119 return rc;
1120 }
1121
1122 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
1123 if (rc < 0) {
1124 pr_err("failed to enable backlight\n");
1125 gpio_free(QRD_GPIO_BACKLIGHT_EN);
1126 return rc;
1127 }
1128 dsi_gpio_initialized = 1;
1129 }
1130
1131 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
1132
Jeevan Shrirame941df42012-01-23 12:40:21 +05301133 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301134 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1135 msleep(20);
1136 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1137 msleep(20);
1138 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1139
1140 }
1141
1142 return rc;
1143}
1144
Jeevan Shrirame941df42012-01-23 12:40:21 +05301145static int qrd3_dsi_gpio_initialized;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301146static struct regulator *gpio_reg_2p85v, *gpio_reg_1p8v;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301147
1148static int mipi_dsi_panel_qrd3_power(int on)
1149{
1150 int rc = 0;
1151
1152 if (!qrd3_dsi_gpio_initialized) {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +05301153 pmapp_disp_backlight_init();
Jeevan Shrirame941df42012-01-23 12:40:21 +05301154 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
1155 "qrd3_gpio_bkl_en");
1156 if (rc < 0)
1157 return rc;
1158
Jeevan Shriram4461a112012-06-01 22:08:47 +05301159 qrd3_dsi_gpio_initialized = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301160
1161 if (mdp_pdata.cont_splash_enabled) {
1162 rc = gpio_tlmm_config(GPIO_CFG(
1163 GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
1164 GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
1165 if (rc < 0) {
1166 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1167 return rc;
1168 }
1169 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN,
1170 1);
1171 if (rc < 0) {
1172 pr_err("failed to enable backlight\n");
1173 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1174 return rc;
1175 }
1176
1177 /*Configure LCD Bridge reset*/
1178 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0],
1179 GPIO_CFG_ENABLE);
1180 if (rc < 0) {
1181 pr_err("Failed to enable LCD Bridge reset enable\n");
1182 return rc;
1183 }
1184
1185 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N,
1186 1);
1187
1188 if (rc < 0) {
1189 pr_err("Failed GPIO bridge Reset\n");
1190 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1191 return rc;
1192 }
1193 return 0;
1194 }
Jeevan Shrirame941df42012-01-23 12:40:21 +05301195 }
1196
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301197 if (on) {
Padmanabhan Komanduru6dadd872012-04-12 12:20:12 +05301198 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1199 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
1200 GPIO_CFG_ENABLE);
1201 if (rc < 0) {
1202 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1203 return rc;
1204 }
1205 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1206 if (rc < 0) {
1207 pr_err("failed to enable backlight\n");
1208 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1209 return rc;
1210 }
Jeevan Shriram4461a112012-06-01 22:08:47 +05301211 /*Toggle Backlight GPIO*/
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301212 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301213 udelay(100);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301214 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301215 udelay(430);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301216 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1217 /* 1 wire mode starts from this low to high transition */
1218 udelay(50);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301219
Jeevan Shriram4461a112012-06-01 22:08:47 +05301220 /*Enable EXT_2.85 and 1.8 regulators*/
1221 rc = regulator_enable(gpio_reg_2p85v);
1222 if (rc < 0)
1223 pr_err("%s: reg enable failed\n", __func__);
1224 rc = regulator_enable(gpio_reg_1p8v);
1225 if (rc < 0)
1226 pr_err("%s: reg enable failed\n", __func__);
Jeevan Shrirame941df42012-01-23 12:40:21 +05301227
Jeevan Shriram4461a112012-06-01 22:08:47 +05301228 /*Configure LCD Bridge reset*/
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301229 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301230 if (rc < 0) {
1231 pr_err("Failed to enable LCD Bridge reset enable\n");
1232 return rc;
1233 }
1234
1235 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1236
1237 if (rc < 0) {
1238 pr_err("Failed GPIO bridge Reset\n");
1239 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1240 return rc;
1241 }
1242
Jeevan Shriram4461a112012-06-01 22:08:47 +05301243 /*Toggle Bridge Reset GPIO*/
Jeevan Shrirame941df42012-01-23 12:40:21 +05301244 msleep(20);
1245 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
1246 msleep(20);
1247 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1248 msleep(20);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301249
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301250 } else {
Jeevan Shriram4461a112012-06-01 22:08:47 +05301251 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1252 GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
1253 GPIO_CFG_DISABLE);
1254
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301255 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
1256 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1257 GPIO_CFG_DISABLE);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301258
1259 rc = regulator_disable(gpio_reg_2p85v);
1260 if (rc < 0)
1261 pr_err("%s: reg disable failed\n", __func__);
1262 rc = regulator_disable(gpio_reg_1p8v);
1263 if (rc < 0)
1264 pr_err("%s: reg disable failed\n", __func__);
1265
Jeevan Shrirame941df42012-01-23 12:40:21 +05301266 }
1267
Jeevan Shriram4461a112012-06-01 22:08:47 +05301268 return rc;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301269}
1270
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301271static char mipi_dsi_splash_is_enabled(void);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301272static int mipi_dsi_panel_power(int on)
1273{
1274 int rc = 0;
1275
1276 if (machine_is_msm7627a_qrd1())
1277 rc = mipi_dsi_panel_qrd1_power(on);
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301278 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1279 || machine_is_msm8625_evt())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301280 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301281 else
1282 rc = mipi_dsi_panel_msm_power(on);
1283 return rc;
1284}
1285
1286#define MDP_303_VSYNC_GPIO 97
1287
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301288#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301289static struct mipi_dsi_platform_data mipi_dsi_pdata = {
1290 .vsync_gpio = MDP_303_VSYNC_GPIO,
1291 .dsi_power_save = mipi_dsi_panel_power,
1292 .dsi_client_reset = msm_fb_dsi_client_reset,
1293 .get_lane_config = msm_fb_get_lane_config,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301294 .splash_is_enabled = mipi_dsi_splash_is_enabled,
Chintan Pandya250c2e52012-01-19 17:15:49 +05301295};
1296#endif
1297
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301298static char mipi_dsi_splash_is_enabled(void)
1299{
1300 return mdp_pdata.cont_splash_enabled;
1301}
1302
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301303static char prim_panel_name[PANEL_NAME_MAX_LEN];
1304static int __init prim_display_setup(char *param)
1305{
1306 if (strnlen(param, PANEL_NAME_MAX_LEN))
1307 strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
1308 return 0;
1309}
1310early_param("prim_display", prim_display_setup);
1311
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301312static int disable_splash;
1313
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301314void msm7x27a_set_display_params(char *prim_panel)
1315{
1316 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1317 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1318 PANEL_NAME_MAX_LEN);
1319 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1320 msm_fb_pdata.prim_panel_name);
1321 }
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301322 if (strnlen(msm_fb_pdata.prim_panel_name, PANEL_NAME_MAX_LEN)) {
1323 if (strncmp((char *)msm_fb_pdata.prim_panel_name,
1324 "mipi_cmd_nt35510_wvga",
1325 strnlen("mipi_cmd_nt35510_wvga",
1326 PANEL_NAME_MAX_LEN)) &&
1327 strncmp((char *)msm_fb_pdata.prim_panel_name,
1328 "mipi_video_nt35510_wvga",
1329 strnlen("mipi_video_nt35510_wvga",
1330 PANEL_NAME_MAX_LEN)))
1331 disable_splash = 1;
1332 }
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301333}
1334
Chintan Pandya250c2e52012-01-19 17:15:49 +05301335void __init msm_fb_add_devices(void)
1336{
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301337 int rc = 0;
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301338 msm7x27a_set_display_params(prim_panel_name);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301339 if (machine_is_msm7627a_qrd1())
1340 platform_add_devices(qrd_fb_devices,
1341 ARRAY_SIZE(qrd_fb_devices));
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301342 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1343 || machine_is_msm8625_evt()) {
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301344 mipi_NT35510_pdata.bl_lock = 1;
Padmanabhan Komanduru0f0000a2012-04-12 10:23:02 +05301345 mipi_NT35516_pdata.bl_lock = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301346 if (disable_splash)
1347 mdp_pdata.cont_splash_enabled = 0x0;
1348
1349
Taniya Dasc868a2e2012-01-03 10:18:47 +05301350 platform_add_devices(evb_fb_devices,
1351 ARRAY_SIZE(evb_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301352 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301353 sku3_lcdc_lcd_camera_power_init();
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301354 mdp_pdata.cont_splash_enabled = 0x0;
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301355 platform_add_devices(qrd3_fb_devices,
1356 ARRAY_SIZE(qrd3_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301357 } else {
1358 mdp_pdata.cont_splash_enabled = 0x0;
Chintan Pandya250c2e52012-01-19 17:15:49 +05301359 platform_add_devices(msm_fb_devices,
1360 ARRAY_SIZE(msm_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301361 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301362
1363 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +05301364 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
Jeevan Shriram045cdc72012-03-27 07:04:15 +05301365 machine_is_msm8625_surf() || machine_is_msm7627a_qrd3()
1366 || machine_is_msm8625_qrd7())
Chintan Pandya250c2e52012-01-19 17:15:49 +05301367 msm_fb_register_device("lcdc", &lcdc_pdata);
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301368#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301369 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1370#endif
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301371 if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1372 || machine_is_msm8625_evt()) {
1373 gpio_reg_2p85v = regulator_get(&mipi_dsi_device.dev,
1374 "lcd_vdd");
1375 if (IS_ERR(gpio_reg_2p85v))
1376 pr_err("%s:ext_2p85v regulator get failed", __func__);
1377
1378 gpio_reg_1p8v = regulator_get(&mipi_dsi_device.dev,
1379 "lcd_vddi");
1380 if (IS_ERR(gpio_reg_1p8v))
1381 pr_err("%s:ext_1p8v regulator get failed", __func__);
1382
1383 if (mdp_pdata.cont_splash_enabled) {
1384 /*Enable EXT_2.85 and 1.8 regulators*/
1385 rc = regulator_enable(gpio_reg_2p85v);
1386 if (rc < 0)
1387 pr_err("%s: reg enable failed\n", __func__);
1388 rc = regulator_enable(gpio_reg_1p8v);
1389 if (rc < 0)
1390 pr_err("%s: reg enable failed\n", __func__);
1391 }
1392 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301393}