blob: 24f8f9fc9b7f203a6e5e25796112b8babfd02e8a [file] [log] [blame]
Chitti Babu Theegalaa7458c12013-05-06 21:03:20 +05301/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Huaibin Yang4a084e32011-12-15 15:25:52 -08002 *
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>
Steve Mucklef132c6c2012-06-06 18:30:57 -070016#include <linux/gpio.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080017#include <linux/platform_device.h>
18#include <linux/bootmem.h>
Mitchel Humpherys00a8b8e2012-09-06 11:32:35 -070019#include <linux/msm_ion.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080020#include <asm/mach-types.h>
21#include <mach/msm_memtypes.h>
22#include <mach/board.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080023#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) */
Huaibin Yangc8946d42012-05-04 17:22:02 -070033#define MSM_FB_PRIM_BUF_SIZE roundup(1920 * 1088 * 4 * 3, 0x10000)
Huaibin Yang4a084e32011-12-15 15:25:52 -080034#else
35/* prim = 1366 x 768 x 3(bpp) x 2(pages) */
Huaibin Yangc8946d42012-05-04 17:22:02 -070036#define MSM_FB_PRIM_BUF_SIZE roundup(1920 * 1088 * 4 * 2, 0x10000)
Huaibin Yang4a084e32011-12-15 15:25:52 -080037#endif
38
Huaibin Yangc8946d42012-05-04 17:22:02 -070039#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE, 4096)
Huaibin Yang4a084e32011-12-15 15:25:52 -080040
41#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
42#define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((1376 * 768 * 3 * 2), 4096)
43#else
44#define MSM_FB_OVERLAY0_WRITEBACK_SIZE (0)
45#endif /* CONFIG_FB_MSM_OVERLAY0_WRITEBACK */
46
47#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
48#define MSM_FB_OVERLAY1_WRITEBACK_SIZE roundup((1920 * 1088 * 3 * 2), 4096)
49#else
50#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
51#endif /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
52
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080053
Huaibin Yang4a084e32011-12-15 15:25:52 -080054static struct resource msm_fb_resources[] = {
55 {
56 .flags = IORESOURCE_DMA,
57 }
58};
59
Huaibin Yang4a084e32011-12-15 15:25:52 -080060#define LVDS_CHIMEI_PANEL_NAME "lvds_chimei_wxga"
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -040061#define LVDS_FRC_PANEL_NAME "lvds_frc_fhd"
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080062#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
63#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
64#define HDMI_PANEL_NAME "hdmi_msm"
Aravind Venkateswaran7f934ae2012-08-20 14:43:23 -070065#define MHL_PANEL_NAME "hdmi_msm,mhl_8334"
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080066#define TVOUT_PANEL_NAME "tvout_msm"
Huaibin Yang4a084e32011-12-15 15:25:52 -080067
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -040068#define LVDS_PIXEL_MAP_PATTERN_1 1
69#define LVDS_PIXEL_MAP_PATTERN_2 2
70
Ravishangar Kalyanamfda36c42012-03-26 16:28:19 -070071#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
72static unsigned char hdmi_is_primary = 1;
73#else
74static unsigned char hdmi_is_primary;
75#endif
76
Aravind Venkateswaran7f934ae2012-08-20 14:43:23 -070077static unsigned char mhl_display_enabled;
78
Ravishangar Kalyanamfda36c42012-03-26 16:28:19 -070079unsigned char apq8064_hdmi_as_primary_selected(void)
80{
81 return hdmi_is_primary;
82}
83
Aravind Venkateswaran7f934ae2012-08-20 14:43:23 -070084unsigned char apq8064_mhl_display_enabled(void)
85{
86 return mhl_display_enabled;
87}
88
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -070089static void set_mdp_clocks_for_wuxga(void);
90
Huaibin Yang4a084e32011-12-15 15:25:52 -080091static int msm_fb_detect_panel(const char *name)
92{
Ravishangar Kalyanamed3593c2012-03-08 10:15:04 -080093 u32 version;
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -080094 if (machine_is_apq8064_liquid()) {
Ravishangar Kalyanamed3593c2012-03-08 10:15:04 -080095 version = socinfo_get_platform_version();
96 if ((SOCINFO_VERSION_MAJOR(version) == 1) &&
97 (SOCINFO_VERSION_MINOR(version) == 1)) {
98 if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
99 strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
100 PANEL_NAME_MAX_LEN)))
101 return 0;
102 } else {
103 if (!strncmp(name, LVDS_CHIMEI_PANEL_NAME,
104 strnlen(LVDS_CHIMEI_PANEL_NAME,
105 PANEL_NAME_MAX_LEN)))
106 return 0;
107 }
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800108 } else if (machine_is_apq8064_mtp()) {
109 if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
110 strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
111 PANEL_NAME_MAX_LEN)))
112 return 0;
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -0400113 } else if (machine_is_apq8064_cdp()) {
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800114 if (!strncmp(name, LVDS_CHIMEI_PANEL_NAME,
115 strnlen(LVDS_CHIMEI_PANEL_NAME,
116 PANEL_NAME_MAX_LEN)))
117 return 0;
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -0400118 } else if (machine_is_mpq8064_dtv()) {
119 if (!strncmp(name, LVDS_FRC_PANEL_NAME,
120 strnlen(LVDS_FRC_PANEL_NAME,
121 PANEL_NAME_MAX_LEN))) {
122 set_mdp_clocks_for_wuxga();
123 return 0;
124 }
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800125 }
126
127 if (!strncmp(name, HDMI_PANEL_NAME,
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -0700128 strnlen(HDMI_PANEL_NAME,
129 PANEL_NAME_MAX_LEN))) {
Ravishangar Kalyanamfda36c42012-03-26 16:28:19 -0700130 if (apq8064_hdmi_as_primary_selected())
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -0700131 set_mdp_clocks_for_wuxga();
Huaibin Yang4a084e32011-12-15 15:25:52 -0800132 return 0;
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -0700133 }
134
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800135
Huaibin Yang4a084e32011-12-15 15:25:52 -0800136 return -ENODEV;
137}
138
139static struct msm_fb_platform_data msm_fb_pdata = {
140 .detect_client = msm_fb_detect_panel,
141};
142
143static struct platform_device msm_fb_device = {
144 .name = "msm_fb",
145 .id = 0,
146 .num_resources = ARRAY_SIZE(msm_fb_resources),
147 .resource = msm_fb_resources,
148 .dev.platform_data = &msm_fb_pdata,
149};
150
151void __init apq8064_allocate_fb_region(void)
152{
153 void *addr;
154 unsigned long size;
155
156 size = MSM_FB_SIZE;
157 addr = alloc_bootmem_align(size, 0x1000);
158 msm_fb_resources[0].start = __pa(addr);
159 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
160 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
161 size, addr, __pa(addr));
162}
163
164#define MDP_VSYNC_GPIO 0
165
Ravishangar Kalyanam59a67b12012-02-13 14:29:56 -0800166static struct msm_bus_vectors mdp_init_vectors[] = {
167 {
168 .src = MSM_BUS_MASTER_MDP_PORT0,
169 .dst = MSM_BUS_SLAVE_EBI_CH0,
170 .ab = 0,
171 .ib = 0,
172 },
173};
174
175static struct msm_bus_vectors mdp_ui_vectors[] = {
176 {
177 .src = MSM_BUS_MASTER_MDP_PORT0,
178 .dst = MSM_BUS_SLAVE_EBI_CH0,
179 .ab = 216000000 * 2,
180 .ib = 270000000 * 2,
181 },
182};
183
184static struct msm_bus_vectors mdp_vga_vectors[] = {
185 /* VGA and less video */
186 {
187 .src = MSM_BUS_MASTER_MDP_PORT0,
188 .dst = MSM_BUS_SLAVE_EBI_CH0,
189 .ab = 216000000 * 2,
190 .ib = 270000000 * 2,
191 },
192};
193
194static struct msm_bus_vectors mdp_720p_vectors[] = {
195 /* 720p and less video */
196 {
197 .src = MSM_BUS_MASTER_MDP_PORT0,
198 .dst = MSM_BUS_SLAVE_EBI_CH0,
199 .ab = 230400000 * 2,
200 .ib = 288000000 * 2,
201 },
202};
203
204static struct msm_bus_vectors mdp_1080p_vectors[] = {
205 /* 1080p and less video */
206 {
207 .src = MSM_BUS_MASTER_MDP_PORT0,
208 .dst = MSM_BUS_SLAVE_EBI_CH0,
209 .ab = 334080000 * 2,
210 .ib = 417600000 * 2,
211 },
212};
213
214static struct msm_bus_paths mdp_bus_scale_usecases[] = {
215 {
216 ARRAY_SIZE(mdp_init_vectors),
217 mdp_init_vectors,
218 },
219 {
220 ARRAY_SIZE(mdp_ui_vectors),
221 mdp_ui_vectors,
222 },
223 {
224 ARRAY_SIZE(mdp_ui_vectors),
225 mdp_ui_vectors,
226 },
227 {
228 ARRAY_SIZE(mdp_vga_vectors),
229 mdp_vga_vectors,
230 },
231 {
232 ARRAY_SIZE(mdp_720p_vectors),
233 mdp_720p_vectors,
234 },
235 {
236 ARRAY_SIZE(mdp_1080p_vectors),
237 mdp_1080p_vectors,
238 },
239};
240
241static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
242 mdp_bus_scale_usecases,
243 ARRAY_SIZE(mdp_bus_scale_usecases),
244 .name = "mdp",
245};
246
Huaibin Yang4a084e32011-12-15 15:25:52 -0800247static struct msm_panel_common_pdata mdp_pdata = {
248 .gpio = MDP_VSYNC_GPIO,
Huaibin Yang23441d82012-10-15 15:39:21 -0700249 .mdp_max_clk = 266667000,
Huaibin Yang42f73712013-03-21 17:27:45 -0700250 .mdp_max_bw = 2000000000,
251 .mdp_bw_ab_factor = 115,
Huaibin Yangfa15f932013-04-09 15:33:19 -0700252 .mdp_bw_ib_factor = 150,
Ravishangar Kalyanam59a67b12012-02-13 14:29:56 -0800253 .mdp_bus_scale_table = &mdp_bus_scale_pdata,
Huaibin Yang4a084e32011-12-15 15:25:52 -0800254 .mdp_rev = MDP_REV_44,
255#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
Ravishangar Kalyanama3b168b2012-03-26 11:13:11 -0700256 .mem_hid = BIT(ION_CP_MM_HEAP_ID),
Huaibin Yang4a084e32011-12-15 15:25:52 -0800257#else
258 .mem_hid = MEMTYPE_EBI1,
259#endif
Olav Hauganef95ae32012-05-15 09:50:30 -0700260 .mdp_iommu_split_domain = 1,
Huaibin Yang4a084e32011-12-15 15:25:52 -0800261};
262
263void __init apq8064_mdp_writeback(struct memtype_reserve* reserve_table)
264{
265 mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
266 mdp_pdata.ov1_wb_size = MSM_FB_OVERLAY1_WRITEBACK_SIZE;
267#if defined(CONFIG_ANDROID_PMEM) && !defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
268 reserve_table[mdp_pdata.mem_hid].size +=
269 mdp_pdata.ov0_wb_size;
270 reserve_table[mdp_pdata.mem_hid].size +=
271 mdp_pdata.ov1_wb_size;
Chitti Babu Theegalaa7458c12013-05-06 21:03:20 +0530272
273 pr_info("mem_map: mdp reserved with size 0x%lx in pool\n",
274 mdp_pdata.ov0_wb_size + mdp_pdata.ov1_wb_size);
Huaibin Yang4a084e32011-12-15 15:25:52 -0800275#endif
276}
277
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800278static struct resource hdmi_msm_resources[] = {
279 {
280 .name = "hdmi_msm_qfprom_addr",
281 .start = 0x00700000,
282 .end = 0x007060FF,
283 .flags = IORESOURCE_MEM,
284 },
285 {
286 .name = "hdmi_msm_hdmi_addr",
287 .start = 0x04A00000,
288 .end = 0x04A00FFF,
289 .flags = IORESOURCE_MEM,
290 },
291 {
292 .name = "hdmi_msm_irq",
293 .start = HDMI_IRQ,
294 .end = HDMI_IRQ,
295 .flags = IORESOURCE_IRQ,
296 },
297};
298
299static int hdmi_enable_5v(int on);
300static int hdmi_core_power(int on, int show);
301static int hdmi_cec_power(int on);
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530302static int hdmi_gpio_config(int on);
303static int hdmi_panel_power(int on);
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800304
305static struct msm_hdmi_platform_data hdmi_msm_data = {
306 .irq = HDMI_IRQ,
307 .enable_5v = hdmi_enable_5v,
308 .core_power = hdmi_core_power,
309 .cec_power = hdmi_cec_power,
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530310 .panel_power = hdmi_panel_power,
311 .gpio_config = hdmi_gpio_config,
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800312};
313
314static struct platform_device hdmi_msm_device = {
315 .name = "hdmi_msm",
316 .id = 0,
317 .num_resources = ARRAY_SIZE(hdmi_msm_resources),
318 .resource = hdmi_msm_resources,
319 .dev.platform_data = &hdmi_msm_data,
320};
321
Olav Hauganef95ae32012-05-15 09:50:30 -0700322static char wfd_check_mdp_iommu_split_domain(void)
323{
324 return mdp_pdata.mdp_iommu_split_domain;
325}
326
Mohan Kumar Gubbihalli Lachma Naikcb7d4e72012-03-23 18:17:30 -0700327#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
Olav Hauganef95ae32012-05-15 09:50:30 -0700328static struct msm_wfd_platform_data wfd_pdata = {
329 .wfd_check_mdp_iommu_split = wfd_check_mdp_iommu_split_domain,
330};
331
Mohan Kumar Gubbihalli Lachma Naikcb7d4e72012-03-23 18:17:30 -0700332static struct platform_device wfd_panel_device = {
333 .name = "wfd_panel",
334 .id = 0,
335 .dev.platform_data = NULL,
336};
337
338static struct platform_device wfd_device = {
339 .name = "msm_wfd",
340 .id = -1,
Olav Hauganef95ae32012-05-15 09:50:30 -0700341 .dev.platform_data = &wfd_pdata,
Mohan Kumar Gubbihalli Lachma Naikcb7d4e72012-03-23 18:17:30 -0700342};
343#endif
344
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800345/* HDMI related GPIOs */
346#define HDMI_CEC_VAR_GPIO 69
347#define HDMI_DDC_CLK_GPIO 70
348#define HDMI_DDC_DATA_GPIO 71
349#define HDMI_HPD_GPIO 72
350
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800351static bool dsi_power_on;
352static int mipi_dsi_panel_power(int on)
353{
354 static struct regulator *reg_lvs7, *reg_l2, *reg_l11, *reg_ext_3p3v;
355 static int gpio36, gpio25, gpio26, mpp3;
356 int rc;
357
358 pr_debug("%s: on=%d\n", __func__, on);
359
360 if (!dsi_power_on) {
361 reg_lvs7 = regulator_get(&msm_mipi_dsi1_device.dev,
362 "dsi1_vddio");
363 if (IS_ERR_OR_NULL(reg_lvs7)) {
364 pr_err("could not get 8921_lvs7, rc = %ld\n",
365 PTR_ERR(reg_lvs7));
366 return -ENODEV;
367 }
368
369 reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
370 "dsi1_pll_vdda");
371 if (IS_ERR_OR_NULL(reg_l2)) {
372 pr_err("could not get 8921_l2, rc = %ld\n",
373 PTR_ERR(reg_l2));
374 return -ENODEV;
375 }
376
377 rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
378 if (rc) {
379 pr_err("set_voltage l2 failed, rc=%d\n", rc);
380 return -EINVAL;
381 }
382 reg_l11 = regulator_get(&msm_mipi_dsi1_device.dev,
383 "dsi1_avdd");
384 if (IS_ERR(reg_l11)) {
385 pr_err("could not get 8921_l11, rc = %ld\n",
386 PTR_ERR(reg_l11));
387 return -ENODEV;
388 }
389 rc = regulator_set_voltage(reg_l11, 3000000, 3000000);
390 if (rc) {
391 pr_err("set_voltage l11 failed, rc=%d\n", rc);
392 return -EINVAL;
393 }
394
395 if (machine_is_apq8064_liquid()) {
396 reg_ext_3p3v = regulator_get(&msm_mipi_dsi1_device.dev,
397 "dsi1_vccs_3p3v");
398 if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
399 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
400 PTR_ERR(reg_ext_3p3v));
401 reg_ext_3p3v = NULL;
402 return -ENODEV;
403 }
404 mpp3 = PM8921_MPP_PM_TO_SYS(3);
405 rc = gpio_request(mpp3, "backlight_en");
406 if (rc) {
407 pr_err("request mpp3 failed, rc=%d\n", rc);
408 return -ENODEV;
409 }
410 }
411
412 gpio25 = PM8921_GPIO_PM_TO_SYS(25);
413 rc = gpio_request(gpio25, "disp_rst_n");
414 if (rc) {
415 pr_err("request gpio 25 failed, rc=%d\n", rc);
416 return -ENODEV;
417 }
418
419 gpio26 = PM8921_GPIO_PM_TO_SYS(26);
420 rc = gpio_request(gpio26, "pwm_backlight_ctrl");
421 if (rc) {
422 pr_err("request gpio 26 failed, rc=%d\n", rc);
423 return -ENODEV;
424 }
425
426 gpio36 = PM8921_GPIO_PM_TO_SYS(36); /* lcd1_pwr_en_n */
427 rc = gpio_request(gpio36, "lcd1_pwr_en_n");
428 if (rc) {
429 pr_err("request gpio 36 failed, rc=%d\n", rc);
430 return -ENODEV;
431 }
432
433 dsi_power_on = true;
434 }
435
436 if (on) {
437 rc = regulator_enable(reg_lvs7);
438 if (rc) {
439 pr_err("enable lvs7 failed, rc=%d\n", rc);
440 return -ENODEV;
441 }
442
443 rc = regulator_set_optimum_mode(reg_l11, 110000);
444 if (rc < 0) {
445 pr_err("set_optimum_mode l11 failed, rc=%d\n", rc);
446 return -EINVAL;
447 }
448 rc = regulator_enable(reg_l11);
449 if (rc) {
450 pr_err("enable l11 failed, rc=%d\n", rc);
451 return -ENODEV;
452 }
453
454 rc = regulator_set_optimum_mode(reg_l2, 100000);
455 if (rc < 0) {
456 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
457 return -EINVAL;
458 }
459 rc = regulator_enable(reg_l2);
460 if (rc) {
461 pr_err("enable l2 failed, rc=%d\n", rc);
462 return -ENODEV;
463 }
464
465 if (machine_is_apq8064_liquid()) {
466 rc = regulator_enable(reg_ext_3p3v);
467 if (rc) {
468 pr_err("enable reg_ext_3p3v failed, rc=%d\n",
469 rc);
470 return -ENODEV;
471 }
472 gpio_set_value_cansleep(mpp3, 1);
473 }
474
475 gpio_set_value_cansleep(gpio36, 0);
476 gpio_set_value_cansleep(gpio25, 1);
David Collins1b859572012-08-22 13:59:23 -0700477 if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
478 gpio_set_value_cansleep(gpio26, 1);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800479 } else {
David Collins1b859572012-08-22 13:59:23 -0700480 if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
481 gpio_set_value_cansleep(gpio26, 0);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800482 gpio_set_value_cansleep(gpio25, 0);
483 gpio_set_value_cansleep(gpio36, 1);
484
485 if (machine_is_apq8064_liquid()) {
486 gpio_set_value_cansleep(mpp3, 0);
487
488 rc = regulator_disable(reg_ext_3p3v);
489 if (rc) {
490 pr_err("disable reg_ext_3p3v failed, rc=%d\n",
491 rc);
492 return -ENODEV;
493 }
494 }
495
Nagamalleswararao Ganji15ad5ac2012-06-20 20:50:01 -0700496 rc = regulator_disable(reg_l11);
497 if (rc) {
498 pr_err("disable reg_l1 failed, rc=%d\n", rc);
499 return -ENODEV;
500 }
501
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800502 rc = regulator_disable(reg_lvs7);
503 if (rc) {
504 pr_err("disable reg_lvs7 failed, rc=%d\n", rc);
505 return -ENODEV;
506 }
Nagamalleswararao Ganji15ad5ac2012-06-20 20:50:01 -0700507
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800508 rc = regulator_disable(reg_l2);
509 if (rc) {
510 pr_err("disable reg_l2 failed, rc=%d\n", rc);
511 return -ENODEV;
512 }
513 }
514
515 return 0;
516}
517
518static struct mipi_dsi_platform_data mipi_dsi_pdata = {
519 .dsi_power_save = mipi_dsi_panel_power,
520};
521
522static bool lvds_power_on;
523static int lvds_panel_power(int on)
524{
525 static struct regulator *reg_lvs7, *reg_l2, *reg_ext_3p3v;
526 static int gpio36, gpio26, mpp3;
527 int rc;
528
529 pr_debug("%s: on=%d\n", __func__, on);
530
531 if (!lvds_power_on) {
532 reg_lvs7 = regulator_get(&msm_lvds_device.dev,
533 "lvds_vdda");
534 if (IS_ERR_OR_NULL(reg_lvs7)) {
535 pr_err("could not get 8921_lvs7, rc = %ld\n",
536 PTR_ERR(reg_lvs7));
537 return -ENODEV;
538 }
539
540 reg_l2 = regulator_get(&msm_lvds_device.dev,
541 "lvds_pll_vdda");
542 if (IS_ERR_OR_NULL(reg_l2)) {
543 pr_err("could not get 8921_l2, rc = %ld\n",
544 PTR_ERR(reg_l2));
545 return -ENODEV;
546 }
547
548 rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
549 if (rc) {
550 pr_err("set_voltage l2 failed, rc=%d\n", rc);
551 return -EINVAL;
552 }
553
554 reg_ext_3p3v = regulator_get(&msm_lvds_device.dev,
555 "lvds_vccs_3p3v");
556 if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
557 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
558 PTR_ERR(reg_ext_3p3v));
559 return -ENODEV;
560 }
561
562 gpio26 = PM8921_GPIO_PM_TO_SYS(26);
563 rc = gpio_request(gpio26, "pwm_backlight_ctrl");
564 if (rc) {
565 pr_err("request gpio 26 failed, rc=%d\n", rc);
566 return -ENODEV;
567 }
568
569 gpio36 = PM8921_GPIO_PM_TO_SYS(36); /* lcd1_pwr_en_n */
570 rc = gpio_request(gpio36, "lcd1_pwr_en_n");
571 if (rc) {
572 pr_err("request gpio 36 failed, rc=%d\n", rc);
573 return -ENODEV;
574 }
575
576 mpp3 = PM8921_MPP_PM_TO_SYS(3);
577 rc = gpio_request(mpp3, "backlight_en");
578 if (rc) {
579 pr_err("request mpp3 failed, rc=%d\n", rc);
580 return -ENODEV;
581 }
582
583 lvds_power_on = true;
584 }
585
586 if (on) {
587 rc = regulator_enable(reg_lvs7);
588 if (rc) {
589 pr_err("enable lvs7 failed, rc=%d\n", rc);
590 return -ENODEV;
591 }
592
593 rc = regulator_set_optimum_mode(reg_l2, 100000);
594 if (rc < 0) {
595 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
596 return -EINVAL;
597 }
598 rc = regulator_enable(reg_l2);
599 if (rc) {
600 pr_err("enable l2 failed, rc=%d\n", rc);
601 return -ENODEV;
602 }
603
604 rc = regulator_enable(reg_ext_3p3v);
605 if (rc) {
606 pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
607 return -ENODEV;
608 }
609
610 gpio_set_value_cansleep(gpio36, 0);
611 gpio_set_value_cansleep(mpp3, 1);
David Collins1b859572012-08-22 13:59:23 -0700612 if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
613 gpio_set_value_cansleep(gpio26, 1);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800614 } else {
David Collins1b859572012-08-22 13:59:23 -0700615 if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
616 gpio_set_value_cansleep(gpio26, 0);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800617 gpio_set_value_cansleep(mpp3, 0);
618 gpio_set_value_cansleep(gpio36, 1);
619
620 rc = regulator_disable(reg_lvs7);
621 if (rc) {
622 pr_err("disable reg_lvs7 failed, rc=%d\n", rc);
623 return -ENODEV;
624 }
625 rc = regulator_disable(reg_l2);
626 if (rc) {
627 pr_err("disable reg_l2 failed, rc=%d\n", rc);
628 return -ENODEV;
629 }
630 rc = regulator_disable(reg_ext_3p3v);
631 if (rc) {
632 pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
633 return -ENODEV;
634 }
635 }
636
637 return 0;
638}
639
Huaibin Yang02f981c2012-02-27 16:58:41 -0800640static int lvds_pixel_remap(void)
641{
Lei Zhou34e216d2012-07-25 12:52:13 -0400642 u32 ver = socinfo_get_version();
643
Huaibin Yang02f981c2012-02-27 16:58:41 -0800644 if (machine_is_apq8064_cdp() ||
645 machine_is_apq8064_liquid()) {
Huaibin Yang02f981c2012-02-27 16:58:41 -0800646 if ((SOCINFO_VERSION_MAJOR(ver) == 1) &&
647 (SOCINFO_VERSION_MINOR(ver) == 0))
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -0400648 return LVDS_PIXEL_MAP_PATTERN_1;
649 } else if (machine_is_mpq8064_dtv()) {
Lei Zhou34e216d2012-07-25 12:52:13 -0400650 if ((SOCINFO_VERSION_MAJOR(ver) == 1) &&
651 (SOCINFO_VERSION_MINOR(ver) == 0))
652 return LVDS_PIXEL_MAP_PATTERN_2;
Huaibin Yang02f981c2012-02-27 16:58:41 -0800653 }
654 return 0;
655}
656
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800657static struct lcdc_platform_data lvds_pdata = {
658 .lcdc_power_save = lvds_panel_power,
Huaibin Yang02f981c2012-02-27 16:58:41 -0800659 .lvds_pixel_remap = lvds_pixel_remap
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800660};
661
662#define LPM_CHANNEL 2
663static int lvds_chimei_gpio[] = {LPM_CHANNEL};
664
665static struct lvds_panel_platform_data lvds_chimei_pdata = {
666 .gpio = lvds_chimei_gpio,
667};
668
669static struct platform_device lvds_chimei_panel_device = {
670 .name = "lvds_chimei_wxga",
671 .id = 0,
672 .dev = {
673 .platform_data = &lvds_chimei_pdata,
674 }
675};
676
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -0400677#define FRC_GPIO_UPDATE (SX150X_EXP4_GPIO_BASE + 8)
678#define FRC_GPIO_RESET (SX150X_EXP4_GPIO_BASE + 9)
679#define FRC_GPIO_PWR (SX150X_EXP4_GPIO_BASE + 10)
680
681static int lvds_frc_gpio[] = {FRC_GPIO_UPDATE, FRC_GPIO_RESET, FRC_GPIO_PWR};
682static struct lvds_panel_platform_data lvds_frc_pdata = {
683 .gpio = lvds_frc_gpio,
684};
685
686static struct platform_device lvds_frc_panel_device = {
687 .name = "lvds_frc_fhd",
688 .id = 0,
689 .dev = {
690 .platform_data = &lvds_frc_pdata,
691 }
692};
693
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -0800694static int dsi2lvds_gpio[2] = {
695 LPM_CHANNEL,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
696 0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
697};
698static struct msm_panel_common_pdata mipi_dsi2lvds_pdata = {
699 .gpio_num = dsi2lvds_gpio,
700};
701
702static struct platform_device mipi_dsi2lvds_bridge_device = {
703 .name = "mipi_tc358764",
704 .id = 0,
705 .dev.platform_data = &mipi_dsi2lvds_pdata,
706};
707
708static int toshiba_gpio[] = {LPM_CHANNEL};
709static struct mipi_dsi_panel_platform_data toshiba_pdata = {
710 .gpio = toshiba_gpio,
711};
712
713static struct platform_device mipi_dsi_toshiba_panel_device = {
714 .name = "mipi_toshiba",
715 .id = 0,
716 .dev = {
717 .platform_data = &toshiba_pdata,
718 }
719};
720
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800721static struct msm_bus_vectors dtv_bus_init_vectors[] = {
722 {
723 .src = MSM_BUS_MASTER_MDP_PORT0,
724 .dst = MSM_BUS_SLAVE_EBI_CH0,
725 .ab = 0,
726 .ib = 0,
727 },
728};
729
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800730static struct msm_bus_vectors dtv_bus_def_vectors[] = {
731 {
732 .src = MSM_BUS_MASTER_MDP_PORT0,
733 .dst = MSM_BUS_SLAVE_EBI_CH0,
734 .ab = 566092800 * 2,
735 .ib = 707616000 * 2,
736 },
737};
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800738
739static struct msm_bus_paths dtv_bus_scale_usecases[] = {
740 {
741 ARRAY_SIZE(dtv_bus_init_vectors),
742 dtv_bus_init_vectors,
743 },
744 {
745 ARRAY_SIZE(dtv_bus_def_vectors),
746 dtv_bus_def_vectors,
747 },
748};
749static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
750 dtv_bus_scale_usecases,
751 ARRAY_SIZE(dtv_bus_scale_usecases),
752 .name = "dtv",
753};
754
755static struct lcdc_platform_data dtv_pdata = {
756 .bus_scale_table = &dtv_bus_scale_pdata,
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530757 .lcdc_power_save = hdmi_panel_power,
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800758};
759
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530760static int hdmi_panel_power(int on)
761{
762 int rc;
763
764 pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
765 rc = hdmi_core_power(on, 1);
766 if (rc)
767 rc = hdmi_cec_power(on);
768
769 pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
770 return rc;
771}
772
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800773static int hdmi_enable_5v(int on)
774{
775 /* TBD: PM8921 regulator instead of 8901 */
776 static struct regulator *reg_8921_hdmi_mvs; /* HDMI_5V */
777 static int prev_on;
778 int rc;
779
780 if (on == prev_on)
781 return 0;
782
783 if (!reg_8921_hdmi_mvs) {
784 reg_8921_hdmi_mvs = regulator_get(&hdmi_msm_device.dev,
785 "hdmi_mvs");
786 if (IS_ERR(reg_8921_hdmi_mvs)) {
787 pr_err("could not get reg_8921_hdmi_mvs, rc = %ld\n",
788 PTR_ERR(reg_8921_hdmi_mvs));
789 reg_8921_hdmi_mvs = NULL;
790 return -ENODEV;
791 }
792 }
793
794 if (on) {
795 rc = regulator_enable(reg_8921_hdmi_mvs);
796 if (rc) {
797 pr_err("'%s' regulator enable failed, rc=%d\n",
798 "8921_hdmi_mvs", rc);
799 return rc;
800 }
801 pr_debug("%s(on): success\n", __func__);
802 } else {
803 rc = regulator_disable(reg_8921_hdmi_mvs);
804 if (rc)
805 pr_warning("'%s' regulator disable failed, rc=%d\n",
806 "8921_hdmi_mvs", rc);
807 pr_debug("%s(off): success\n", __func__);
808 }
809
810 prev_on = on;
811
812 return 0;
813}
814
815static int hdmi_core_power(int on, int show)
816{
817 static struct regulator *reg_8921_lvs7, *reg_8921_s4, *reg_ext_3p3v;
818 static int prev_on;
819 int rc;
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800820
821 if (on == prev_on)
822 return 0;
823
824 /* TBD: PM8921 regulator instead of 8901 */
825 if (!reg_ext_3p3v) {
826 reg_ext_3p3v = regulator_get(&hdmi_msm_device.dev,
827 "hdmi_mux_vdd");
828 if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
829 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
830 PTR_ERR(reg_ext_3p3v));
831 reg_ext_3p3v = NULL;
832 return -ENODEV;
833 }
834 }
835
836 if (!reg_8921_lvs7) {
837 reg_8921_lvs7 = regulator_get(&hdmi_msm_device.dev,
838 "hdmi_vdda");
839 if (IS_ERR(reg_8921_lvs7)) {
840 pr_err("could not get reg_8921_lvs7, rc = %ld\n",
841 PTR_ERR(reg_8921_lvs7));
842 reg_8921_lvs7 = NULL;
843 return -ENODEV;
844 }
845 }
846 if (!reg_8921_s4) {
847 reg_8921_s4 = regulator_get(&hdmi_msm_device.dev,
848 "hdmi_lvl_tsl");
849 if (IS_ERR(reg_8921_s4)) {
850 pr_err("could not get reg_8921_s4, rc = %ld\n",
851 PTR_ERR(reg_8921_s4));
852 reg_8921_s4 = NULL;
853 return -ENODEV;
854 }
855 rc = regulator_set_voltage(reg_8921_s4, 1800000, 1800000);
856 if (rc) {
857 pr_err("set_voltage failed for 8921_s4, rc=%d\n", rc);
858 return -EINVAL;
859 }
860 }
861
862 if (on) {
863 /*
864 * Configure 3P3V_BOOST_EN as GPIO, 8mA drive strength,
865 * pull none, out-high
866 */
867 rc = regulator_set_optimum_mode(reg_ext_3p3v, 290000);
868 if (rc < 0) {
869 pr_err("set_optimum_mode ext_3p3v failed, rc=%d\n", rc);
870 return -EINVAL;
871 }
872
873 rc = regulator_enable(reg_ext_3p3v);
874 if (rc) {
875 pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530876 return rc;
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800877 }
878 rc = regulator_enable(reg_8921_lvs7);
879 if (rc) {
880 pr_err("'%s' regulator enable failed, rc=%d\n",
881 "hdmi_vdda", rc);
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530882 goto error1;
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800883 }
884 rc = regulator_enable(reg_8921_s4);
885 if (rc) {
886 pr_err("'%s' regulator enable failed, rc=%d\n",
887 "hdmi_lvl_tsl", rc);
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530888 goto error2;
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800889 }
Ajay Singh Parmar7d11c272012-06-07 12:25:31 +0530890 pr_debug("%s(on): success\n", __func__);
891 } else {
892 rc = regulator_disable(reg_ext_3p3v);
893 if (rc) {
894 pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
895 return -ENODEV;
896 }
897 rc = regulator_disable(reg_8921_lvs7);
898 if (rc) {
899 pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
900 return -ENODEV;
901 }
902 rc = regulator_disable(reg_8921_s4);
903 if (rc) {
904 pr_err("disable reg_8921_s4 failed, rc=%d\n", rc);
905 return -ENODEV;
906 }
907 pr_debug("%s(off): success\n", __func__);
908 }
909
910 prev_on = on;
911
912 return 0;
913
914error2:
915 regulator_disable(reg_8921_lvs7);
916error1:
917 regulator_disable(reg_ext_3p3v);
918 return rc;
919}
920
921static int hdmi_gpio_config(int on)
922{
923 int rc = 0;
924 static int prev_on;
925 int pmic_gpio14 = PM8921_GPIO_PM_TO_SYS(14);
926
927 if (on == prev_on)
928 return 0;
929
930 if (on) {
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800931 rc = gpio_request(HDMI_DDC_CLK_GPIO, "HDMI_DDC_CLK");
932 if (rc) {
933 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
934 "HDMI_DDC_CLK", HDMI_DDC_CLK_GPIO, rc);
935 goto error1;
936 }
937 rc = gpio_request(HDMI_DDC_DATA_GPIO, "HDMI_DDC_DATA");
938 if (rc) {
939 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
940 "HDMI_DDC_DATA", HDMI_DDC_DATA_GPIO, rc);
941 goto error2;
942 }
943 rc = gpio_request(HDMI_HPD_GPIO, "HDMI_HPD");
944 if (rc) {
945 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
946 "HDMI_HPD", HDMI_HPD_GPIO, rc);
947 goto error3;
948 }
949 if (machine_is_apq8064_liquid()) {
950 rc = gpio_request(pmic_gpio14, "PMIC_HDMI_MUX_SEL");
951 if (rc) {
952 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
953 "PMIC_HDMI_MUX_SEL", 14, rc);
954 goto error4;
955 }
956 gpio_set_value_cansleep(pmic_gpio14, 0);
957 }
958 pr_debug("%s(on): success\n", __func__);
959 } else {
960 gpio_free(HDMI_DDC_CLK_GPIO);
961 gpio_free(HDMI_DDC_DATA_GPIO);
962 gpio_free(HDMI_HPD_GPIO);
963
964 if (machine_is_apq8064_liquid()) {
965 gpio_set_value_cansleep(pmic_gpio14, 1);
966 gpio_free(pmic_gpio14);
967 }
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800968 pr_debug("%s(off): success\n", __func__);
969 }
970
971 prev_on = on;
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800972 return 0;
973
974error4:
975 gpio_free(HDMI_HPD_GPIO);
976error3:
977 gpio_free(HDMI_DDC_DATA_GPIO);
978error2:
979 gpio_free(HDMI_DDC_CLK_GPIO);
980error1:
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -0800981 return rc;
982}
983
984static int hdmi_cec_power(int on)
985{
986 static int prev_on;
987 int rc;
988
989 if (on == prev_on)
990 return 0;
991
992 if (on) {
993 rc = gpio_request(HDMI_CEC_VAR_GPIO, "HDMI_CEC_VAR");
994 if (rc) {
995 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
996 "HDMI_CEC_VAR", HDMI_CEC_VAR_GPIO, rc);
997 goto error;
998 }
999 pr_debug("%s(on): success\n", __func__);
1000 } else {
1001 gpio_free(HDMI_CEC_VAR_GPIO);
1002 pr_debug("%s(off): success\n", __func__);
1003 }
1004
1005 prev_on = on;
1006
1007 return 0;
1008error:
1009 return rc;
1010}
1011
Huaibin Yang4a084e32011-12-15 15:25:52 -08001012void __init apq8064_init_fb(void)
1013{
1014 platform_device_register(&msm_fb_device);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -08001015 platform_device_register(&lvds_chimei_panel_device);
1016
Mohan Kumar Gubbihalli Lachma Naikcb7d4e72012-03-23 18:17:30 -07001017#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
1018 platform_device_register(&wfd_panel_device);
1019 platform_device_register(&wfd_device);
1020#endif
1021
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -08001022 if (machine_is_apq8064_liquid())
1023 platform_device_register(&mipi_dsi2lvds_bridge_device);
1024 if (machine_is_apq8064_mtp())
1025 platform_device_register(&mipi_dsi_toshiba_panel_device);
Zhang Chang Ken4a07fcb2012-06-03 11:24:51 -04001026 if (machine_is_mpq8064_dtv())
1027 platform_device_register(&lvds_frc_panel_device);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -08001028
Huaibin Yang4a084e32011-12-15 15:25:52 -08001029 msm_fb_register_device("mdp", &mdp_pdata);
Ravishangar Kalyanamc2fee312012-02-09 19:11:22 -08001030 msm_fb_register_device("lvds", &lvds_pdata);
1031 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
Aravind Venkateswaran0507c8c2012-02-16 17:16:05 -08001032 platform_device_register(&hdmi_msm_device);
1033 msm_fb_register_device("dtv", &dtv_pdata);
Huaibin Yang4a084e32011-12-15 15:25:52 -08001034}
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001035
1036/**
1037 * Set MDP clocks to high frequency to avoid DSI underflow
1038 * when using high resolution 1200x1920 WUXGA panels
1039 */
1040static void set_mdp_clocks_for_wuxga(void)
1041{
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001042 mdp_ui_vectors[0].ab = 2000000000;
1043 mdp_ui_vectors[0].ib = 2000000000;
1044 mdp_vga_vectors[0].ab = 2000000000;
1045 mdp_vga_vectors[0].ib = 2000000000;
1046 mdp_720p_vectors[0].ab = 2000000000;
1047 mdp_720p_vectors[0].ib = 2000000000;
1048 mdp_1080p_vectors[0].ab = 2000000000;
1049 mdp_1080p_vectors[0].ib = 2000000000;
1050
Ravishangar Kalyanamfda36c42012-03-26 16:28:19 -07001051 if (apq8064_hdmi_as_primary_selected()) {
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001052 dtv_bus_def_vectors[0].ab = 2000000000;
1053 dtv_bus_def_vectors[0].ib = 2000000000;
1054 }
1055}
1056
Ajay Singh Parmar6b82d2b2012-07-19 17:23:26 +05301057void __init apq8064_set_display_params(char *prim_panel, char *ext_panel,
1058 unsigned char resolution)
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001059{
Aravind Venkateswarand98bc432012-04-04 16:19:06 -07001060 /*
1061 * For certain MPQ boards, HDMI should be set as primary display
1062 * by default, with the flexibility to specify any other panel
1063 * as a primary panel through boot parameters.
1064 */
1065 if (machine_is_mpq8064_hrd() || machine_is_mpq8064_cdp()) {
1066 pr_debug("HDMI is the primary display by default for MPQ\n");
1067 if (!strnlen(prim_panel, PANEL_NAME_MAX_LEN))
1068 strlcpy(msm_fb_pdata.prim_panel_name, HDMI_PANEL_NAME,
1069 PANEL_NAME_MAX_LEN);
1070 }
1071
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001072 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1073 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1074 PANEL_NAME_MAX_LEN);
1075 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1076 msm_fb_pdata.prim_panel_name);
1077
1078 if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
1079 HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
1080 PANEL_NAME_MAX_LEN))) {
1081 pr_debug("HDMI is the primary display by"
1082 " boot parameter\n");
1083 hdmi_is_primary = 1;
1084 set_mdp_clocks_for_wuxga();
1085 }
1086 }
1087 if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
1088 strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
1089 PANEL_NAME_MAX_LEN);
1090 pr_debug("msm_fb_pdata.ext_panel_name %s\n",
1091 msm_fb_pdata.ext_panel_name);
Aravind Venkateswaran7f934ae2012-08-20 14:43:23 -07001092
1093 if (!strncmp((char *)msm_fb_pdata.ext_panel_name,
1094 MHL_PANEL_NAME, strnlen(MHL_PANEL_NAME,
1095 PANEL_NAME_MAX_LEN))) {
1096 pr_debug("MHL is external display by boot parameter\n");
1097 mhl_display_enabled = 1;
1098 }
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001099 }
Ajay Singh Parmar6b82d2b2012-07-19 17:23:26 +05301100
1101 msm_fb_pdata.ext_resolution = resolution;
Aravind Venkateswaran7f934ae2012-08-20 14:43:23 -07001102 hdmi_msm_data.is_mhl_enabled = mhl_display_enabled;
Aravind Venkateswaran8ac7f412012-03-16 17:57:30 -07001103}