blob: 144cea509973b3523502a744e0e7bd5e6e3d77c3 [file] [log] [blame]
Huaibin Yang4a084e32011-12-15 15:25:52 -08001/* 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
14#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/platform_device.h>
17#include <linux/bootmem.h>
Ravishangar Kalyanam59a67b12012-02-13 14:29:56 -080018#include <linux/ion.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080019#include <asm/mach-types.h>
20#include <mach/msm_memtypes.h>
21#include <mach/board.h>
22#include <mach/gpio.h>
23#include <mach/gpiomux.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080024#include <mach/ion.h>
Ravishangar Kalyanam59a67b12012-02-13 14:29:56 -080025#include <mach/msm_bus_board.h>
Huaibin Yang02f981c2012-02-27 16:58:41 -080026#include <mach/socinfo.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080027
28#include "devices.h"
29#include "board-8064.h"
30
31#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
32/* prim = 1366 x 768 x 3(bpp) x 3(pages) */
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080033#define MSM_FB_PRIM_BUF_SIZE roundup(1376 * 768 * 4 * 3, 0x10000)
Huaibin Yang4a084e32011-12-15 15:25:52 -080034#else
35/* prim = 1366 x 768 x 3(bpp) x 2(pages) */
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080036#define MSM_FB_PRIM_BUF_SIZE roundup(1376 * 768 * 4 * 2, 0x10000)
Huaibin Yang4a084e32011-12-15 15:25:52 -080037#endif
38
39#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -080040#define MSM_FB_EXT_BUF_SIZE (1920 * 1088 * 2 * 1) /* 2 bpp x 1 page */
Huaibin Yang4a084e32011-12-15 15:25:52 -080041#elif defined(CONFIG_FB_MSM_TVOUT)
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -080042#define MSM_FB_EXT_BUF_SIZE (720 * 576 * 2 * 2) /* 2 bpp x 2 pages */
43#else
44#define MSM_FB_EXT_BUF_SIZE 0
45#endif
Huaibin Yang4a084e32011-12-15 15:25:52 -080046
47#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
48
49#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
50#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1376 * 768 * 3 * 2), 4096)
51#else
52#define MSM_FB_OVERLAY0_WRITEBACK_SIZE (0)
53#endif /* CONFIG_FB_MSM_OVERLAY0_WRITEBACK */
54
55#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
56#define MSM_FB_OVERLAY1_WRITEBACK_SIZE roundup((1920 * 1088 * 3 * 2), 4096)
57#else
58#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
59#endif /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
60
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080061
Huaibin Yang4a084e32011-12-15 15:25:52 -080062static struct resource msm_fb_resources[] = {
63 {
64 .flags = IORESOURCE_DMA,
65 }
66};
67
Huaibin Yang4a084e32011-12-15 15:25:52 -080068#define LVDS_CHIMEI_PANEL_NAME "lvds_chimei_wxga"
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080069#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
70#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
71#define HDMI_PANEL_NAME "hdmi_msm"
72#define TVOUT_PANEL_NAME "tvout_msm"
Huaibin Yang4a084e32011-12-15 15:25:52 -080073
74static int msm_fb_detect_panel(const char *name)
75{
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080076 if (machine_is_apq8064_liquid()) {
77 if (!strncmp(name, LVDS_CHIMEI_PANEL_NAME,
78 strnlen(LVDS_CHIMEI_PANEL_NAME,
79 PANEL_NAME_MAX_LEN)))
80 return 0;
81
82#if !defined(CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT) && \
83 !defined(CONFIG_FB_MSM_MIPI_PANEL_DETECT)
84 if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
85 strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
86 PANEL_NAME_MAX_LEN)))
87 return 0;
88#endif
89 } else if (machine_is_apq8064_mtp()) {
90 if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
91 strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
92 PANEL_NAME_MAX_LEN)))
93 return 0;
94 } else if (machine_is_apq8064_cdp()) {
95 if (!strncmp(name, LVDS_CHIMEI_PANEL_NAME,
96 strnlen(LVDS_CHIMEI_PANEL_NAME,
97 PANEL_NAME_MAX_LEN)))
98 return 0;
99 }
100
101 if (!strncmp(name, HDMI_PANEL_NAME,
102 strnlen(HDMI_PANEL_NAME,
103 PANEL_NAME_MAX_LEN)))
Huaibin Yang4a084e32011-12-15 15:25:52 -0800104 return 0;
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800105
Huaibin Yang4a084e32011-12-15 15:25:52 -0800106 return -ENODEV;
107}
108
109static struct msm_fb_platform_data msm_fb_pdata = {
110 .detect_client = msm_fb_detect_panel,
111};
112
113static struct platform_device msm_fb_device = {
114 .name = "msm_fb",
115 .id = 0,
116 .num_resources = ARRAY_SIZE(msm_fb_resources),
117 .resource = msm_fb_resources,
118 .dev.platform_data = &msm_fb_pdata,
119};
120
121void __init apq8064_allocate_fb_region(void)
122{
123 void *addr;
124 unsigned long size;
125
126 size = MSM_FB_SIZE;
127 addr = alloc_bootmem_align(size, 0x1000);
128 msm_fb_resources[0].start = __pa(addr);
129 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
130 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
131 size, addr, __pa(addr));
132}
133
134#define MDP_VSYNC_GPIO 0
135
Ravishangar Kalyanam59a67b12012-02-13 14:29:56 -0800136static struct msm_bus_vectors mdp_init_vectors[] = {
137 {
138 .src = MSM_BUS_MASTER_MDP_PORT0,
139 .dst = MSM_BUS_SLAVE_EBI_CH0,
140 .ab = 0,
141 .ib = 0,
142 },
143};
144
145static struct msm_bus_vectors mdp_ui_vectors[] = {
146 {
147 .src = MSM_BUS_MASTER_MDP_PORT0,
148 .dst = MSM_BUS_SLAVE_EBI_CH0,
149 .ab = 216000000 * 2,
150 .ib = 270000000 * 2,
151 },
152};
153
154static struct msm_bus_vectors mdp_vga_vectors[] = {
155 /* VGA and less video */
156 {
157 .src = MSM_BUS_MASTER_MDP_PORT0,
158 .dst = MSM_BUS_SLAVE_EBI_CH0,
159 .ab = 216000000 * 2,
160 .ib = 270000000 * 2,
161 },
162};
163
164static struct msm_bus_vectors mdp_720p_vectors[] = {
165 /* 720p and less video */
166 {
167 .src = MSM_BUS_MASTER_MDP_PORT0,
168 .dst = MSM_BUS_SLAVE_EBI_CH0,
169 .ab = 230400000 * 2,
170 .ib = 288000000 * 2,
171 },
172};
173
174static struct msm_bus_vectors mdp_1080p_vectors[] = {
175 /* 1080p and less video */
176 {
177 .src = MSM_BUS_MASTER_MDP_PORT0,
178 .dst = MSM_BUS_SLAVE_EBI_CH0,
179 .ab = 334080000 * 2,
180 .ib = 417600000 * 2,
181 },
182};
183
184static struct msm_bus_paths mdp_bus_scale_usecases[] = {
185 {
186 ARRAY_SIZE(mdp_init_vectors),
187 mdp_init_vectors,
188 },
189 {
190 ARRAY_SIZE(mdp_ui_vectors),
191 mdp_ui_vectors,
192 },
193 {
194 ARRAY_SIZE(mdp_ui_vectors),
195 mdp_ui_vectors,
196 },
197 {
198 ARRAY_SIZE(mdp_vga_vectors),
199 mdp_vga_vectors,
200 },
201 {
202 ARRAY_SIZE(mdp_720p_vectors),
203 mdp_720p_vectors,
204 },
205 {
206 ARRAY_SIZE(mdp_1080p_vectors),
207 mdp_1080p_vectors,
208 },
209};
210
211static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
212 mdp_bus_scale_usecases,
213 ARRAY_SIZE(mdp_bus_scale_usecases),
214 .name = "mdp",
215};
216
Huaibin Yang4a084e32011-12-15 15:25:52 -0800217static int mdp_core_clk_rate_table[] = {
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800218 200000000,
219 200000000,
220 200000000,
221 200000000,
Huaibin Yang4a084e32011-12-15 15:25:52 -0800222};
223
224static struct msm_panel_common_pdata mdp_pdata = {
225 .gpio = MDP_VSYNC_GPIO,
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800226 .mdp_core_clk_rate = 200000000,
Huaibin Yang4a084e32011-12-15 15:25:52 -0800227 .mdp_core_clk_table = mdp_core_clk_rate_table,
228 .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
Ravishangar Kalyanam59a67b12012-02-13 14:29:56 -0800229 .mdp_bus_scale_table = &mdp_bus_scale_pdata,
Huaibin Yang4a084e32011-12-15 15:25:52 -0800230 .mdp_rev = MDP_REV_44,
231#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
232 .mem_hid = ION_CP_MM_HEAP_ID,
233#else
234 .mem_hid = MEMTYPE_EBI1,
235#endif
236};
237
238void __init apq8064_mdp_writeback(struct memtype_reserve* reserve_table)
239{
240 mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
241 mdp_pdata.ov1_wb_size = MSM_FB_OVERLAY1_WRITEBACK_SIZE;
242#if defined(CONFIG_ANDROID_PMEM) && !defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
243 reserve_table[mdp_pdata.mem_hid].size +=
244 mdp_pdata.ov0_wb_size;
245 reserve_table[mdp_pdata.mem_hid].size +=
246 mdp_pdata.ov1_wb_size;
247#endif
248}
249
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800250static struct resource hdmi_msm_resources[] = {
251 {
252 .name = "hdmi_msm_qfprom_addr",
253 .start = 0x00700000,
254 .end = 0x007060FF,
255 .flags = IORESOURCE_MEM,
256 },
257 {
258 .name = "hdmi_msm_hdmi_addr",
259 .start = 0x04A00000,
260 .end = 0x04A00FFF,
261 .flags = IORESOURCE_MEM,
262 },
263 {
264 .name = "hdmi_msm_irq",
265 .start = HDMI_IRQ,
266 .end = HDMI_IRQ,
267 .flags = IORESOURCE_IRQ,
268 },
269};
270
271static int hdmi_enable_5v(int on);
272static int hdmi_core_power(int on, int show);
273static int hdmi_cec_power(int on);
274
275static struct msm_hdmi_platform_data hdmi_msm_data = {
276 .irq = HDMI_IRQ,
277 .enable_5v = hdmi_enable_5v,
278 .core_power = hdmi_core_power,
279 .cec_power = hdmi_cec_power,
280};
281
282static struct platform_device hdmi_msm_device = {
283 .name = "hdmi_msm",
284 .id = 0,
285 .num_resources = ARRAY_SIZE(hdmi_msm_resources),
286 .resource = hdmi_msm_resources,
287 .dev.platform_data = &hdmi_msm_data,
288};
289
290/* HDMI related GPIOs */
291#define HDMI_CEC_VAR_GPIO 69
292#define HDMI_DDC_CLK_GPIO 70
293#define HDMI_DDC_DATA_GPIO 71
294#define HDMI_HPD_GPIO 72
295
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800296static bool dsi_power_on;
297static int mipi_dsi_panel_power(int on)
298{
299 static struct regulator *reg_lvs7, *reg_l2, *reg_l11, *reg_ext_3p3v;
300 static int gpio36, gpio25, gpio26, mpp3;
301 int rc;
302
303 pr_debug("%s: on=%d\n", __func__, on);
304
305 if (!dsi_power_on) {
306 reg_lvs7 = regulator_get(&msm_mipi_dsi1_device.dev,
307 "dsi1_vddio");
308 if (IS_ERR_OR_NULL(reg_lvs7)) {
309 pr_err("could not get 8921_lvs7, rc = %ld\n",
310 PTR_ERR(reg_lvs7));
311 return -ENODEV;
312 }
313
314 reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
315 "dsi1_pll_vdda");
316 if (IS_ERR_OR_NULL(reg_l2)) {
317 pr_err("could not get 8921_l2, rc = %ld\n",
318 PTR_ERR(reg_l2));
319 return -ENODEV;
320 }
321
322 rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
323 if (rc) {
324 pr_err("set_voltage l2 failed, rc=%d\n", rc);
325 return -EINVAL;
326 }
327 reg_l11 = regulator_get(&msm_mipi_dsi1_device.dev,
328 "dsi1_avdd");
329 if (IS_ERR(reg_l11)) {
330 pr_err("could not get 8921_l11, rc = %ld\n",
331 PTR_ERR(reg_l11));
332 return -ENODEV;
333 }
334 rc = regulator_set_voltage(reg_l11, 3000000, 3000000);
335 if (rc) {
336 pr_err("set_voltage l11 failed, rc=%d\n", rc);
337 return -EINVAL;
338 }
339
340 if (machine_is_apq8064_liquid()) {
341 reg_ext_3p3v = regulator_get(&msm_mipi_dsi1_device.dev,
342 "dsi1_vccs_3p3v");
343 if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
344 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
345 PTR_ERR(reg_ext_3p3v));
346 reg_ext_3p3v = NULL;
347 return -ENODEV;
348 }
349 mpp3 = PM8921_MPP_PM_TO_SYS(3);
350 rc = gpio_request(mpp3, "backlight_en");
351 if (rc) {
352 pr_err("request mpp3 failed, rc=%d\n", rc);
353 return -ENODEV;
354 }
355 }
356
357 gpio25 = PM8921_GPIO_PM_TO_SYS(25);
358 rc = gpio_request(gpio25, "disp_rst_n");
359 if (rc) {
360 pr_err("request gpio 25 failed, rc=%d\n", rc);
361 return -ENODEV;
362 }
363
364 gpio26 = PM8921_GPIO_PM_TO_SYS(26);
365 rc = gpio_request(gpio26, "pwm_backlight_ctrl");
366 if (rc) {
367 pr_err("request gpio 26 failed, rc=%d\n", rc);
368 return -ENODEV;
369 }
370
371 gpio36 = PM8921_GPIO_PM_TO_SYS(36); /* lcd1_pwr_en_n */
372 rc = gpio_request(gpio36, "lcd1_pwr_en_n");
373 if (rc) {
374 pr_err("request gpio 36 failed, rc=%d\n", rc);
375 return -ENODEV;
376 }
377
378 dsi_power_on = true;
379 }
380
381 if (on) {
382 rc = regulator_enable(reg_lvs7);
383 if (rc) {
384 pr_err("enable lvs7 failed, rc=%d\n", rc);
385 return -ENODEV;
386 }
387
388 rc = regulator_set_optimum_mode(reg_l11, 110000);
389 if (rc < 0) {
390 pr_err("set_optimum_mode l11 failed, rc=%d\n", rc);
391 return -EINVAL;
392 }
393 rc = regulator_enable(reg_l11);
394 if (rc) {
395 pr_err("enable l11 failed, rc=%d\n", rc);
396 return -ENODEV;
397 }
398
399 rc = regulator_set_optimum_mode(reg_l2, 100000);
400 if (rc < 0) {
401 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
402 return -EINVAL;
403 }
404 rc = regulator_enable(reg_l2);
405 if (rc) {
406 pr_err("enable l2 failed, rc=%d\n", rc);
407 return -ENODEV;
408 }
409
410 if (machine_is_apq8064_liquid()) {
411 rc = regulator_enable(reg_ext_3p3v);
412 if (rc) {
413 pr_err("enable reg_ext_3p3v failed, rc=%d\n",
414 rc);
415 return -ENODEV;
416 }
417 gpio_set_value_cansleep(mpp3, 1);
418 }
419
420 gpio_set_value_cansleep(gpio36, 0);
421 gpio_set_value_cansleep(gpio25, 1);
422 } else {
423 gpio_set_value_cansleep(gpio25, 0);
424 gpio_set_value_cansleep(gpio36, 1);
425
426 if (machine_is_apq8064_liquid()) {
427 gpio_set_value_cansleep(mpp3, 0);
428
429 rc = regulator_disable(reg_ext_3p3v);
430 if (rc) {
431 pr_err("disable reg_ext_3p3v failed, rc=%d\n",
432 rc);
433 return -ENODEV;
434 }
435 }
436
437 rc = regulator_disable(reg_lvs7);
438 if (rc) {
439 pr_err("disable reg_lvs7 failed, rc=%d\n", rc);
440 return -ENODEV;
441 }
442 rc = regulator_disable(reg_l2);
443 if (rc) {
444 pr_err("disable reg_l2 failed, rc=%d\n", rc);
445 return -ENODEV;
446 }
447 }
448
449 return 0;
450}
451
452static struct mipi_dsi_platform_data mipi_dsi_pdata = {
453 .dsi_power_save = mipi_dsi_panel_power,
454};
455
456static bool lvds_power_on;
457static int lvds_panel_power(int on)
458{
459 static struct regulator *reg_lvs7, *reg_l2, *reg_ext_3p3v;
460 static int gpio36, gpio26, mpp3;
461 int rc;
462
463 pr_debug("%s: on=%d\n", __func__, on);
464
465 if (!lvds_power_on) {
466 reg_lvs7 = regulator_get(&msm_lvds_device.dev,
467 "lvds_vdda");
468 if (IS_ERR_OR_NULL(reg_lvs7)) {
469 pr_err("could not get 8921_lvs7, rc = %ld\n",
470 PTR_ERR(reg_lvs7));
471 return -ENODEV;
472 }
473
474 reg_l2 = regulator_get(&msm_lvds_device.dev,
475 "lvds_pll_vdda");
476 if (IS_ERR_OR_NULL(reg_l2)) {
477 pr_err("could not get 8921_l2, rc = %ld\n",
478 PTR_ERR(reg_l2));
479 return -ENODEV;
480 }
481
482 rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
483 if (rc) {
484 pr_err("set_voltage l2 failed, rc=%d\n", rc);
485 return -EINVAL;
486 }
487
488 reg_ext_3p3v = regulator_get(&msm_lvds_device.dev,
489 "lvds_vccs_3p3v");
490 if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
491 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
492 PTR_ERR(reg_ext_3p3v));
493 return -ENODEV;
494 }
495
496 gpio26 = PM8921_GPIO_PM_TO_SYS(26);
497 rc = gpio_request(gpio26, "pwm_backlight_ctrl");
498 if (rc) {
499 pr_err("request gpio 26 failed, rc=%d\n", rc);
500 return -ENODEV;
501 }
502
503 gpio36 = PM8921_GPIO_PM_TO_SYS(36); /* lcd1_pwr_en_n */
504 rc = gpio_request(gpio36, "lcd1_pwr_en_n");
505 if (rc) {
506 pr_err("request gpio 36 failed, rc=%d\n", rc);
507 return -ENODEV;
508 }
509
510 mpp3 = PM8921_MPP_PM_TO_SYS(3);
511 rc = gpio_request(mpp3, "backlight_en");
512 if (rc) {
513 pr_err("request mpp3 failed, rc=%d\n", rc);
514 return -ENODEV;
515 }
516
517 lvds_power_on = true;
518 }
519
520 if (on) {
521 rc = regulator_enable(reg_lvs7);
522 if (rc) {
523 pr_err("enable lvs7 failed, rc=%d\n", rc);
524 return -ENODEV;
525 }
526
527 rc = regulator_set_optimum_mode(reg_l2, 100000);
528 if (rc < 0) {
529 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
530 return -EINVAL;
531 }
532 rc = regulator_enable(reg_l2);
533 if (rc) {
534 pr_err("enable l2 failed, rc=%d\n", rc);
535 return -ENODEV;
536 }
537
538 rc = regulator_enable(reg_ext_3p3v);
539 if (rc) {
540 pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
541 return -ENODEV;
542 }
543
544 gpio_set_value_cansleep(gpio36, 0);
545 gpio_set_value_cansleep(mpp3, 1);
546 } else {
547 gpio_set_value_cansleep(mpp3, 0);
548 gpio_set_value_cansleep(gpio36, 1);
549
550 rc = regulator_disable(reg_lvs7);
551 if (rc) {
552 pr_err("disable reg_lvs7 failed, rc=%d\n", rc);
553 return -ENODEV;
554 }
555 rc = regulator_disable(reg_l2);
556 if (rc) {
557 pr_err("disable reg_l2 failed, rc=%d\n", rc);
558 return -ENODEV;
559 }
560 rc = regulator_disable(reg_ext_3p3v);
561 if (rc) {
562 pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
563 return -ENODEV;
564 }
565 }
566
567 return 0;
568}
569
Huaibin Yang02f981c2012-02-27 16:58:41 -0800570static int lvds_pixel_remap(void)
571{
572 if (machine_is_apq8064_cdp() ||
573 machine_is_apq8064_liquid()) {
574 u32 ver = socinfo_get_platform_version();
575 if ((SOCINFO_VERSION_MAJOR(ver) == 1) &&
576 (SOCINFO_VERSION_MINOR(ver) == 0))
577 return 1;
578 }
579 return 0;
580}
581
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800582static struct lcdc_platform_data lvds_pdata = {
583 .lcdc_power_save = lvds_panel_power,
Huaibin Yang02f981c2012-02-27 16:58:41 -0800584 .lvds_pixel_remap = lvds_pixel_remap
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800585};
586
587#define LPM_CHANNEL 2
588static int lvds_chimei_gpio[] = {LPM_CHANNEL};
589
590static struct lvds_panel_platform_data lvds_chimei_pdata = {
591 .gpio = lvds_chimei_gpio,
592};
593
594static struct platform_device lvds_chimei_panel_device = {
595 .name = "lvds_chimei_wxga",
596 .id = 0,
597 .dev = {
598 .platform_data = &lvds_chimei_pdata,
599 }
600};
601
602static int dsi2lvds_gpio[2] = {
603 LPM_CHANNEL,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
604 0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
605};
606static struct msm_panel_common_pdata mipi_dsi2lvds_pdata = {
607 .gpio_num = dsi2lvds_gpio,
608};
609
610static struct platform_device mipi_dsi2lvds_bridge_device = {
611 .name = "mipi_tc358764",
612 .id = 0,
613 .dev.platform_data = &mipi_dsi2lvds_pdata,
614};
615
616static int toshiba_gpio[] = {LPM_CHANNEL};
617static struct mipi_dsi_panel_platform_data toshiba_pdata = {
618 .gpio = toshiba_gpio,
619};
620
621static struct platform_device mipi_dsi_toshiba_panel_device = {
622 .name = "mipi_toshiba",
623 .id = 0,
624 .dev = {
625 .platform_data = &toshiba_pdata,
626 }
627};
628
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800629static struct msm_bus_vectors dtv_bus_init_vectors[] = {
630 {
631 .src = MSM_BUS_MASTER_MDP_PORT0,
632 .dst = MSM_BUS_SLAVE_EBI_CH0,
633 .ab = 0,
634 .ib = 0,
635 },
636};
637
638#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
639static struct msm_bus_vectors dtv_bus_def_vectors[] = {
640 {
641 .src = MSM_BUS_MASTER_MDP_PORT0,
642 .dst = MSM_BUS_SLAVE_EBI_CH0,
643 .ab = 2000000000,
644 .ib = 2000000000,
645 },
646};
647#else
648static struct msm_bus_vectors dtv_bus_def_vectors[] = {
649 {
650 .src = MSM_BUS_MASTER_MDP_PORT0,
651 .dst = MSM_BUS_SLAVE_EBI_CH0,
652 .ab = 566092800 * 2,
653 .ib = 707616000 * 2,
654 },
655};
656#endif
657
658static struct msm_bus_paths dtv_bus_scale_usecases[] = {
659 {
660 ARRAY_SIZE(dtv_bus_init_vectors),
661 dtv_bus_init_vectors,
662 },
663 {
664 ARRAY_SIZE(dtv_bus_def_vectors),
665 dtv_bus_def_vectors,
666 },
667};
668static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
669 dtv_bus_scale_usecases,
670 ARRAY_SIZE(dtv_bus_scale_usecases),
671 .name = "dtv",
672};
673
674static struct lcdc_platform_data dtv_pdata = {
675 .bus_scale_table = &dtv_bus_scale_pdata,
676};
677
678static int hdmi_enable_5v(int on)
679{
680 /* TBD: PM8921 regulator instead of 8901 */
681 static struct regulator *reg_8921_hdmi_mvs; /* HDMI_5V */
682 static int prev_on;
683 int rc;
684
685 if (on == prev_on)
686 return 0;
687
688 if (!reg_8921_hdmi_mvs) {
689 reg_8921_hdmi_mvs = regulator_get(&hdmi_msm_device.dev,
690 "hdmi_mvs");
691 if (IS_ERR(reg_8921_hdmi_mvs)) {
692 pr_err("could not get reg_8921_hdmi_mvs, rc = %ld\n",
693 PTR_ERR(reg_8921_hdmi_mvs));
694 reg_8921_hdmi_mvs = NULL;
695 return -ENODEV;
696 }
697 }
698
699 if (on) {
700 rc = regulator_enable(reg_8921_hdmi_mvs);
701 if (rc) {
702 pr_err("'%s' regulator enable failed, rc=%d\n",
703 "8921_hdmi_mvs", rc);
704 return rc;
705 }
706 pr_debug("%s(on): success\n", __func__);
707 } else {
708 rc = regulator_disable(reg_8921_hdmi_mvs);
709 if (rc)
710 pr_warning("'%s' regulator disable failed, rc=%d\n",
711 "8921_hdmi_mvs", rc);
712 pr_debug("%s(off): success\n", __func__);
713 }
714
715 prev_on = on;
716
717 return 0;
718}
719
720static int hdmi_core_power(int on, int show)
721{
722 static struct regulator *reg_8921_lvs7, *reg_8921_s4, *reg_ext_3p3v;
723 static int prev_on;
724 int rc;
725 int pmic_gpio14 = PM8921_GPIO_PM_TO_SYS(14);
726
727 if (on == prev_on)
728 return 0;
729
730 /* TBD: PM8921 regulator instead of 8901 */
731 if (!reg_ext_3p3v) {
732 reg_ext_3p3v = regulator_get(&hdmi_msm_device.dev,
733 "hdmi_mux_vdd");
734 if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
735 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
736 PTR_ERR(reg_ext_3p3v));
737 reg_ext_3p3v = NULL;
738 return -ENODEV;
739 }
740 }
741
742 if (!reg_8921_lvs7) {
743 reg_8921_lvs7 = regulator_get(&hdmi_msm_device.dev,
744 "hdmi_vdda");
745 if (IS_ERR(reg_8921_lvs7)) {
746 pr_err("could not get reg_8921_lvs7, rc = %ld\n",
747 PTR_ERR(reg_8921_lvs7));
748 reg_8921_lvs7 = NULL;
749 return -ENODEV;
750 }
751 }
752 if (!reg_8921_s4) {
753 reg_8921_s4 = regulator_get(&hdmi_msm_device.dev,
754 "hdmi_lvl_tsl");
755 if (IS_ERR(reg_8921_s4)) {
756 pr_err("could not get reg_8921_s4, rc = %ld\n",
757 PTR_ERR(reg_8921_s4));
758 reg_8921_s4 = NULL;
759 return -ENODEV;
760 }
761 rc = regulator_set_voltage(reg_8921_s4, 1800000, 1800000);
762 if (rc) {
763 pr_err("set_voltage failed for 8921_s4, rc=%d\n", rc);
764 return -EINVAL;
765 }
766 }
767
768 if (on) {
769 /*
770 * Configure 3P3V_BOOST_EN as GPIO, 8mA drive strength,
771 * pull none, out-high
772 */
773 rc = regulator_set_optimum_mode(reg_ext_3p3v, 290000);
774 if (rc < 0) {
775 pr_err("set_optimum_mode ext_3p3v failed, rc=%d\n", rc);
776 return -EINVAL;
777 }
778
779 rc = regulator_enable(reg_ext_3p3v);
780 if (rc) {
781 pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
782 return -ENODEV;
783 }
784 rc = regulator_enable(reg_8921_lvs7);
785 if (rc) {
786 pr_err("'%s' regulator enable failed, rc=%d\n",
787 "hdmi_vdda", rc);
788 return rc;
789 }
790 rc = regulator_enable(reg_8921_s4);
791 if (rc) {
792 pr_err("'%s' regulator enable failed, rc=%d\n",
793 "hdmi_lvl_tsl", rc);
794 return rc;
795 }
796 rc = gpio_request(HDMI_DDC_CLK_GPIO, "HDMI_DDC_CLK");
797 if (rc) {
798 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
799 "HDMI_DDC_CLK", HDMI_DDC_CLK_GPIO, rc);
800 goto error1;
801 }
802 rc = gpio_request(HDMI_DDC_DATA_GPIO, "HDMI_DDC_DATA");
803 if (rc) {
804 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
805 "HDMI_DDC_DATA", HDMI_DDC_DATA_GPIO, rc);
806 goto error2;
807 }
808 rc = gpio_request(HDMI_HPD_GPIO, "HDMI_HPD");
809 if (rc) {
810 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
811 "HDMI_HPD", HDMI_HPD_GPIO, rc);
812 goto error3;
813 }
814 if (machine_is_apq8064_liquid()) {
815 rc = gpio_request(pmic_gpio14, "PMIC_HDMI_MUX_SEL");
816 if (rc) {
817 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
818 "PMIC_HDMI_MUX_SEL", 14, rc);
819 goto error4;
820 }
821 gpio_set_value_cansleep(pmic_gpio14, 0);
822 }
823 pr_debug("%s(on): success\n", __func__);
824 } else {
825 gpio_free(HDMI_DDC_CLK_GPIO);
826 gpio_free(HDMI_DDC_DATA_GPIO);
827 gpio_free(HDMI_HPD_GPIO);
828
829 if (machine_is_apq8064_liquid()) {
830 gpio_set_value_cansleep(pmic_gpio14, 1);
831 gpio_free(pmic_gpio14);
832 }
833
834 rc = regulator_disable(reg_ext_3p3v);
835 if (rc) {
836 pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
837 return -ENODEV;
838 }
839 rc = regulator_disable(reg_8921_lvs7);
840 if (rc) {
841 pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
842 return -ENODEV;
843 }
844 rc = regulator_disable(reg_8921_s4);
845 if (rc) {
846 pr_err("disable reg_8921_s4 failed, rc=%d\n", rc);
847 return -ENODEV;
848 }
849 pr_debug("%s(off): success\n", __func__);
850 }
851
852 prev_on = on;
853
854 return 0;
855
856error4:
857 gpio_free(HDMI_HPD_GPIO);
858error3:
859 gpio_free(HDMI_DDC_DATA_GPIO);
860error2:
861 gpio_free(HDMI_DDC_CLK_GPIO);
862error1:
863 regulator_disable(reg_8921_lvs7);
864 regulator_disable(reg_8921_s4);
865 return rc;
866}
867
868static int hdmi_cec_power(int on)
869{
870 static int prev_on;
871 int rc;
872
873 if (on == prev_on)
874 return 0;
875
876 if (on) {
877 rc = gpio_request(HDMI_CEC_VAR_GPIO, "HDMI_CEC_VAR");
878 if (rc) {
879 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
880 "HDMI_CEC_VAR", HDMI_CEC_VAR_GPIO, rc);
881 goto error;
882 }
883 pr_debug("%s(on): success\n", __func__);
884 } else {
885 gpio_free(HDMI_CEC_VAR_GPIO);
886 pr_debug("%s(off): success\n", __func__);
887 }
888
889 prev_on = on;
890
891 return 0;
892error:
893 return rc;
894}
895
Huaibin Yang4a084e32011-12-15 15:25:52 -0800896void __init apq8064_init_fb(void)
897{
898 platform_device_register(&msm_fb_device);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800899 platform_device_register(&lvds_chimei_panel_device);
900
901 if (machine_is_apq8064_liquid())
902 platform_device_register(&mipi_dsi2lvds_bridge_device);
903 if (machine_is_apq8064_mtp())
904 platform_device_register(&mipi_dsi_toshiba_panel_device);
905
Huaibin Yang4a084e32011-12-15 15:25:52 -0800906 msm_fb_register_device("mdp", &mdp_pdata);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800907 msm_fb_register_device("lvds", &lvds_pdata);
908 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800909 platform_device_register(&hdmi_msm_device);
910 msm_fb_register_device("dtv", &dtv_pdata);
Huaibin Yang4a084e32011-12-15 15:25:52 -0800911}