blob: 61bf9fca910ca9a54e048402563feff79a8cb73b [file] [log] [blame]
Nagamalleswararao Ganji70fac1e2011-12-29 19:06:37 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -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>
16#include <linux/platform_device.h>
17#include <linux/bootmem.h>
Huaibin Yang4a084e32011-12-15 15:25:52 -080018#include <linux/ion.h>
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080019#include <asm/mach-types.h>
20#include <mach/msm_bus_board.h>
Huaibin Yanga5419422011-12-08 23:52:10 -080021#include <mach/msm_memtypes.h>
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080022#include <mach/board.h>
23#include <mach/gpio.h>
24#include <mach/gpiomux.h>
Nagamalleswararao Ganji937a1192011-12-07 19:00:52 -080025#include <mach/ion.h>
Amir Samuelov6f1e5002012-02-01 17:42:43 +020026#include <mach/socinfo.h>
Nagamalleswararao Ganji937a1192011-12-07 19:00:52 -080027
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080028#include "devices.h"
Stepan Moskovchenko5a83dba2011-12-05 17:30:17 -080029#include "board-8960.h"
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080030
31#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053032#define MSM_FB_PRIM_BUF_SIZE \
Eugene Yasman7052e132012-03-11 16:16:06 +020033 (roundup((roundup(1920, 32) * roundup(1200, 32) * 4), 4096) * 3)
34 /* 4 bpp x 3 pages */
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080035#else
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053036#define MSM_FB_PRIM_BUF_SIZE \
Eugene Yasman7052e132012-03-11 16:16:06 +020037 (roundup((roundup(1920, 32) * roundup(1200, 32) * 4), 4096) * 2)
38 /* 4 bpp x 2 pages */
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080039#endif
40
41#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053042#define MSM_FB_EXT_BUF_SIZE \
Eugene Yasman7052e132012-03-11 16:16:06 +020043 (roundup((roundup(1920, 32) * roundup(1080, 32) * 2), 4096) * 1)
44 /* 2 bpp x 1 page */
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080045#elif defined(CONFIG_FB_MSM_TVOUT)
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053046#define MSM_FB_EXT_BUF_SIZE \
Eugene Yasman7052e132012-03-11 16:16:06 +020047 (roundup((roundup(720, 32) * roundup(576, 32) * 2), 4096) * 2)
48 /* 2 bpp x 2 pages */
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080049#else
50#define MSM_FB_EXT_BUF_SIZE 0
51#endif
52
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080053/* Note: must be multiple of 4096 */
Huaibin Yang27634b82011-12-09 00:16:25 -080054#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096)
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080055
Huaibin Yanga5419422011-12-08 23:52:10 -080056#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
Eugene Yasman7052e132012-03-11 16:16:06 +020057#define MSM_FB_OVERLAY0_WRITEBACK_SIZE \
58 roundup((roundup(1920, 32) * roundup(1200, 32) * 3 * 2), 4096)
Huaibin Yanga5419422011-12-08 23:52:10 -080059#else
60#define MSM_FB_OVERLAY0_WRITEBACK_SIZE (0)
61#endif /* CONFIG_FB_MSM_OVERLAY0_WRITEBACK */
62
63#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
Eugene Yasman7052e132012-03-11 16:16:06 +020064#define MSM_FB_OVERLAY1_WRITEBACK_SIZE \
65 roundup((roundup(1920, 32) * roundup(1080, 32) * 3 * 2), 4096)
Huaibin Yanga5419422011-12-08 23:52:10 -080066#else
67#define MSM_FB_OVERLAY1_WRITEBACK_SIZE (0)
68#endif /* CONFIG_FB_MSM_OVERLAY1_WRITEBACK */
69
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080070#define MDP_VSYNC_GPIO 0
71
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080072#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
73#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
74#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
Ravishangar Kalyanamda07f662012-02-16 13:29:43 -080075#define MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME "mipi_video_toshiba_wuxga"
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080076#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
Amir Samuelov6f1e5002012-02-01 17:42:43 +020077#define MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME "mipi_video_chimei_wuxga"
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080078#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME "mipi_video_simulator_vga"
79#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
Ravishangar Kalyaname2d015c2012-01-26 14:47:14 -080080#define MIPI_VIDEO_ORISE_720P_PANEL_NAME "mipi_video_orise_720p"
81#define MIPI_CMD_ORISE_720P_PANEL_NAME "mipi_cmd_orise_720p"
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080082#define HDMI_PANEL_NAME "hdmi_msm"
83#define TVOUT_PANEL_NAME "tvout_msm"
84
Ravishangar Kalyanam8c79ead2011-12-02 21:05:01 -080085#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
86unsigned char hdmi_is_primary = 1;
87#else
88unsigned char hdmi_is_primary;
89#endif
90
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080091static struct resource msm_fb_resources[] = {
92 {
93 .flags = IORESOURCE_DMA,
94 }
95};
96
Ravishangar Kalyanam8e784252012-02-10 16:27:51 -080097static void set_mdp_clocks_for_wuxga(void);
Amir Samuelovf0d1f542012-02-06 12:50:42 +020098
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -080099static int msm_fb_detect_panel(const char *name)
100{
101 if (machine_is_msm8960_liquid()) {
Amir Samuelov6f1e5002012-02-01 17:42:43 +0200102 u32 ver = socinfo_get_platform_version();
103 if (SOCINFO_VERSION_MAJOR(ver) == 3) {
104 if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
105 strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
Amir Samuelovf0d1f542012-02-06 12:50:42 +0200106 PANEL_NAME_MAX_LEN))) {
Ravishangar Kalyanam8e784252012-02-10 16:27:51 -0800107 set_mdp_clocks_for_wuxga();
Amir Samuelov6f1e5002012-02-01 17:42:43 +0200108 return 0;
Amir Samuelovf0d1f542012-02-06 12:50:42 +0200109 }
Amir Samuelov6f1e5002012-02-01 17:42:43 +0200110 } else {
111 if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
112 strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
113 PANEL_NAME_MAX_LEN)))
114 return 0;
115 }
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800116 } else {
117 if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
118 strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
119 PANEL_NAME_MAX_LEN)))
120 return 0;
121
Ravishangar Kalyanama4286d72012-02-15 16:09:58 -0800122#if !defined(CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT) && \
123 !defined(CONFIG_FB_MSM_MIPI_PANEL_DETECT)
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800124 if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
125 strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
126 PANEL_NAME_MAX_LEN)))
127 return 0;
128
129 if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
130 strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
131 PANEL_NAME_MAX_LEN)))
132 return 0;
133
134 if (!strncmp(name, MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
135 strnlen(MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
136 PANEL_NAME_MAX_LEN)))
137 return 0;
138
139 if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
140 strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
141 PANEL_NAME_MAX_LEN)))
142 return 0;
Ravishangar Kalyanam8e784252012-02-10 16:27:51 -0800143
Ravishangar Kalyanamda07f662012-02-16 13:29:43 -0800144 if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME,
145 strnlen(MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME,
Ravishangar Kalyanam8e784252012-02-10 16:27:51 -0800146 PANEL_NAME_MAX_LEN))) {
147 set_mdp_clocks_for_wuxga();
148 return 0;
149 }
Ravishangar Kalyaname2d015c2012-01-26 14:47:14 -0800150
151 if (!strncmp(name, MIPI_VIDEO_ORISE_720P_PANEL_NAME,
152 strnlen(MIPI_VIDEO_ORISE_720P_PANEL_NAME,
153 PANEL_NAME_MAX_LEN)))
154 return 0;
155
156 if (!strncmp(name, MIPI_CMD_ORISE_720P_PANEL_NAME,
157 strnlen(MIPI_CMD_ORISE_720P_PANEL_NAME,
158 PANEL_NAME_MAX_LEN)))
159 return 0;
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800160#endif
161 }
162
163 if (!strncmp(name, HDMI_PANEL_NAME,
164 strnlen(HDMI_PANEL_NAME,
165 PANEL_NAME_MAX_LEN)))
166 return 0;
167
168 if (!strncmp(name, TVOUT_PANEL_NAME,
169 strnlen(TVOUT_PANEL_NAME,
170 PANEL_NAME_MAX_LEN)))
171 return 0;
172
173 pr_warning("%s: not supported '%s'", __func__, name);
174 return -ENODEV;
175}
176
177static struct msm_fb_platform_data msm_fb_pdata = {
178 .detect_client = msm_fb_detect_panel,
179};
180
181static struct platform_device msm_fb_device = {
182 .name = "msm_fb",
183 .id = 0,
184 .num_resources = ARRAY_SIZE(msm_fb_resources),
185 .resource = msm_fb_resources,
186 .dev.platform_data = &msm_fb_pdata,
187};
188
Chandan Uddaraju2679f092012-03-09 15:48:04 -0800189static void mipi_dsi_panel_pwm_cfg(void)
190{
191 int rc;
192 static int mipi_dsi_panel_gpio_configured;
193 static struct pm_gpio pwm_enable = {
194 .direction = PM_GPIO_DIR_OUT,
195 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
196 .output_value = 1,
197 .pull = PM_GPIO_PULL_NO,
198 .vin_sel = PM_GPIO_VIN_VPH,
199 .out_strength = PM_GPIO_STRENGTH_HIGH,
200 .function = PM_GPIO_FUNC_NORMAL,
201 .inv_int_pol = 0,
202 .disable_pin = 0,
203 };
204 static struct pm_gpio pwm_mode = {
205 .direction = PM_GPIO_DIR_OUT,
206 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
207 .output_value = 0,
208 .pull = PM_GPIO_PULL_NO,
209 .vin_sel = PM_GPIO_VIN_S4,
210 .out_strength = PM_GPIO_STRENGTH_HIGH,
211 .function = PM_GPIO_FUNC_2,
212 .inv_int_pol = 0,
213 .disable_pin = 0,
214 };
215
216 if (mipi_dsi_panel_gpio_configured == 0) {
217 /* pm8xxx: gpio-21, Backlight Enable */
218 rc = pm8xxx_gpio_config(PM8921_GPIO_PM_TO_SYS(21),
219 &pwm_enable);
220 if (rc != 0)
221 pr_err("%s: pwm_enabled failed\n", __func__);
222
223 /* pm8xxx: gpio-24, Bl: Off, PWM mode */
224 rc = pm8xxx_gpio_config(PM8921_GPIO_PM_TO_SYS(24),
225 &pwm_mode);
226 if (rc != 0)
227 pr_err("%s: pwm_mode failed\n", __func__);
228
229 mipi_dsi_panel_gpio_configured++;
230 }
231}
232
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800233static bool dsi_power_on;
234
235/**
236 * LiQUID panel on/off
237 *
238 * @param on
239 *
240 * @return int
241 */
242static int mipi_dsi_liquid_panel_power(int on)
243{
244 static struct regulator *reg_l2, *reg_ext_3p3v;
245 static int gpio21, gpio24, gpio43;
246 int rc;
247
Chandan Uddaraju2679f092012-03-09 15:48:04 -0800248 mipi_dsi_panel_pwm_cfg();
Jeff Ohlstein2cbe5ba2011-12-16 13:32:56 -0800249 pr_debug("%s: on=%d\n", __func__, on);
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800250
251 gpio21 = PM8921_GPIO_PM_TO_SYS(21); /* disp power enable_n */
252 gpio43 = PM8921_GPIO_PM_TO_SYS(43); /* Displays Enable (rst_n)*/
253 gpio24 = PM8921_GPIO_PM_TO_SYS(24); /* Backlight PWM */
254
255 if (!dsi_power_on) {
256
257 reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
258 "dsi_vdda");
259 if (IS_ERR(reg_l2)) {
260 pr_err("could not get 8921_l2, rc = %ld\n",
261 PTR_ERR(reg_l2));
262 return -ENODEV;
263 }
264
265 rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
266 if (rc) {
267 pr_err("set_voltage l2 failed, rc=%d\n", rc);
268 return -EINVAL;
269 }
270
271 reg_ext_3p3v = regulator_get(&msm_mipi_dsi1_device.dev,
272 "vdd_lvds_3p3v");
273 if (IS_ERR(reg_ext_3p3v)) {
274 pr_err("could not get reg_ext_3p3v, rc = %ld\n",
275 PTR_ERR(reg_ext_3p3v));
276 return -ENODEV;
277 }
278
279 rc = gpio_request(gpio21, "disp_pwr_en_n");
280 if (rc) {
281 pr_err("request gpio 21 failed, rc=%d\n", rc);
282 return -ENODEV;
283 }
284
285 rc = gpio_request(gpio43, "disp_rst_n");
286 if (rc) {
287 pr_err("request gpio 43 failed, rc=%d\n", rc);
288 return -ENODEV;
289 }
290
291 rc = gpio_request(gpio24, "disp_backlight_pwm");
292 if (rc) {
293 pr_err("request gpio 24 failed, rc=%d\n", rc);
294 return -ENODEV;
295 }
296
297 dsi_power_on = true;
298 }
299
300 if (on) {
301 rc = regulator_set_optimum_mode(reg_l2, 100000);
302 if (rc < 0) {
303 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
304 return -EINVAL;
305 }
306 rc = regulator_enable(reg_l2);
307 if (rc) {
308 pr_err("enable l2 failed, rc=%d\n", rc);
309 return -ENODEV;
310 }
311
312 rc = regulator_enable(reg_ext_3p3v);
313 if (rc) {
314 pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
315 return -ENODEV;
316 }
317
318 /* set reset pin before power enable */
319 gpio_set_value_cansleep(gpio43, 0); /* disp disable (resx=0) */
320
321 gpio_set_value_cansleep(gpio21, 0); /* disp power enable_n */
322 msleep(20);
323 gpio_set_value_cansleep(gpio43, 1); /* disp enable */
324 msleep(20);
325 gpio_set_value_cansleep(gpio43, 0); /* disp enable */
326 msleep(20);
327 gpio_set_value_cansleep(gpio43, 1); /* disp enable */
328 msleep(20);
329 } else {
330 gpio_set_value_cansleep(gpio43, 0);
331 gpio_set_value_cansleep(gpio21, 1);
332
333 rc = regulator_disable(reg_l2);
334 if (rc) {
335 pr_err("disable reg_l2 failed, rc=%d\n", rc);
336 return -ENODEV;
337 }
338 rc = regulator_disable(reg_ext_3p3v);
339 if (rc) {
340 pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
341 return -ENODEV;
342 }
343 rc = regulator_set_optimum_mode(reg_l2, 100);
344 if (rc < 0) {
345 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
346 return -EINVAL;
347 }
348 }
349
350 return 0;
351}
352
353static int mipi_dsi_cdp_panel_power(int on)
354{
355 static struct regulator *reg_l8, *reg_l23, *reg_l2;
356 static int gpio43;
357 int rc;
358
Jeff Ohlstein2cbe5ba2011-12-16 13:32:56 -0800359 pr_debug("%s: state : %d\n", __func__, on);
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800360
361 if (!dsi_power_on) {
362
363 reg_l8 = regulator_get(&msm_mipi_dsi1_device.dev,
364 "dsi_vdc");
365 if (IS_ERR(reg_l8)) {
366 pr_err("could not get 8921_l8, rc = %ld\n",
367 PTR_ERR(reg_l8));
368 return -ENODEV;
369 }
370 reg_l23 = regulator_get(&msm_mipi_dsi1_device.dev,
371 "dsi_vddio");
372 if (IS_ERR(reg_l23)) {
373 pr_err("could not get 8921_l23, rc = %ld\n",
374 PTR_ERR(reg_l23));
375 return -ENODEV;
376 }
377 reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
378 "dsi_vdda");
379 if (IS_ERR(reg_l2)) {
380 pr_err("could not get 8921_l2, rc = %ld\n",
381 PTR_ERR(reg_l2));
382 return -ENODEV;
383 }
384 rc = regulator_set_voltage(reg_l8, 2800000, 3000000);
385 if (rc) {
386 pr_err("set_voltage l8 failed, rc=%d\n", rc);
387 return -EINVAL;
388 }
389 rc = regulator_set_voltage(reg_l23, 1800000, 1800000);
390 if (rc) {
391 pr_err("set_voltage l23 failed, rc=%d\n", rc);
392 return -EINVAL;
393 }
394 rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
395 if (rc) {
396 pr_err("set_voltage l2 failed, rc=%d\n", rc);
397 return -EINVAL;
398 }
399 gpio43 = PM8921_GPIO_PM_TO_SYS(43);
400 rc = gpio_request(gpio43, "disp_rst_n");
401 if (rc) {
402 pr_err("request gpio 43 failed, rc=%d\n", rc);
403 return -ENODEV;
404 }
405 dsi_power_on = true;
406 }
407 if (on) {
408 rc = regulator_set_optimum_mode(reg_l8, 100000);
409 if (rc < 0) {
410 pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
411 return -EINVAL;
412 }
413 rc = regulator_set_optimum_mode(reg_l23, 100000);
414 if (rc < 0) {
415 pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
416 return -EINVAL;
417 }
418 rc = regulator_set_optimum_mode(reg_l2, 100000);
419 if (rc < 0) {
420 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
421 return -EINVAL;
422 }
423 rc = regulator_enable(reg_l8);
424 if (rc) {
425 pr_err("enable l8 failed, rc=%d\n", rc);
426 return -ENODEV;
427 }
428 rc = regulator_enable(reg_l23);
429 if (rc) {
430 pr_err("enable l8 failed, rc=%d\n", rc);
431 return -ENODEV;
432 }
433 rc = regulator_enable(reg_l2);
434 if (rc) {
435 pr_err("enable l2 failed, rc=%d\n", rc);
436 return -ENODEV;
437 }
438 gpio_set_value_cansleep(gpio43, 1);
439 } else {
440 rc = regulator_disable(reg_l2);
441 if (rc) {
442 pr_err("disable reg_l2 failed, rc=%d\n", rc);
443 return -ENODEV;
444 }
445 rc = regulator_disable(reg_l8);
446 if (rc) {
447 pr_err("disable reg_l8 failed, rc=%d\n", rc);
448 return -ENODEV;
449 }
450 rc = regulator_disable(reg_l23);
451 if (rc) {
452 pr_err("disable reg_l23 failed, rc=%d\n", rc);
453 return -ENODEV;
454 }
455 rc = regulator_set_optimum_mode(reg_l8, 100);
456 if (rc < 0) {
457 pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
458 return -EINVAL;
459 }
460 rc = regulator_set_optimum_mode(reg_l23, 100);
461 if (rc < 0) {
462 pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
463 return -EINVAL;
464 }
465 rc = regulator_set_optimum_mode(reg_l2, 100);
466 if (rc < 0) {
467 pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
468 return -EINVAL;
469 }
470 gpio_set_value_cansleep(gpio43, 0);
471 }
472 return 0;
473}
474
475static int mipi_dsi_panel_power(int on)
476{
477 int ret;
478
Jeff Ohlstein2cbe5ba2011-12-16 13:32:56 -0800479 pr_debug("%s: on=%d\n", __func__, on);
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800480
481 if (machine_is_msm8960_liquid())
482 ret = mipi_dsi_liquid_panel_power(on);
483 else
484 ret = mipi_dsi_cdp_panel_power(on);
485
486 return ret;
487}
488
489static struct mipi_dsi_platform_data mipi_dsi_pdata = {
490 .vsync_gpio = MDP_VSYNC_GPIO,
491 .dsi_power_save = mipi_dsi_panel_power,
492};
493
494#ifdef CONFIG_MSM_BUS_SCALING
495
Nagamalleswararao Ganji5fabbd62011-11-06 23:10:43 -0800496static struct msm_bus_vectors rotator_init_vectors[] = {
497 {
498 .src = MSM_BUS_MASTER_ROTATOR,
499 .dst = MSM_BUS_SLAVE_EBI_CH0,
500 .ab = 0,
501 .ib = 0,
502 },
503};
504
505static struct msm_bus_vectors rotator_ui_vectors[] = {
506 {
507 .src = MSM_BUS_MASTER_ROTATOR,
508 .dst = MSM_BUS_SLAVE_EBI_CH0,
509 .ab = (1024 * 600 * 4 * 2 * 60),
510 .ib = (1024 * 600 * 4 * 2 * 60 * 1.5),
511 },
512};
513
514static struct msm_bus_vectors rotator_vga_vectors[] = {
515 {
516 .src = MSM_BUS_MASTER_ROTATOR,
517 .dst = MSM_BUS_SLAVE_EBI_CH0,
518 .ab = (640 * 480 * 2 * 2 * 30),
519 .ib = (640 * 480 * 2 * 2 * 30 * 1.5),
520 },
521};
522static struct msm_bus_vectors rotator_720p_vectors[] = {
523 {
524 .src = MSM_BUS_MASTER_ROTATOR,
525 .dst = MSM_BUS_SLAVE_EBI_CH0,
526 .ab = (1280 * 736 * 2 * 2 * 30),
527 .ib = (1280 * 736 * 2 * 2 * 30 * 1.5),
528 },
529};
530
531static struct msm_bus_vectors rotator_1080p_vectors[] = {
532 {
533 .src = MSM_BUS_MASTER_ROTATOR,
534 .dst = MSM_BUS_SLAVE_EBI_CH0,
535 .ab = (1920 * 1088 * 2 * 2 * 30),
536 .ib = (1920 * 1088 * 2 * 2 * 30 * 1.5),
537 },
538};
539
540static struct msm_bus_paths rotator_bus_scale_usecases[] = {
541 {
542 ARRAY_SIZE(rotator_init_vectors),
543 rotator_init_vectors,
544 },
545 {
546 ARRAY_SIZE(rotator_ui_vectors),
547 rotator_ui_vectors,
548 },
549 {
550 ARRAY_SIZE(rotator_vga_vectors),
551 rotator_vga_vectors,
552 },
553 {
554 ARRAY_SIZE(rotator_720p_vectors),
555 rotator_720p_vectors,
556 },
557 {
558 ARRAY_SIZE(rotator_1080p_vectors),
559 rotator_1080p_vectors,
560 },
561};
562
563struct msm_bus_scale_pdata rotator_bus_scale_pdata = {
564 rotator_bus_scale_usecases,
565 ARRAY_SIZE(rotator_bus_scale_usecases),
566 .name = "rotator",
567};
568
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800569static struct msm_bus_vectors mdp_init_vectors[] = {
570 {
571 .src = MSM_BUS_MASTER_MDP_PORT0,
572 .dst = MSM_BUS_SLAVE_EBI_CH0,
573 .ab = 0,
574 .ib = 0,
575 },
576};
577
578#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
579static struct msm_bus_vectors hdmi_as_primary_vectors[] = {
580 /* If HDMI is used as primary */
581 {
582 .src = MSM_BUS_MASTER_MDP_PORT0,
583 .dst = MSM_BUS_SLAVE_EBI_CH0,
584 .ab = 2000000000,
585 .ib = 2000000000,
586 },
587};
588static struct msm_bus_paths mdp_bus_scale_usecases[] = {
589 {
590 ARRAY_SIZE(mdp_init_vectors),
591 mdp_init_vectors,
592 },
593 {
594 ARRAY_SIZE(hdmi_as_primary_vectors),
595 hdmi_as_primary_vectors,
596 },
597 {
598 ARRAY_SIZE(hdmi_as_primary_vectors),
599 hdmi_as_primary_vectors,
600 },
601 {
602 ARRAY_SIZE(hdmi_as_primary_vectors),
603 hdmi_as_primary_vectors,
604 },
605 {
606 ARRAY_SIZE(hdmi_as_primary_vectors),
607 hdmi_as_primary_vectors,
608 },
609 {
610 ARRAY_SIZE(hdmi_as_primary_vectors),
611 hdmi_as_primary_vectors,
612 },
613};
614#else
615static struct msm_bus_vectors mdp_ui_vectors[] = {
616 {
617 .src = MSM_BUS_MASTER_MDP_PORT0,
618 .dst = MSM_BUS_SLAVE_EBI_CH0,
619 .ab = 216000000 * 2,
620 .ib = 270000000 * 2,
621 },
622};
623
624static struct msm_bus_vectors mdp_vga_vectors[] = {
625 /* VGA and less video */
626 {
627 .src = MSM_BUS_MASTER_MDP_PORT0,
628 .dst = MSM_BUS_SLAVE_EBI_CH0,
629 .ab = 216000000 * 2,
630 .ib = 270000000 * 2,
631 },
632};
633
634static struct msm_bus_vectors mdp_720p_vectors[] = {
635 /* 720p and less video */
636 {
637 .src = MSM_BUS_MASTER_MDP_PORT0,
638 .dst = MSM_BUS_SLAVE_EBI_CH0,
639 .ab = 230400000 * 2,
640 .ib = 288000000 * 2,
641 },
642};
643
644static struct msm_bus_vectors mdp_1080p_vectors[] = {
645 /* 1080p and less video */
646 {
647 .src = MSM_BUS_MASTER_MDP_PORT0,
648 .dst = MSM_BUS_SLAVE_EBI_CH0,
649 .ab = 334080000 * 2,
650 .ib = 417600000 * 2,
651 },
652};
653
654static struct msm_bus_paths mdp_bus_scale_usecases[] = {
655 {
656 ARRAY_SIZE(mdp_init_vectors),
657 mdp_init_vectors,
658 },
659 {
660 ARRAY_SIZE(mdp_ui_vectors),
661 mdp_ui_vectors,
662 },
663 {
664 ARRAY_SIZE(mdp_ui_vectors),
665 mdp_ui_vectors,
666 },
667 {
668 ARRAY_SIZE(mdp_vga_vectors),
669 mdp_vga_vectors,
670 },
671 {
672 ARRAY_SIZE(mdp_720p_vectors),
673 mdp_720p_vectors,
674 },
675 {
676 ARRAY_SIZE(mdp_1080p_vectors),
677 mdp_1080p_vectors,
678 },
679};
680#endif
681
682static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
683 mdp_bus_scale_usecases,
684 ARRAY_SIZE(mdp_bus_scale_usecases),
685 .name = "mdp",
686};
687
688#endif
689
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800690static int mdp_core_clk_rate_table[] = {
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800691 85330000,
Huaibin Yang1f180ee2012-01-30 16:23:06 -0800692 128000000,
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800693 160000000,
694 200000000,
695};
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800696
697static struct msm_panel_common_pdata mdp_pdata = {
698 .gpio = MDP_VSYNC_GPIO,
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800699 .mdp_core_clk_rate = 85330000,
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800700 .mdp_core_clk_table = mdp_core_clk_rate_table,
701 .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
702#ifdef CONFIG_MSM_BUS_SCALING
703 .mdp_bus_scale_table = &mdp_bus_scale_pdata,
704#endif
705 .mdp_rev = MDP_REV_42,
Nagamalleswararao Ganji937a1192011-12-07 19:00:52 -0800706#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
707 .mem_hid = ION_CP_MM_HEAP_ID,
708#else
709 .mem_hid = MEMTYPE_EBI1,
710#endif
Chandan Uddaraju2679f092012-03-09 15:48:04 -0800711 .cont_splash_enabled = 0x01,
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800712};
713
Amir Samuelovf0d1f542012-02-06 12:50:42 +0200714/**
715 * Set MDP clocks to high frequency to avoid DSI underflow
Ravishangar Kalyanam8e784252012-02-10 16:27:51 -0800716 * when using high resolution 1200x1920 WUXGA panels
Amir Samuelovf0d1f542012-02-06 12:50:42 +0200717 */
Ravishangar Kalyanam8e784252012-02-10 16:27:51 -0800718static void set_mdp_clocks_for_wuxga(void)
Amir Samuelovf0d1f542012-02-06 12:50:42 +0200719{
720 int i;
721
722 mdp_ui_vectors[0].ab = 2000000000;
723 mdp_ui_vectors[0].ib = 2000000000;
Ravishangar Kalyanam30170872012-02-25 17:47:18 -0800724 mdp_vga_vectors[0].ab = 2000000000;
725 mdp_vga_vectors[0].ib = 2000000000;
726 mdp_720p_vectors[0].ab = 2000000000;
727 mdp_720p_vectors[0].ib = 2000000000;
728 mdp_1080p_vectors[0].ab = 2000000000;
729 mdp_1080p_vectors[0].ib = 2000000000;
Amir Samuelovf0d1f542012-02-06 12:50:42 +0200730
731 mdp_pdata.mdp_core_clk_rate = 200000000;
732
733 for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
734 mdp_core_clk_rate_table[i] = 200000000;
735
736}
737
Huaibin Yanga5419422011-12-08 23:52:10 -0800738void __init msm8960_mdp_writeback(struct memtype_reserve* reserve_table)
739{
Nagamalleswararao Ganji937a1192011-12-07 19:00:52 -0800740 mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
741 mdp_pdata.ov1_wb_size = MSM_FB_OVERLAY1_WRITEBACK_SIZE;
742#if defined(CONFIG_ANDROID_PMEM) && !defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
743 reserve_table[mdp_pdata.mem_hid].size +=
744 mdp_pdata.ov0_wb_size;
745 reserve_table[mdp_pdata.mem_hid].size +=
746 mdp_pdata.ov1_wb_size;
747#endif
Huaibin Yanga5419422011-12-08 23:52:10 -0800748}
749
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800750static struct platform_device mipi_dsi_renesas_panel_device = {
751 .name = "mipi_renesas",
752 .id = 0,
753};
754
755static struct platform_device mipi_dsi_simulator_panel_device = {
756 .name = "mipi_simulator",
757 .id = 0,
758};
759
760#define LPM_CHANNEL0 0
761static int toshiba_gpio[] = {LPM_CHANNEL0};
762
763static struct mipi_dsi_panel_platform_data toshiba_pdata = {
764 .gpio = toshiba_gpio,
Chandan Uddaraju2679f092012-03-09 15:48:04 -0800765 .dsi_pwm_cfg = mipi_dsi_panel_pwm_cfg,
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800766};
767
768static struct platform_device mipi_dsi_toshiba_panel_device = {
769 .name = "mipi_toshiba",
770 .id = 0,
771 .dev = {
772 .platform_data = &toshiba_pdata,
773 }
774};
775
776#define FPGA_3D_GPIO_CONFIG_ADDR 0xB5
Amir Samuelovca199b92012-01-31 14:50:04 +0200777static int dsi2lvds_gpio[4] = {
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800778 0,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
Amir Samuelovca199b92012-01-31 14:50:04 +0200779 0x1F08, /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
780 GPIO_LIQUID_EXPANDER_BASE+6, /* TN Enable */
781 GPIO_LIQUID_EXPANDER_BASE+7, /* TN Mode */
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800782 };
783
784static struct msm_panel_common_pdata mipi_dsi2lvds_pdata = {
785 .gpio_num = dsi2lvds_gpio,
786};
787
788static struct mipi_dsi_phy_ctrl dsi_novatek_cmd_mode_phy_db = {
789
790/* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */
791 {0x0F, 0x0a, 0x04, 0x00, 0x20}, /* regulator */
792 /* timing */
793 {0xab, 0x8a, 0x18, 0x00, 0x92, 0x97, 0x1b, 0x8c,
794 0x0c, 0x03, 0x04, 0xa0},
795 {0x5f, 0x00, 0x00, 0x10}, /* phy ctrl */
796 {0xff, 0x00, 0x06, 0x00}, /* strength */
797 /* pll control */
798 {0x40, 0xf9, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,
799 0x40, 0x07, 0x03,
800 0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01},
801};
802
803static struct mipi_dsi_panel_platform_data novatek_pdata = {
804 .fpga_3d_config_addr = FPGA_3D_GPIO_CONFIG_ADDR,
805 .fpga_ctrl_mode = FPGA_SPI_INTF,
806 .phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
807};
808
809static struct platform_device mipi_dsi_novatek_panel_device = {
810 .name = "mipi_novatek",
811 .id = 0,
812 .dev = {
813 .platform_data = &novatek_pdata,
814 }
815};
816
817static struct platform_device mipi_dsi2lvds_bridge_device = {
818 .name = "mipi_tc358764",
819 .id = 0,
820 .dev.platform_data = &mipi_dsi2lvds_pdata,
821};
822
Ravishangar Kalyaname2d015c2012-01-26 14:47:14 -0800823static struct platform_device mipi_dsi_orise_panel_device = {
824 .name = "mipi_orise",
825 .id = 0,
826};
827
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800828#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
829static struct resource hdmi_msm_resources[] = {
830 {
831 .name = "hdmi_msm_qfprom_addr",
832 .start = 0x00700000,
833 .end = 0x007060FF,
834 .flags = IORESOURCE_MEM,
835 },
836 {
837 .name = "hdmi_msm_hdmi_addr",
838 .start = 0x04A00000,
839 .end = 0x04A00FFF,
840 .flags = IORESOURCE_MEM,
841 },
842 {
843 .name = "hdmi_msm_irq",
844 .start = HDMI_IRQ,
845 .end = HDMI_IRQ,
846 .flags = IORESOURCE_IRQ,
847 },
848};
849
850static int hdmi_enable_5v(int on);
851static int hdmi_core_power(int on, int show);
852static int hdmi_cec_power(int on);
853
854static struct msm_hdmi_platform_data hdmi_msm_data = {
855 .irq = HDMI_IRQ,
856 .enable_5v = hdmi_enable_5v,
857 .core_power = hdmi_core_power,
858 .cec_power = hdmi_cec_power,
859};
860
861static struct platform_device hdmi_msm_device = {
862 .name = "hdmi_msm",
863 .id = 0,
864 .num_resources = ARRAY_SIZE(hdmi_msm_resources),
865 .resource = hdmi_msm_resources,
866 .dev.platform_data = &hdmi_msm_data,
867};
868#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
869
870#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
871static struct platform_device wfd_panel_device = {
872 .name = "wfd_panel",
873 .id = 0,
874 .dev.platform_data = NULL,
875};
Stepan Moskovchenko270888d2011-11-30 12:19:11 -0800876
877static struct platform_device wfd_device = {
878 .name = "msm_wfd",
879 .id = -1,
880};
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800881#endif
882
883#ifdef CONFIG_MSM_BUS_SCALING
884static struct msm_bus_vectors dtv_bus_init_vectors[] = {
885 {
886 .src = MSM_BUS_MASTER_MDP_PORT0,
887 .dst = MSM_BUS_SLAVE_EBI_CH0,
888 .ab = 0,
889 .ib = 0,
890 },
891};
892
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800893static struct msm_bus_vectors dtv_bus_def_vectors[] = {
894 {
895 .src = MSM_BUS_MASTER_MDP_PORT0,
896 .dst = MSM_BUS_SLAVE_EBI_CH0,
897 .ab = 566092800 * 2,
898 .ib = 707616000 * 2,
899 },
900};
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800901
902static struct msm_bus_paths dtv_bus_scale_usecases[] = {
903 {
904 ARRAY_SIZE(dtv_bus_init_vectors),
905 dtv_bus_init_vectors,
906 },
907 {
908 ARRAY_SIZE(dtv_bus_def_vectors),
909 dtv_bus_def_vectors,
910 },
911};
912static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
913 dtv_bus_scale_usecases,
914 ARRAY_SIZE(dtv_bus_scale_usecases),
915 .name = "dtv",
916};
917
918static struct lcdc_platform_data dtv_pdata = {
919 .bus_scale_table = &dtv_bus_scale_pdata,
920};
921#endif
922
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800923#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800924static int hdmi_enable_5v(int on)
925{
926 /* TBD: PM8921 regulator instead of 8901 */
927 static struct regulator *reg_8921_hdmi_mvs; /* HDMI_5V */
928 static int prev_on;
929 int rc;
930
931 if (on == prev_on)
932 return 0;
933
Ajay Singh Parmar07847642011-12-09 02:57:45 +0530934 if (!reg_8921_hdmi_mvs) {
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800935 reg_8921_hdmi_mvs = regulator_get(&hdmi_msm_device.dev,
Ajay Singh Parmar07847642011-12-09 02:57:45 +0530936 "hdmi_mvs");
937 if (IS_ERR(reg_8921_hdmi_mvs)) {
938 pr_err("'%s' regulator not found, rc=%ld\n",
939 "hdmi_mvs", IS_ERR(reg_8921_hdmi_mvs));
940 reg_8921_hdmi_mvs = NULL;
941 return -ENODEV;
942 }
943 }
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -0800944
945 if (on) {
946 rc = regulator_enable(reg_8921_hdmi_mvs);
947 if (rc) {
948 pr_err("'%s' regulator enable failed, rc=%d\n",
949 "8921_hdmi_mvs", rc);
950 return rc;
951 }
952 pr_debug("%s(on): success\n", __func__);
953 } else {
954 rc = regulator_disable(reg_8921_hdmi_mvs);
955 if (rc)
956 pr_warning("'%s' regulator disable failed, rc=%d\n",
957 "8921_hdmi_mvs", rc);
958 pr_debug("%s(off): success\n", __func__);
959 }
960
961 prev_on = on;
962
963 return 0;
964}
965
966static int hdmi_core_power(int on, int show)
967{
968 static struct regulator *reg_8921_l23, *reg_8921_s4;
969 static int prev_on;
970 int rc;
971
972 if (on == prev_on)
973 return 0;
974
975 /* TBD: PM8921 regulator instead of 8901 */
976 if (!reg_8921_l23) {
977 reg_8921_l23 = regulator_get(&hdmi_msm_device.dev, "hdmi_avdd");
978 if (IS_ERR(reg_8921_l23)) {
979 pr_err("could not get reg_8921_l23, rc = %ld\n",
980 PTR_ERR(reg_8921_l23));
981 return -ENODEV;
982 }
983 rc = regulator_set_voltage(reg_8921_l23, 1800000, 1800000);
984 if (rc) {
985 pr_err("set_voltage failed for 8921_l23, rc=%d\n", rc);
986 return -EINVAL;
987 }
988 }
989 if (!reg_8921_s4) {
990 reg_8921_s4 = regulator_get(&hdmi_msm_device.dev, "hdmi_vcc");
991 if (IS_ERR(reg_8921_s4)) {
992 pr_err("could not get reg_8921_s4, rc = %ld\n",
993 PTR_ERR(reg_8921_s4));
994 return -ENODEV;
995 }
996 rc = regulator_set_voltage(reg_8921_s4, 1800000, 1800000);
997 if (rc) {
998 pr_err("set_voltage failed for 8921_s4, rc=%d\n", rc);
999 return -EINVAL;
1000 }
1001 }
1002
1003 if (on) {
1004 rc = regulator_set_optimum_mode(reg_8921_l23, 100000);
1005 if (rc < 0) {
1006 pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
1007 return -EINVAL;
1008 }
1009 rc = regulator_enable(reg_8921_l23);
1010 if (rc) {
1011 pr_err("'%s' regulator enable failed, rc=%d\n",
1012 "hdmi_avdd", rc);
1013 return rc;
1014 }
1015 rc = regulator_enable(reg_8921_s4);
1016 if (rc) {
1017 pr_err("'%s' regulator enable failed, rc=%d\n",
1018 "hdmi_vcc", rc);
1019 return rc;
1020 }
1021 rc = gpio_request(100, "HDMI_DDC_CLK");
1022 if (rc) {
1023 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
1024 "HDMI_DDC_CLK", 100, rc);
1025 goto error1;
1026 }
1027 rc = gpio_request(101, "HDMI_DDC_DATA");
1028 if (rc) {
1029 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
1030 "HDMI_DDC_DATA", 101, rc);
1031 goto error2;
1032 }
1033 rc = gpio_request(102, "HDMI_HPD");
1034 if (rc) {
1035 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
1036 "HDMI_HPD", 102, rc);
1037 goto error3;
1038 }
1039 pr_debug("%s(on): success\n", __func__);
1040 } else {
1041 gpio_free(100);
1042 gpio_free(101);
1043 gpio_free(102);
1044
1045 rc = regulator_disable(reg_8921_l23);
1046 if (rc) {
1047 pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
1048 return -ENODEV;
1049 }
1050 rc = regulator_disable(reg_8921_s4);
1051 if (rc) {
1052 pr_err("disable reg_8921_s4 failed, rc=%d\n", rc);
1053 return -ENODEV;
1054 }
1055 rc = regulator_set_optimum_mode(reg_8921_l23, 100);
1056 if (rc < 0) {
1057 pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
1058 return -EINVAL;
1059 }
1060 pr_debug("%s(off): success\n", __func__);
1061 }
1062
1063 prev_on = on;
1064
1065 return 0;
1066
1067error3:
1068 gpio_free(101);
1069error2:
1070 gpio_free(100);
1071error1:
1072 regulator_disable(reg_8921_l23);
1073 regulator_disable(reg_8921_s4);
1074 return rc;
1075}
1076
1077static int hdmi_cec_power(int on)
1078{
1079 static int prev_on;
1080 int rc;
1081
1082 if (on == prev_on)
1083 return 0;
1084
1085 if (on) {
1086 rc = gpio_request(99, "HDMI_CEC_VAR");
1087 if (rc) {
1088 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
1089 "HDMI_CEC_VAR", 99, rc);
1090 goto error;
1091 }
1092 pr_debug("%s(on): success\n", __func__);
1093 } else {
1094 gpio_free(99);
1095 pr_debug("%s(off): success\n", __func__);
1096 }
1097
1098 prev_on = on;
1099
1100 return 0;
1101error:
1102 return rc;
1103}
1104#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
1105
1106void __init msm8960_init_fb(void)
1107{
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -08001108 platform_device_register(&msm_fb_device);
1109
Stepan Moskovchenko270888d2011-11-30 12:19:11 -08001110#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
1111 platform_device_register(&wfd_panel_device);
1112 platform_device_register(&wfd_device);
1113#endif
1114
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -08001115 if (machine_is_msm8960_sim())
1116 platform_device_register(&mipi_dsi_simulator_panel_device);
1117
1118 if (machine_is_msm8960_rumi3())
1119 platform_device_register(&mipi_dsi_renesas_panel_device);
1120
1121 if (!machine_is_msm8960_sim() && !machine_is_msm8960_rumi3()) {
1122 platform_device_register(&mipi_dsi_novatek_panel_device);
Ravishangar Kalyaname2d015c2012-01-26 14:47:14 -08001123 platform_device_register(&mipi_dsi_orise_panel_device);
Stepan Moskovchenko24cd8642011-11-29 13:07:53 -08001124
1125#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
1126 platform_device_register(&hdmi_msm_device);
1127#endif
1128 }
1129
1130 if (machine_is_msm8960_liquid())
1131 platform_device_register(&mipi_dsi2lvds_bridge_device);
1132 else
1133 platform_device_register(&mipi_dsi_toshiba_panel_device);
1134
1135 if (machine_is_msm8x60_rumi3()) {
1136 msm_fb_register_device("mdp", NULL);
1137 mipi_dsi_pdata.target_type = 1;
1138 } else
1139 msm_fb_register_device("mdp", &mdp_pdata);
1140 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1141#ifdef CONFIG_MSM_BUS_SCALING
1142 msm_fb_register_device("dtv", &dtv_pdata);
1143#endif
1144}
1145
1146void __init msm8960_allocate_fb_region(void)
1147{
1148 void *addr;
1149 unsigned long size;
1150
1151 size = MSM_FB_SIZE;
1152 addr = alloc_bootmem_align(size, 0x1000);
1153 msm_fb_resources[0].start = __pa(addr);
1154 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
1155 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
1156 size, addr, __pa(addr));
1157}
Ravishangar Kalyanam8c79ead2011-12-02 21:05:01 -08001158
1159void __init msm8960_set_display_params(char *prim_panel, char *ext_panel)
1160{
1161 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1162 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1163 PANEL_NAME_MAX_LEN);
1164 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1165 msm_fb_pdata.prim_panel_name);
1166
1167 if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
1168 HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
1169 PANEL_NAME_MAX_LEN))) {
1170 pr_debug("HDMI is the primary display by"
1171 " boot parameter\n");
1172 hdmi_is_primary = 1;
1173 }
1174 }
1175 if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
1176 strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
1177 PANEL_NAME_MAX_LEN);
1178 pr_debug("msm_fb_pdata.ext_panel_name %s\n",
1179 msm_fb_pdata.ext_panel_name);
1180 }
1181}