blob: 7f033561590ef588be78f001f0e0beed87d9695a [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Chintan Pandya250c2e52012-01-19 17:15:49 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/platform_device.h>
16#include <linux/bootmem.h>
17#include <linux/regulator/consumer.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070018#include <linux/gpio.h>
Chintan Pandya250c2e52012-01-19 17:15:49 +053019#include <asm/mach-types.h>
20#include <asm/io.h>
21#include <mach/msm_bus_board.h>
22#include <mach/msm_memtypes.h>
23#include <mach/board.h>
Chintan Pandya250c2e52012-01-19 17:15:49 +053024#include <mach/gpiomux.h>
25#include <mach/socinfo.h>
26#include <mach/rpc_pmapp.h>
27#include "devices.h"
28#include "board-msm7627a.h"
29
30#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
Jeevan Shriram8c23e072012-03-14 11:35:49 +053031#define MSM_FB_SIZE 0x4BF000
32#define MSM7x25A_MSM_FB_SIZE 0x1C2000
33#define MSM8x25_MSM_FB_SIZE 0x5FA000
Chintan Pandya250c2e52012-01-19 17:15:49 +053034#else
Jeevan Shriram8c23e072012-03-14 11:35:49 +053035#define MSM_FB_SIZE 0x32A000
36#define MSM7x25A_MSM_FB_SIZE 0x12C000
37#define MSM8x25_MSM_FB_SIZE 0x3FC000
Chintan Pandya250c2e52012-01-19 17:15:49 +053038#endif
39
Alhad Purnapatrec55856c2012-02-28 13:24:57 -080040/*
41 * Reserve enough v4l2 space for a double buffered full screen
42 * res image (864x480x1.5x2)
43 */
44#define MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE 1244160
45
Chintan Pandya250c2e52012-01-19 17:15:49 +053046static unsigned fb_size = MSM_FB_SIZE;
47static int __init fb_size_setup(char *p)
48{
49 fb_size = memparse(p, NULL);
50 return 0;
51}
52
53early_param("fb_size", fb_size_setup);
54
Jeevan Shriram901a15f2012-03-09 11:53:23 +053055static uint32_t lcdc_truly_gpio_initialized;
56static struct regulator_bulk_data regs_truly_lcdc[] = {
57 { .supply = "rfrx1", .min_uV = 1800000, .max_uV = 1800000 },
58};
59
60#define SKU3_LCDC_GPIO_DISPLAY_RESET 90
61#define SKU3_LCDC_GPIO_SPI_MOSI 19
62#define SKU3_LCDC_GPIO_SPI_CLK 20
63#define SKU3_LCDC_GPIO_SPI_CS0_N 21
64#define SKU3_LCDC_LCD_CAMERA_LDO_2V8 35 /*LCD_CAMERA_LDO_2V8*/
65#define SKU3_LCDC_LCD_CAMERA_LDO_1V8 34 /*LCD_CAMERA_LDO_1V8*/
66#define SKU3_1_LCDC_LCD_CAMERA_LDO_1V8 58 /*LCD_CAMERA_LDO_1V8*/
67
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
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +053084static char lcdc_splash_is_enabled(void);
Jeevan Shriram901a15f2012-03-09 11:53:23 +053085static int lcdc_truly_gpio_init(void)
86{
87 int i;
88 int rc = 0;
89
90 if (!lcdc_truly_gpio_initialized) {
91 for (i = 0; i < ARRAY_SIZE(lcdc_truly_gpio_table); i++) {
92 rc = gpio_request(lcdc_truly_gpio_table[i],
93 lcdc_gpio_name_table[i]);
94 if (rc < 0) {
95 pr_err("Error request gpio %s\n",
96 lcdc_gpio_name_table[i]);
97 goto truly_gpio_fail;
98 }
99 rc = gpio_tlmm_config(GPIO_CFG(lcdc_truly_gpio_table[i],
100 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
101 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
102 if (rc < 0) {
103 pr_err("Error config lcdc gpio:%d\n",
104 lcdc_truly_gpio_table[i]);
105 goto truly_gpio_fail;
106 }
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530107 if (lcdc_splash_is_enabled())
108 rc = gpio_direction_output(
109 lcdc_truly_gpio_table[i], 1);
110 else
111 rc = gpio_direction_output(
112 lcdc_truly_gpio_table[i], 0);
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530113 if (rc < 0) {
114 pr_err("Error direct lcdc gpio:%d\n",
115 lcdc_truly_gpio_table[i]);
116 goto truly_gpio_fail;
117 }
118 }
119
120 lcdc_truly_gpio_initialized = 1;
121 }
122
123 return rc;
124
125truly_gpio_fail:
126 for (; i >= 0; i--) {
127 pr_err("Freeing GPIO: %d", lcdc_truly_gpio_table[i]);
128 gpio_free(lcdc_truly_gpio_table[i]);
129 }
130
131 lcdc_truly_gpio_initialized = 0;
132 return rc;
133}
134
135
136void sku3_lcdc_lcd_camera_power_init(void)
137{
138 int rc = 0;
139 u32 socinfo = socinfo_get_platform_type();
140
141 /* LDO_EXT2V8 */
142 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
143 pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
144 return;
145 }
146
147 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0,
148 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
149 GPIO_CFG_ENABLE);
150
151 if (rc < 0) {
152 pr_err("%s:unable to enable lcd_camera_ldo_2v8!\n", __func__);
153 goto fail_gpio2;
154 }
155
156 /* LDO_EVT1V8 */
157 if (socinfo == 0x0B) {
158 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
159 "lcd_camera_ldo_1v8")) {
160 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
161 goto fail_gpio1;
162 }
163
164 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_1V8, 0,
165 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
166 GPIO_CFG_ENABLE);
167
168 if (rc < 0) {
169 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
170 __func__);
171 goto fail_gpio1;
172 }
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530173 } else if (socinfo == 0x0F || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530174 if (gpio_request(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
175 "lcd_camera_ldo_1v8")) {
176 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
177 goto fail_gpio1;
178 }
179
180 rc = gpio_tlmm_config(GPIO_CFG(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
181 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
182 GPIO_CFG_ENABLE);
183
184 if (rc < 0) {
185 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
186 __func__);
187 goto fail_gpio1;
188 }
189 }
190
191 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_truly_lcdc),
192 regs_truly_lcdc);
193 if (rc)
194 pr_err("%s: could not get regulators: %d\n", __func__, rc);
195
196 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_truly_lcdc),
197 regs_truly_lcdc);
198 if (rc)
199 pr_err("%s: could not set voltages: %d\n", __func__, rc);
200
201 return;
202
203fail_gpio1:
204 if (socinfo == 0x0B)
205 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530206 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530207 gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
208fail_gpio2:
209 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
210 return;
211}
212
213int sku3_lcdc_lcd_camera_power_onoff(int on)
214{
215 int rc = 0;
216 u32 socinfo = socinfo_get_platform_type();
217
218 if (on) {
219 if (socinfo == 0x0B)
220 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
221 1);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530222 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530223 gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
224 1);
225
226 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 1);
227
228 rc = regulator_bulk_enable(ARRAY_SIZE(regs_truly_lcdc),
229 regs_truly_lcdc);
230 if (rc)
231 pr_err("%s: could not enable regulators: %d\n",
232 __func__, rc);
233 } else {
234 if (socinfo == 0x0B)
235 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
236 0);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530237 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530238 gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
239 0);
240
241 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0);
242
243 rc = regulator_bulk_disable(ARRAY_SIZE(regs_truly_lcdc),
244 regs_truly_lcdc);
245 if (rc)
246 pr_err("%s: could not disable regulators: %d\n",
247 __func__, rc);
248 }
249
250 return rc;
251}
252
253static int sku3_lcdc_power_save(int on)
254{
255 int rc = 0;
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530256 static int cont_splash_done;
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530257
258 if (on) {
259 sku3_lcdc_lcd_camera_power_onoff(1);
260 rc = lcdc_truly_gpio_init();
261 if (rc < 0) {
262 pr_err("%s(): Truly GPIO initializations failed",
263 __func__);
264 return rc;
265 }
266
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530267 if (lcdc_splash_is_enabled() && !cont_splash_done) {
268 cont_splash_done = 1;
269 return rc;
270 }
271
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530272 if (lcdc_truly_gpio_initialized) {
273 /*LCD reset*/
274 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
275 msleep(20);
276 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
277 msleep(20);
278 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
279 msleep(20);
280 }
281 } else {
282 /* pull down LCD IO to avoid current leakage */
283 gpio_set_value(SKU3_LCDC_GPIO_SPI_MOSI, 0);
284 gpio_set_value(SKU3_LCDC_GPIO_SPI_CLK, 0);
285 gpio_set_value(SKU3_LCDC_GPIO_SPI_CS0_N, 0);
286 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
287
288 sku3_lcdc_lcd_camera_power_onoff(0);
289 }
290 return rc;
291}
292
293static struct msm_panel_common_pdata lcdc_truly_panel_data = {
294 .panel_config_gpio = NULL,
295 .gpio_num = lcdc_truly_gpio_table,
296};
297
298static struct platform_device lcdc_truly_panel_device = {
299 .name = "lcdc_truly_hvga_ips3p2335_pt",
300 .id = 0,
301 .dev = {
302 .platform_data = &lcdc_truly_panel_data,
303 }
304};
305
Chintan Pandya250c2e52012-01-19 17:15:49 +0530306static struct regulator_bulk_data regs_lcdc[] = {
307 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
308 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
309};
310static uint32_t lcdc_gpio_initialized;
311
312static void lcdc_toshiba_gpio_init(void)
313{
314 int rc = 0;
315 if (!lcdc_gpio_initialized) {
316 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
317 pr_err("failed to request gpio spi_clk\n");
318 return;
319 }
320 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
321 pr_err("failed to request gpio spi_cs0_N\n");
322 goto fail_gpio6;
323 }
324 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
325 pr_err("failed to request gpio spi_mosi\n");
326 goto fail_gpio5;
327 }
328 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
329 pr_err("failed to request gpio spi_miso\n");
330 goto fail_gpio4;
331 }
332 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
333 pr_err("failed to request gpio_disp_pwr\n");
334 goto fail_gpio3;
335 }
336 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
337 pr_err("failed to request gpio_bkl_en\n");
338 goto fail_gpio2;
339 }
340 pmapp_disp_backlight_init();
341
342 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc),
343 regs_lcdc);
344 if (rc) {
345 pr_err("%s: could not get regulators: %d\n",
346 __func__, rc);
347 goto fail_gpio1;
348 }
349
350 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
351 regs_lcdc);
352 if (rc) {
353 pr_err("%s: could not set voltages: %d\n",
354 __func__, rc);
355 goto fail_vreg;
356 }
357 lcdc_gpio_initialized = 1;
358 }
359 return;
360fail_vreg:
361 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
362fail_gpio1:
363 gpio_free(GPIO_BACKLIGHT_EN);
364fail_gpio2:
365 gpio_free(GPIO_DISPLAY_PWR_EN);
366fail_gpio3:
367 gpio_free(GPIO_SPI_MISO);
368fail_gpio4:
369 gpio_free(GPIO_SPI_MOSI);
370fail_gpio5:
371 gpio_free(GPIO_SPI_CS0_N);
372fail_gpio6:
373 gpio_free(GPIO_SPI_CLK);
374 lcdc_gpio_initialized = 0;
375}
376
377static uint32_t lcdc_gpio_table[] = {
378 GPIO_SPI_CLK,
379 GPIO_SPI_CS0_N,
380 GPIO_SPI_MOSI,
381 GPIO_DISPLAY_PWR_EN,
382 GPIO_BACKLIGHT_EN,
383 GPIO_SPI_MISO,
384};
385
386static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
387{
388 int n;
389
390 if (lcdc_gpio_initialized) {
391 /* All are IO Expander GPIOs */
392 for (n = 0; n < (len - 1); n++)
393 gpio_direction_output(table[n], 1);
394 }
395}
396
397static void lcdc_toshiba_config_gpios(int enable)
398{
399 config_lcdc_gpio_table(lcdc_gpio_table,
400 ARRAY_SIZE(lcdc_gpio_table), enable);
401}
402
403static int msm_fb_lcdc_power_save(int on)
404{
405 int rc = 0;
406 /* Doing the init of the LCDC GPIOs very late as they are from
407 an I2C-controlled IO Expander */
408 lcdc_toshiba_gpio_init();
409
410 if (lcdc_gpio_initialized) {
411 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
412 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
413
414 rc = on ? regulator_bulk_enable(
415 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
416 regulator_bulk_disable(
417 ARRAY_SIZE(regs_lcdc), regs_lcdc);
418
419 if (rc)
420 pr_err("%s: could not %sable regulators: %d\n",
421 __func__, on ? "en" : "dis", rc);
422 }
423
424 return rc;
425}
426
427static int lcdc_toshiba_set_bl(int level)
428{
429 int ret;
430
431 ret = pmapp_disp_backlight_set_brightness(level);
432 if (ret)
433 pr_err("%s: can't set lcd backlight!\n", __func__);
434
435 return ret;
436}
437
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530438
439static int msm_lcdc_power_save(int on)
440{
441 int rc = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530442 if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530443 rc = sku3_lcdc_power_save(on);
444 else
445 rc = msm_fb_lcdc_power_save(on);
446
447 return rc;
448}
449
Chintan Pandya250c2e52012-01-19 17:15:49 +0530450static struct lcdc_platform_data lcdc_pdata = {
451 .lcdc_gpio_config = NULL,
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530452 .lcdc_power_save = msm_lcdc_power_save,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530453};
454
455static int lcd_panel_spi_gpio_num[] = {
456 GPIO_SPI_MOSI, /* spi_sdi */
457 GPIO_SPI_MISO, /* spi_sdoi */
458 GPIO_SPI_CLK, /* spi_clk */
459 GPIO_SPI_CS0_N, /* spi_cs */
460};
461
462static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
463 .panel_config_gpio = lcdc_toshiba_config_gpios,
464 .pmic_backlight = lcdc_toshiba_set_bl,
465 .gpio_num = lcd_panel_spi_gpio_num,
466};
467
468static struct platform_device lcdc_toshiba_panel_device = {
469 .name = "lcdc_toshiba_fwvga_pt",
470 .id = 0,
471 .dev = {
472 .platform_data = &lcdc_toshiba_panel_data,
473 }
474};
475
476static struct resource msm_fb_resources[] = {
477 {
478 .flags = IORESOURCE_DMA,
479 }
480};
481
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800482#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
483static struct resource msm_v4l2_video_overlay_resources[] = {
484 {
485 .flags = IORESOURCE_DMA,
486 }
487};
488#endif
489
Chintan Pandya250c2e52012-01-19 17:15:49 +0530490#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
491#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
492
493static int msm_fb_detect_panel(const char *name)
494{
495 int ret = -ENODEV;
496
Taniya Dase3027e22012-02-27 16:32:27 +0530497 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
498 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530499 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
500 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
501 ret = 0;
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +0530502 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
503 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530504 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
505 ret = 0;
506 } else if (machine_is_msm7627a_qrd1()) {
507 if (!strncmp(name, "mipi_video_truly_wvga", 21))
508 ret = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530509 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530510 if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
511 ret = 0;
Jeevan Shriram66c3c2d2012-06-12 17:46:53 +0530512 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
513 machine_is_msm8625_evt()) {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530514 if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
515 ret = 0;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530516 }
517
518#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
519 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
520 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
521 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530522 machine_is_msm7625a_surf() ||
523 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530524 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
525 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
526 PANEL_NAME_MAX_LEN)))
527 return 0;
528 }
529#endif
530
531 return ret;
532}
533
534static int mipi_truly_set_bl(int on)
535{
536 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
537
538 return 1;
539}
540
541static struct msm_fb_platform_data msm_fb_pdata = {
542 .detect_client = msm_fb_detect_panel,
543};
544
545static struct platform_device msm_fb_device = {
546 .name = "msm_fb",
547 .id = 0,
548 .num_resources = ARRAY_SIZE(msm_fb_resources),
549 .resource = msm_fb_resources,
550 .dev = {
551 .platform_data = &msm_fb_pdata,
552 }
553};
554
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800555#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
556static struct platform_device msm_v4l2_video_overlay_device = {
557 .name = "msm_v4l2_overlay_pd",
558 .id = 0,
559 .num_resources = ARRAY_SIZE(msm_v4l2_video_overlay_resources),
560 .resource = msm_v4l2_video_overlay_resources,
561 };
562#endif
563
564
Chintan Pandya250c2e52012-01-19 17:15:49 +0530565#ifdef CONFIG_FB_MSM_MIPI_DSI
566static int mipi_renesas_set_bl(int level)
567{
568 int ret;
569
570 ret = pmapp_disp_backlight_set_brightness(level);
571
572 if (ret)
573 pr_err("%s: can't set lcd backlight!\n", __func__);
574
575 return ret;
576}
577
578static struct msm_panel_common_pdata mipi_renesas_pdata = {
579 .pmic_backlight = mipi_renesas_set_bl,
580};
581
582
583static struct platform_device mipi_dsi_renesas_panel_device = {
584 .name = "mipi_renesas",
585 .id = 0,
586 .dev = {
587 .platform_data = &mipi_renesas_pdata,
588 }
589};
590#endif
591
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530592static int evb_backlight_control(int level, int mode)
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530593{
594
595 int i = 0;
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530596 int remainder, ret = 0;
597
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530598 /* device address byte = 0x72 */
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530599 if (!mode) {
600 gpio_set_value(96, 0);
601 udelay(67);
602 gpio_set_value(96, 1);
603 udelay(33);
604 gpio_set_value(96, 0);
605 udelay(33);
606 gpio_set_value(96, 1);
607 udelay(67);
608 gpio_set_value(96, 0);
609 udelay(33);
610 gpio_set_value(96, 1);
611 udelay(67);
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);
620 gpio_set_value(96, 0);
621 udelay(67);
622 gpio_set_value(96, 1);
623 udelay(33);
624 gpio_set_value(96, 0);
625 udelay(33);
626 gpio_set_value(96, 1);
627 udelay(67);
628 gpio_set_value(96, 0);
629 udelay(67);
630 gpio_set_value(96, 1);
631 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530632
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530633 /* t-EOS and t-start */
634 gpio_set_value(96, 0);
635 ndelay(4200);
636 gpio_set_value(96, 1);
637 ndelay(9000);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530638
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530639 /* data byte */
640 /* RFA = 0 */
641 gpio_set_value(96, 0);
642 udelay(67);
643 gpio_set_value(96, 1);
644 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530645
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530646 /* Address bits */
647 gpio_set_value(96, 0);
648 udelay(67);
649 gpio_set_value(96, 1);
650 udelay(33);
651 gpio_set_value(96, 0);
652 udelay(67);
653 gpio_set_value(96, 1);
654 udelay(33);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530655
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530656 /* Data bits */
657 for (i = 0; i < 5; i++) {
658 remainder = (level) & (16);
659 if (remainder) {
660 gpio_set_value(96, 0);
661 udelay(33);
662 gpio_set_value(96, 1);
663 udelay(67);
664 } else {
665 gpio_set_value(96, 0);
666 udelay(67);
667 gpio_set_value(96, 1);
668 udelay(33);
669 }
670 level = level << 1;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530671 }
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530672
673 /* t-EOS */
674 gpio_set_value(96, 0);
675 ndelay(12000);
676 gpio_set_value(96, 1);
677 } else {
678 ret = pmapp_disp_backlight_set_brightness(level);
679 if (ret)
680 pr_err("%s: can't set lcd backlight!\n", __func__);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530681 }
682
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530683 return ret;
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530684}
685
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530686static int mipi_NT35510_rotate_panel(void)
687{
688 int rotate = 0;
689 if (machine_is_msm8625_evt())
690 rotate = 1;
691
692 return rotate;
693}
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530694
Chintan Pandya250c2e52012-01-19 17:15:49 +0530695static struct msm_panel_common_pdata mipi_truly_pdata = {
696 .pmic_backlight = mipi_truly_set_bl,
697};
698
699static struct platform_device mipi_dsi_truly_panel_device = {
700 .name = "mipi_truly",
701 .id = 0,
702 .dev = {
703 .platform_data = &mipi_truly_pdata,
704 }
705};
706
Jeevan Shrirame941df42012-01-23 12:40:21 +0530707static struct msm_panel_common_pdata mipi_NT35510_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530708 .backlight = evb_backlight_control,
Jeevan Shriram8f7c96d2012-05-15 12:42:57 +0530709 .rotate_panel = mipi_NT35510_rotate_panel,
Jeevan Shrirame941df42012-01-23 12:40:21 +0530710};
711
712static struct platform_device mipi_dsi_NT35510_panel_device = {
713 .name = "mipi_NT35510",
714 .id = 0,
715 .dev = {
716 .platform_data = &mipi_NT35510_pdata,
717 }
718};
719
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530720static struct msm_panel_common_pdata mipi_NT35516_pdata = {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +0530721 .backlight = evb_backlight_control,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530722};
723
724static struct platform_device mipi_dsi_NT35516_panel_device = {
725 .name = "mipi_truly_tft540960_1_e",
726 .id = 0,
727 .dev = {
728 .platform_data = &mipi_NT35516_pdata,
729 }
730};
731
Chintan Pandya250c2e52012-01-19 17:15:49 +0530732static struct platform_device *msm_fb_devices[] __initdata = {
733 &msm_fb_device,
734 &lcdc_toshiba_panel_device,
735#ifdef CONFIG_FB_MSM_MIPI_DSI
736 &mipi_dsi_renesas_panel_device,
737#endif
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800738#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
739 &msm_v4l2_video_overlay_device,
740#endif
Chintan Pandya250c2e52012-01-19 17:15:49 +0530741};
742
743static struct platform_device *qrd_fb_devices[] __initdata = {
744 &msm_fb_device,
745 &mipi_dsi_truly_panel_device,
746};
747
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530748static struct platform_device *qrd3_fb_devices[] __initdata = {
749 &msm_fb_device,
750 &lcdc_truly_panel_device,
751};
752
Taniya Dasc868a2e2012-01-03 10:18:47 +0530753static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530754 &msm_fb_device,
755 &mipi_dsi_NT35510_panel_device,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530756 &mipi_dsi_NT35516_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530757};
758
Chintan Pandya250c2e52012-01-19 17:15:49 +0530759void __init msm_msm7627a_allocate_memory_regions(void)
760{
761 void *addr;
762 unsigned long fb_size;
763
764 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
765 fb_size = MSM7x25A_MSM_FB_SIZE;
Aparna Mallavarapu5a326242012-05-09 19:49:02 +0530766 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
767 || machine_is_msm8625_evt())
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530768 fb_size = MSM8x25_MSM_FB_SIZE;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530769 else
770 fb_size = MSM_FB_SIZE;
Jeevan Shriram8c23e072012-03-14 11:35:49 +0530771
Chintan Pandya250c2e52012-01-19 17:15:49 +0530772 addr = alloc_bootmem_align(fb_size, 0x1000);
773 msm_fb_resources[0].start = __pa(addr);
774 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
775 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
776 addr, __pa(addr));
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800777
778#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
779 fb_size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE;
780 addr = alloc_bootmem_align(fb_size, 0x1000);
781 msm_v4l2_video_overlay_resources[0].start = __pa(addr);
782 msm_v4l2_video_overlay_resources[0].end =
783 msm_v4l2_video_overlay_resources[0].start + fb_size - 1;
784 pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n",
785 fb_size, addr, __pa(addr));
786#endif
787
Chintan Pandya250c2e52012-01-19 17:15:49 +0530788}
789
790static struct msm_panel_common_pdata mdp_pdata = {
791 .gpio = 97,
792 .mdp_rev = MDP_REV_303,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +0530793 .cont_splash_enabled = 0x1,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530794};
795
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +0530796static char lcdc_splash_is_enabled()
797{
798 return mdp_pdata.cont_splash_enabled;
799}
800
Chintan Pandya250c2e52012-01-19 17:15:49 +0530801#define GPIO_LCDC_BRDG_PD 128
802#define GPIO_LCDC_BRDG_RESET_N 129
803#define GPIO_LCD_DSI_SEL 125
804#define LCDC_RESET_PHYS 0x90008014
805
806static void __iomem *lcdc_reset_ptr;
807
808static unsigned mipi_dsi_gpio[] = {
809 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
810 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
811 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
812 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
813};
814
815static unsigned lcd_dsi_sel_gpio[] = {
816 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
817 GPIO_CFG_2MA),
818};
819
820enum {
821 DSI_SINGLE_LANE = 1,
822 DSI_TWO_LANES,
823};
824
825static int msm_fb_get_lane_config(void)
826{
827 /* For MSM7627A SURF/FFA and QRD */
828 int rc = DSI_TWO_LANES;
829 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
830 rc = DSI_SINGLE_LANE;
831 pr_info("DSI_SINGLE_LANES\n");
832 } else {
833 pr_info("DSI_TWO_LANES\n");
834 }
835 return rc;
836}
837
838static int msm_fb_dsi_client_msm_reset(void)
839{
840 int rc = 0;
841
842 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
843 if (rc < 0) {
844 pr_err("failed to request lcd brdg reset_n\n");
845 return rc;
846 }
847
848 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
849 if (rc < 0) {
850 pr_err("failed to request lcd brdg pd\n");
851 return rc;
852 }
853
854 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
855 if (rc) {
856 pr_err("Failed to enable LCDC Bridge reset enable\n");
857 goto gpio_error;
858 }
859
860 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
861 if (rc) {
862 pr_err("Failed to enable LCDC Bridge pd enable\n");
863 goto gpio_error2;
864 }
865
866 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
867 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
868 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
869
870 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530871 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
872 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530873 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
874 sizeof(uint32_t));
875
876 if (!lcdc_reset_ptr)
877 return 0;
878 }
879 return rc;
880 } else {
881 goto gpio_error;
882 }
883
884gpio_error2:
885 pr_err("Failed GPIO bridge pd\n");
886 gpio_free(GPIO_LCDC_BRDG_PD);
887
888gpio_error:
889 pr_err("Failed GPIO bridge reset\n");
890 gpio_free(GPIO_LCDC_BRDG_RESET_N);
891 return rc;
892}
893
894static int mipi_truly_sel_mode(int video_mode)
895{
896 int rc = 0;
897
898 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
899 if (rc < 0)
900 goto gpio_error;
901
902 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
903 if (rc)
904 goto gpio_error;
905
906 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
907 if (!rc) {
908 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
909 return rc;
910 } else {
911 goto gpio_error;
912 }
913
914gpio_error:
915 pr_err("mipi_truly_sel_mode failed\n");
916 gpio_free(GPIO_LCD_DSI_SEL);
917 return rc;
918}
919
920static int msm_fb_dsi_client_qrd1_reset(void)
921{
922 int rc = 0;
923
924 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
925 if (rc < 0) {
926 pr_err("failed to request lcd brdg reset_n\n");
927 return rc;
928 }
929
930 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
931 if (rc < 0) {
932 pr_err("Failed to enable LCDC Bridge reset enable\n");
933 return rc;
934 }
935
936 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
937 if (rc < 0) {
938 pr_err("Failed GPIO bridge pd\n");
939 gpio_free(GPIO_LCDC_BRDG_RESET_N);
940 return rc;
941 }
942
943 mipi_truly_sel_mode(1);
944
945 return rc;
946}
947
Jeevan Shrirame941df42012-01-23 12:40:21 +0530948#define GPIO_QRD3_LCD_BRDG_RESET_N 85
949#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
950#define GPIO_QRD3_LCD_EXT_2V85_EN 35
951#define GPIO_QRD3_LCD_EXT_1V8_EN 40
952
953static unsigned qrd3_mipi_dsi_gpio[] = {
954 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
955 GPIO_CFG_NO_PULL,
956 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
957 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
958 GPIO_CFG_NO_PULL,
959 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
960 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
961 GPIO_CFG_NO_PULL,
962 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
963 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
964 GPIO_CFG_NO_PULL,
965 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
966};
967
968static int msm_fb_dsi_client_qrd3_reset(void)
969{
970 int rc = 0;
971
972 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
973 if (rc < 0) {
974 pr_err("failed to request qrd3 lcd brdg reset_n\n");
975 return rc;
976 }
977
Jeevan Shrirame941df42012-01-23 12:40:21 +0530978 return rc;
979}
980
Chintan Pandya250c2e52012-01-19 17:15:49 +0530981static int msm_fb_dsi_client_reset(void)
982{
983 int rc = 0;
984
985 if (machine_is_msm7627a_qrd1())
986 rc = msm_fb_dsi_client_qrd1_reset();
Aparna Mallavarapu5a326242012-05-09 19:49:02 +0530987 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
988 || machine_is_msm8625_evt())
Jeevan Shrirame941df42012-01-23 12:40:21 +0530989 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +0530990 else
991 rc = msm_fb_dsi_client_msm_reset();
992
993 return rc;
994
995}
996
997static struct regulator_bulk_data regs_dsi[] = {
998 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
999 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
1000};
1001
1002static int dsi_gpio_initialized;
1003
1004static int mipi_dsi_panel_msm_power(int on)
1005{
1006 int rc = 0;
1007 uint32_t lcdc_reset_cfg;
1008
1009 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
1010 if (unlikely(!dsi_gpio_initialized)) {
1011 pmapp_disp_backlight_init();
1012
1013 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
1014 if (rc < 0) {
1015 pr_err("failed to request gpio_disp_pwr\n");
1016 return rc;
1017 }
1018
Taniya Dase3027e22012-02-27 16:32:27 +05301019 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
1020 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301021 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
1022 if (rc < 0) {
1023 pr_err("failed to enable display pwr\n");
1024 goto fail_gpio1;
1025 }
1026
1027 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1028 if (rc < 0) {
1029 pr_err("failed to request gpio_bkl_en\n");
1030 goto fail_gpio1;
1031 }
1032
1033 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
1034 if (rc < 0) {
1035 pr_err("failed to enable backlight\n");
1036 goto fail_gpio2;
1037 }
1038 }
1039
1040 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
1041 if (rc) {
1042 pr_err("%s: could not get regulators: %d\n",
1043 __func__, rc);
1044 goto fail_gpio2;
1045 }
1046
1047 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
1048 regs_dsi);
1049 if (rc) {
1050 pr_err("%s: could not set voltages: %d\n",
1051 __func__, rc);
1052 goto fail_vreg;
1053 }
1054 if (pmapp_disp_backlight_set_brightness(100))
1055 pr_err("backlight set brightness failed\n");
1056
1057 dsi_gpio_initialized = 1;
1058 }
Taniya Dase3027e22012-02-27 16:32:27 +05301059 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
1060 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301061 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1062 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +05301063 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
1064 || machine_is_msm8625_ffa()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301065 if (on) {
1066 /* This line drives an active low pin on FFA */
1067 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
1068 if (rc < 0)
1069 pr_err("failed to set direction for "
1070 "display pwr\n");
1071 } else {
1072 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
1073 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
1074 if (rc < 0)
1075 pr_err("failed to set direction for "
1076 "display pwr\n");
1077 }
1078 }
1079
1080 if (on) {
1081 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
1082
1083 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +05301084 machine_is_msm7625a_surf() ||
1085 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301086 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
1087 rmb();
1088 lcdc_reset_cfg &= ~1;
1089
1090 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1091 msleep(20);
1092 wmb();
1093 lcdc_reset_cfg |= 1;
1094 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1095 } else {
1096 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1097 msleep(20);
1098 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1099 }
1100 } else {
1101 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301102 }
1103
1104 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
1105 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
1106
1107 if (rc)
1108 pr_err("%s: could not %sable regulators: %d\n",
1109 __func__, on ? "en" : "dis", rc);
1110
1111 return rc;
1112fail_vreg:
1113 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
1114fail_gpio2:
1115 gpio_free(GPIO_BACKLIGHT_EN);
1116fail_gpio1:
1117 gpio_free(GPIO_DISPLAY_PWR_EN);
1118 dsi_gpio_initialized = 0;
1119 return rc;
1120}
1121
1122static int mipi_dsi_panel_qrd1_power(int on)
1123{
1124 int rc = 0;
1125
1126 if (!dsi_gpio_initialized) {
1127 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1128 if (rc < 0)
1129 return rc;
1130
1131 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
1132 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1133 GPIO_CFG_ENABLE);
1134 if (rc < 0) {
1135 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
1136 return rc;
1137 }
1138
1139 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
1140 if (rc < 0) {
1141 pr_err("failed to enable backlight\n");
1142 gpio_free(QRD_GPIO_BACKLIGHT_EN);
1143 return rc;
1144 }
1145 dsi_gpio_initialized = 1;
1146 }
1147
1148 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
1149
Jeevan Shrirame941df42012-01-23 12:40:21 +05301150 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301151 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1152 msleep(20);
1153 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1154 msleep(20);
1155 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1156
1157 }
1158
1159 return rc;
1160}
1161
Jeevan Shrirame941df42012-01-23 12:40:21 +05301162static int qrd3_dsi_gpio_initialized;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301163static struct regulator *gpio_reg_2p85v, *gpio_reg_1p8v;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301164
1165static int mipi_dsi_panel_qrd3_power(int on)
1166{
1167 int rc = 0;
1168
1169 if (!qrd3_dsi_gpio_initialized) {
Padmanabhan Komandurucc913992012-05-09 14:57:28 +05301170 pmapp_disp_backlight_init();
Jeevan Shrirame941df42012-01-23 12:40:21 +05301171 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
1172 "qrd3_gpio_bkl_en");
1173 if (rc < 0)
1174 return rc;
1175
Jeevan Shriram4461a112012-06-01 22:08:47 +05301176 qrd3_dsi_gpio_initialized = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301177
1178 if (mdp_pdata.cont_splash_enabled) {
1179 rc = gpio_tlmm_config(GPIO_CFG(
1180 GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
1181 GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
1182 if (rc < 0) {
1183 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1184 return rc;
1185 }
1186 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN,
1187 1);
1188 if (rc < 0) {
1189 pr_err("failed to enable backlight\n");
1190 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1191 return rc;
1192 }
1193
1194 /*Configure LCD Bridge reset*/
1195 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0],
1196 GPIO_CFG_ENABLE);
1197 if (rc < 0) {
1198 pr_err("Failed to enable LCD Bridge reset enable\n");
1199 return rc;
1200 }
1201
1202 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N,
1203 1);
1204
1205 if (rc < 0) {
1206 pr_err("Failed GPIO bridge Reset\n");
1207 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1208 return rc;
1209 }
1210 return 0;
1211 }
Jeevan Shrirame941df42012-01-23 12:40:21 +05301212 }
1213
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301214 if (on) {
Padmanabhan Komanduru6dadd872012-04-12 12:20:12 +05301215 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1216 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
1217 GPIO_CFG_ENABLE);
1218 if (rc < 0) {
1219 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1220 return rc;
1221 }
1222 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1223 if (rc < 0) {
1224 pr_err("failed to enable backlight\n");
1225 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1226 return rc;
1227 }
Jeevan Shriram4461a112012-06-01 22:08:47 +05301228 /*Toggle Backlight GPIO*/
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301229 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301230 udelay(100);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301231 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
Padmanabhan Komanduru3c48a682012-07-04 17:33:53 +05301232 udelay(430);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301233 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1234 /* 1 wire mode starts from this low to high transition */
1235 udelay(50);
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301236
Jeevan Shriram4461a112012-06-01 22:08:47 +05301237 /*Enable EXT_2.85 and 1.8 regulators*/
1238 rc = regulator_enable(gpio_reg_2p85v);
1239 if (rc < 0)
1240 pr_err("%s: reg enable failed\n", __func__);
1241 rc = regulator_enable(gpio_reg_1p8v);
1242 if (rc < 0)
1243 pr_err("%s: reg enable failed\n", __func__);
Jeevan Shrirame941df42012-01-23 12:40:21 +05301244
Jeevan Shriram4461a112012-06-01 22:08:47 +05301245 /*Configure LCD Bridge reset*/
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301246 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301247 if (rc < 0) {
1248 pr_err("Failed to enable LCD Bridge reset enable\n");
1249 return rc;
1250 }
1251
1252 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1253
1254 if (rc < 0) {
1255 pr_err("Failed GPIO bridge Reset\n");
1256 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1257 return rc;
1258 }
1259
Jeevan Shriram4461a112012-06-01 22:08:47 +05301260 /*Toggle Bridge Reset GPIO*/
Jeevan Shrirame941df42012-01-23 12:40:21 +05301261 msleep(20);
1262 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
1263 msleep(20);
1264 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1265 msleep(20);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301266
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301267 } else {
Jeevan Shriram4461a112012-06-01 22:08:47 +05301268 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
1269 GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
1270 GPIO_CFG_DISABLE);
1271
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301272 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
1273 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1274 GPIO_CFG_DISABLE);
Jeevan Shriram4461a112012-06-01 22:08:47 +05301275
1276 rc = regulator_disable(gpio_reg_2p85v);
1277 if (rc < 0)
1278 pr_err("%s: reg disable failed\n", __func__);
1279 rc = regulator_disable(gpio_reg_1p8v);
1280 if (rc < 0)
1281 pr_err("%s: reg disable failed\n", __func__);
1282
Jeevan Shrirame941df42012-01-23 12:40:21 +05301283 }
1284
Jeevan Shriram4461a112012-06-01 22:08:47 +05301285 return rc;
Jeevan Shrirame941df42012-01-23 12:40:21 +05301286}
1287
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301288static char mipi_dsi_splash_is_enabled(void);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301289static int mipi_dsi_panel_power(int on)
1290{
1291 int rc = 0;
1292
1293 if (machine_is_msm7627a_qrd1())
1294 rc = mipi_dsi_panel_qrd1_power(on);
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301295 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1296 || machine_is_msm8625_evt())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301297 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301298 else
1299 rc = mipi_dsi_panel_msm_power(on);
1300 return rc;
1301}
1302
1303#define MDP_303_VSYNC_GPIO 97
1304
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301305#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301306static struct mipi_dsi_platform_data mipi_dsi_pdata = {
1307 .vsync_gpio = MDP_303_VSYNC_GPIO,
1308 .dsi_power_save = mipi_dsi_panel_power,
1309 .dsi_client_reset = msm_fb_dsi_client_reset,
1310 .get_lane_config = msm_fb_get_lane_config,
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301311 .splash_is_enabled = mipi_dsi_splash_is_enabled,
Chintan Pandya250c2e52012-01-19 17:15:49 +05301312};
1313#endif
1314
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301315static char mipi_dsi_splash_is_enabled(void)
1316{
1317 return mdp_pdata.cont_splash_enabled;
1318}
1319
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301320static char prim_panel_name[PANEL_NAME_MAX_LEN];
1321static int __init prim_display_setup(char *param)
1322{
1323 if (strnlen(param, PANEL_NAME_MAX_LEN))
1324 strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
1325 return 0;
1326}
1327early_param("prim_display", prim_display_setup);
1328
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301329static int disable_splash;
1330
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301331void msm7x27a_set_display_params(char *prim_panel)
1332{
1333 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1334 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1335 PANEL_NAME_MAX_LEN);
1336 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1337 msm_fb_pdata.prim_panel_name);
1338 }
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301339 if (strnlen(msm_fb_pdata.prim_panel_name, PANEL_NAME_MAX_LEN)) {
1340 if (strncmp((char *)msm_fb_pdata.prim_panel_name,
1341 "mipi_cmd_nt35510_wvga",
1342 strnlen("mipi_cmd_nt35510_wvga",
1343 PANEL_NAME_MAX_LEN)) &&
1344 strncmp((char *)msm_fb_pdata.prim_panel_name,
1345 "mipi_video_nt35510_wvga",
1346 strnlen("mipi_video_nt35510_wvga",
1347 PANEL_NAME_MAX_LEN)))
1348 disable_splash = 1;
1349 }
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301350}
1351
Chintan Pandya250c2e52012-01-19 17:15:49 +05301352void __init msm_fb_add_devices(void)
1353{
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301354 int rc = 0;
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301355 msm7x27a_set_display_params(prim_panel_name);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301356 if (machine_is_msm7627a_qrd1())
1357 platform_add_devices(qrd_fb_devices,
1358 ARRAY_SIZE(qrd_fb_devices));
Aparna Mallavarapu5a326242012-05-09 19:49:02 +05301359 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1360 || machine_is_msm8625_evt()) {
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301361 mipi_NT35510_pdata.bl_lock = 1;
Padmanabhan Komanduru0f0000a2012-04-12 10:23:02 +05301362 mipi_NT35516_pdata.bl_lock = 1;
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301363 if (disable_splash)
1364 mdp_pdata.cont_splash_enabled = 0x0;
1365
1366
Taniya Dasc868a2e2012-01-03 10:18:47 +05301367 platform_add_devices(evb_fb_devices,
1368 ARRAY_SIZE(evb_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301369 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301370 sku3_lcdc_lcd_camera_power_init();
Padmanabhan Komanduru5f3807b2012-07-04 00:06:20 +05301371 mdp_pdata.cont_splash_enabled = 0x1;
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301372 platform_add_devices(qrd3_fb_devices,
1373 ARRAY_SIZE(qrd3_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301374 } else {
1375 mdp_pdata.cont_splash_enabled = 0x0;
Chintan Pandya250c2e52012-01-19 17:15:49 +05301376 platform_add_devices(msm_fb_devices,
1377 ARRAY_SIZE(msm_fb_devices));
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301378 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301379
1380 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +05301381 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
Jeevan Shriram045cdc72012-03-27 07:04:15 +05301382 machine_is_msm8625_surf() || machine_is_msm7627a_qrd3()
1383 || machine_is_msm8625_qrd7())
Chintan Pandya250c2e52012-01-19 17:15:49 +05301384 msm_fb_register_device("lcdc", &lcdc_pdata);
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301385#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301386 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1387#endif
Padmanabhan Komanduru0a3699b2012-05-30 16:17:10 +05301388 if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
1389 || machine_is_msm8625_evt()) {
1390 gpio_reg_2p85v = regulator_get(&mipi_dsi_device.dev,
1391 "lcd_vdd");
1392 if (IS_ERR(gpio_reg_2p85v))
1393 pr_err("%s:ext_2p85v regulator get failed", __func__);
1394
1395 gpio_reg_1p8v = regulator_get(&mipi_dsi_device.dev,
1396 "lcd_vddi");
1397 if (IS_ERR(gpio_reg_1p8v))
1398 pr_err("%s:ext_1p8v regulator get failed", __func__);
1399
1400 if (mdp_pdata.cont_splash_enabled) {
1401 /*Enable EXT_2.85 and 1.8 regulators*/
1402 rc = regulator_enable(gpio_reg_2p85v);
1403 if (rc < 0)
1404 pr_err("%s: reg enable failed\n", __func__);
1405 rc = regulator_enable(gpio_reg_1p8v);
1406 if (rc < 0)
1407 pr_err("%s: reg enable failed\n", __func__);
1408 }
1409 }
Chintan Pandya250c2e52012-01-19 17:15:49 +05301410}