blob: 96754b776064cf6981582edb4ae4dadc8c0ea80f [file] [log] [blame]
Jeevan Shriram2d3500b2014-12-29 16:25:06 -08001/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Dhaval Patel019057a2014-08-12 13:52:25 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in
10 * the documentation and/or other materials provided with the
11 * distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <debug.h>
Veera Sundaram Sankaran089f70d2014-12-09 14:17:05 -080031#include <string.h>
Dhaval Patel019057a2014-08-12 13:52:25 -070032#include <smem.h>
33#include <err.h>
34#include <msm_panel.h>
35#include <mipi_dsi.h>
Casey Piper6c2f1132015-03-24 11:37:19 -070036#include <mdss_hdmi.h>
Dhaval Patel019057a2014-08-12 13:52:25 -070037#include <pm8x41.h>
38#include <pm8x41_wled.h>
39#include <qpnp_wled.h>
40#include <board.h>
41#include <mdp5.h>
42#include <scm.h>
43#include <endian.h>
Veera Sundaram Sankaran089f70d2014-12-09 14:17:05 -080044#include <regulator.h>
45#include <qtimer.h>
46#include <arch/defines.h>
Dhaval Patel019057a2014-08-12 13:52:25 -070047#include <platform/gpio.h>
48#include <platform/clock.h>
49#include <platform/iomap.h>
50#include <target/display.h>
51#include "include/panel.h"
52#include "include/display_resource.h"
Veera Sundaram Sankaran089f70d2014-12-09 14:17:05 -080053#include "gcdb_display.h"
Dhaval Patel019057a2014-08-12 13:52:25 -070054
55#define HFPLL_LDO_ID 12
56
57#define GPIO_STATE_LOW 0
58#define GPIO_STATE_HIGH 2
59#define RESET_GPIO_SEQ_LEN 3
60
61#define PWM_DUTY_US 13
62#define PWM_PERIOD_US 27
63#define PMIC_WLED_SLAVE_ID 3
64#define PMIC_MPP_SLAVE_ID 2
65
Jeevan Shriram7aacc322014-12-29 16:02:25 -080066#define DSI0_BASE_ADJUST -0x4000
67#define DSI1_BASE_ADJUST -0xA000
68
Veera Sundaram Sankaran089f70d2014-12-09 14:17:05 -080069/*---------------------------------------------------------------------------*/
70/* GPIO configuration */
71/*---------------------------------------------------------------------------*/
72static struct gpio_pin reset_gpio = {
73 "msmgpio", 78, 3, 1, 0, 1
74};
75
76static struct gpio_pin lcd_reg_en = { /* boost regulator */
77 "pm8994_gpios", 14, 3, 1, 0, 1
78};
79
80static struct gpio_pin bklt_gpio = { /* lcd_bklt_reg_en */
81 "pmi8994_gpios", 2, 3, 1, 0, 1
82};
83
Ajay Singh Parmar20bdc1b2015-02-13 23:47:40 -080084/* gpio name, id, strength, direction, pull, state. */
85static struct gpio_pin hdmi_cec_gpio = { /* CEC */
86 "msmgpio", 31, 0, 2, 3, 1
87};
88
89static struct gpio_pin hdmi_ddc_clk_gpio = { /* DDC CLK */
90 "msmgpio", 32, 0, 2, 3, 1
91};
92
93static struct gpio_pin hdmi_ddc_data_gpio = { /* DDC DATA */
94 "msmgpio", 33, 0, 2, 3, 1
95};
96
97static struct gpio_pin hdmi_hpd_gpio = { /* HPD, input */
98 "msmgpio", 34, 7, 0, 1, 1
99};
100
Casey Piperd2af07b2015-04-01 18:01:58 -0700101
102static void target_hdmi_ldo_enable(uint8_t enable)
103{
104 if (enable)
105 regulator_enable(REG_LDO12);
106 else
107 regulator_disable(REG_LDO12);
108}
109
110static void target_hdmi_mpp4_enable(uint8_t enable)
111{
112 struct pm8x41_mpp mpp;
113
114 /* Enable MPP4 */
115 pmi8994_config_mpp_slave_id(0);
116
117 mpp.base = PM8x41_MMP4_BASE;
118 mpp.vin = MPP_VIN2;
119 mpp.mode = MPP_HIGH;;
120 if (enable) {
121 pm8x41_config_output_mpp(&mpp);
122 pm8x41_enable_mpp(&mpp, MPP_ENABLE);
123 } else {
124 pm8x41_enable_mpp(&mpp, MPP_DISABLE);
125 }
126
127 /* Need delay before power on regulators */
128 mdelay(20);
129}
130
131int target_hdmi_regulator_ctrl(uint8_t enable)
132{
133 target_hdmi_ldo_enable(enable);
134
135 target_hdmi_mpp4_enable(enable);
136
137 return 0;
138}
139
Ajay Singh Parmar20bdc1b2015-02-13 23:47:40 -0800140int target_hdmi_gpio_ctrl(uint8_t enable)
141{
142 gpio_tlmm_config(hdmi_cec_gpio.pin_id, 1, /* gpio 31, CEC */
143 hdmi_cec_gpio.pin_direction, hdmi_cec_gpio.pin_pull,
144 hdmi_cec_gpio.pin_strength, hdmi_cec_gpio.pin_state);
145
146 gpio_tlmm_config(hdmi_ddc_clk_gpio.pin_id, 1, /* gpio 32, DDC CLK */
147 hdmi_ddc_clk_gpio.pin_direction, hdmi_ddc_clk_gpio.pin_pull,
148 hdmi_ddc_clk_gpio.pin_strength, hdmi_ddc_clk_gpio.pin_state);
149
150
151 gpio_tlmm_config(hdmi_ddc_data_gpio.pin_id, 1, /* gpio 33, DDC DATA */
152 hdmi_ddc_data_gpio.pin_direction, hdmi_ddc_data_gpio.pin_pull,
153 hdmi_ddc_data_gpio.pin_strength, hdmi_ddc_data_gpio.pin_state);
154
155 gpio_tlmm_config(hdmi_hpd_gpio.pin_id, 1, /* gpio 34, HPD */
156 hdmi_hpd_gpio.pin_direction, hdmi_hpd_gpio.pin_pull,
157 hdmi_hpd_gpio.pin_strength, hdmi_hpd_gpio.pin_state);
158
159 gpio_set(hdmi_cec_gpio.pin_id, hdmi_cec_gpio.pin_direction);
160 gpio_set(hdmi_ddc_clk_gpio.pin_id, hdmi_ddc_clk_gpio.pin_direction);
161 gpio_set(hdmi_ddc_data_gpio.pin_id, hdmi_ddc_data_gpio.pin_direction);
162 gpio_set(hdmi_hpd_gpio.pin_id, hdmi_hpd_gpio.pin_direction);
163
164 return NO_ERROR;
165}
166
Ajay Singh Parmara8d98712015-02-16 21:05:24 -0800167int target_hdmi_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
168{
169 uint32_t ret;
170
171 dprintf(SPEW, "%s: target_panel_clock\n", __func__);
172
173 if (enable) {
174 mdp_gdsc_ctrl(enable);
175 mmss_bus_clock_enable();
176 mdp_clock_enable();
177 ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
178 if (ret) {
179 dprintf(CRITICAL,
180 "%s: Failed to restore MDP security configs",
181 __func__);
182 mdp_clock_disable();
183 mmss_bus_clock_disable();
184 mdp_gdsc_ctrl(0);
185 return ret;
186 }
187
188 hdmi_core_ahb_clk_enable();
189 } else if(!target_cont_splash_screen()) {
190 hdmi_core_ahb_clk_disable();
191 mdp_clock_disable();
192 mmss_bus_clock_disable();
193 mdp_gdsc_ctrl(enable);
194 }
195
196 return NO_ERROR;
197}
Dhaval Patel019057a2014-08-12 13:52:25 -0700198static uint32_t dsi_pll_20nm_enable_seq(uint32_t pll_base)
199{
200 uint32_t pll_locked;
Jeevan Shriram5a9f8f42014-12-14 14:56:14 -0800201 /* MDSS_DSI_0_PHY_DSIPHY_CTRL_1 */
202 writel(0x00, pll_base + 0x374);
Dhaval Patel019057a2014-08-12 13:52:25 -0700203 dmb();
Jeevan Shriram5a9f8f42014-12-14 14:56:14 -0800204 /* MDSS_DSI_0_PHY_DSIPHY_CTRL_0 */
205 writel(0x7f, pll_base + 0x370);
206 dmb();
207 pll_locked = mdss_dsi_pll_20nm_lock_status(pll_base);
208 if (!pll_locked)
209 dprintf(INFO, "%s: DSI PLL lock failed\n", __func__);
210 else
211 dprintf(INFO, "%s: DSI PLL lock Success\n", __func__);
Dhaval Patel019057a2014-08-12 13:52:25 -0700212
213 return pll_locked;
214}
215
216static int msm8994_wled_backlight_ctrl(uint8_t enable)
217{
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700218 uint8_t slave_id = 3; /* pmi */
Dhaval Patel019057a2014-08-12 13:52:25 -0700219
Veera Sundaram Sankaranf9ddd6c2014-12-02 11:04:52 -0800220 pm8x41_wled_config_slave_id(slave_id);
221 qpnp_wled_enable_backlight(enable);
Dhaval Patel019057a2014-08-12 13:52:25 -0700222 qpnp_ibb_enable(enable);
223 return NO_ERROR;
224}
225
226static int msm8994_pwm_backlight_ctrl(uint8_t enable)
227{
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700228 uint8_t slave_id = 3; /* lpg at pmi */
229
230 if (enable) {
231 /* mpp-1 had been configured already */
232 /* lpg channel 4 */
233
234 /* LPG_ENABLE_CONTROL */
235 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
236 mdelay(100);
237
238 /* LPG_VALUE_LSB, duty cycle = 0x80/0x200 = 1/4 */
239 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x44, 0x80);
240 /* LPG_VALUE_MSB */
241 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x45, 0x00);
242 /* LPG_PWM_SYNC */
243 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x47, 0x01);
244
245 /* LPG_PWM_SIZE_CLK, */
246 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x41, 0x13);
247 /* LPG_PWM_FREQ_PREDIV */
248 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x42, 0x02);
249 /* LPG_PWM_TYPE_CONFIG */
250 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x43, 0x20);
251 /* LPG_ENABLE_CONTROL */
252 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x04);
253
254 /* SEC_ACCESS */
255 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xD0, 0xA5);
256 /* DTEST4, OUT_HI */
257 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xE5, 0x01);
258 /* LPG_ENABLE_CONTROL */
259 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0xA4);
260 } else {
261 /* LPG_ENABLE_CONTROL */
262 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
263 }
264
265 return NO_ERROR;
266}
267
268void lcd_bklt_reg_enable(void)
269{
270 uint8_t slave_id = 2; /* gpio at pmi */
271
272 struct pm8x41_gpio gpio = {
273 .direction = PM_GPIO_DIR_OUT,
274 .function = PM_GPIO_FUNC_HIGH,
275 .vin_sel = 2, /* VIN_2 */
276 .output_buffer = PM_GPIO_OUT_CMOS,
277 .out_strength = PM_GPIO_OUT_DRIVE_LOW,
278 };
279
280 pm8x41_gpio_config_sid(slave_id, bklt_gpio.pin_id, &gpio);
281 pm8x41_gpio_set_sid(slave_id, bklt_gpio.pin_id, 1);
282}
283
284void lcd_bklt_reg_disable(void)
285{
286 uint8_t slave_id = 2; /* gpio at pmi */
287
288 pm8x41_gpio_set_sid(slave_id, bklt_gpio.pin_id, 0);
Dhaval Patel019057a2014-08-12 13:52:25 -0700289}
290
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700291void lcd_reg_enable(void)
Dhaval Patel019057a2014-08-12 13:52:25 -0700292{
293 struct pm8x41_gpio gpio = {
294 .direction = PM_GPIO_DIR_OUT,
295 .function = PM_GPIO_FUNC_HIGH,
296 .vin_sel = 2, /* VIN_2 */
297 .output_buffer = PM_GPIO_OUT_CMOS,
298 .out_strength = PM_GPIO_OUT_DRIVE_MED,
299 };
300
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700301 pm8x41_gpio_config(lcd_reg_en.pin_id, &gpio);
302 pm8x41_gpio_set(lcd_reg_en.pin_id, 1);
303}
304
305void lcd_reg_disable(void)
306{
307 pm8x41_gpio_set(lcd_reg_en.pin_id, 0);
Dhaval Patel019057a2014-08-12 13:52:25 -0700308}
309
310int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
311{
312 uint32_t ret = NO_ERROR;
313 struct pm8x41_mpp mpp;
314 int rc;
315
316 if (!bl) {
317 dprintf(CRITICAL, "backlight structure is not available\n");
318 return ERR_INVALID_ARGS;
319 }
320
321 switch (bl->bl_interface_type) {
322 case BL_WLED:
323 /* Enable MPP4 */
324 pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
325 mpp.base = PM8x41_MMP4_BASE;
326 mpp.vin = MPP_VIN2;
327 if (enable) {
328 pm_pwm_enable(false);
329 rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
330 if (rc < 0) {
331 mpp.mode = MPP_HIGH;
332 } else {
333 mpp.mode = MPP_DTEST1;
334 pm_pwm_enable(true);
335 }
336 pm8x41_config_output_mpp(&mpp);
337 pm8x41_enable_mpp(&mpp, MPP_ENABLE);
338 } else {
339 pm_pwm_enable(false);
340 pm8x41_enable_mpp(&mpp, MPP_DISABLE);
341 }
342 /* Need delay before power on regulators */
343 mdelay(20);
344 /* Enable WLED backlight control */
345 ret = msm8994_wled_backlight_ctrl(enable);
346 break;
347 case BL_PWM:
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700348 /* Enable MPP1 */
349 pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
350 mpp.base = PM8x41_MMP1_BASE;
351 mpp.vin = MPP_VIN2;
352 mpp.mode = MPP_DTEST4;
353 if (enable) {
354 pm8x41_config_output_mpp(&mpp);
355 pm8x41_enable_mpp(&mpp, MPP_ENABLE);
356 } else {
357 pm8x41_enable_mpp(&mpp, MPP_DISABLE);
358 }
359 /* Need delay before power on regulators */
360 mdelay(20);
Dhaval Patel019057a2014-08-12 13:52:25 -0700361 ret = msm8994_pwm_backlight_ctrl(enable);
362 break;
363 default:
364 dprintf(CRITICAL, "backlight type:%d not supported\n",
365 bl->bl_interface_type);
366 return ERR_NOT_SUPPORTED;
367 }
368
369 return ret;
370}
371
Casey Piper6c2f1132015-03-24 11:37:19 -0700372int target_hdmi_pll_clock(uint8_t enable, struct msm_panel_info *pinfo)
373{
374 if (enable) {
375 hdmi_phy_reset();
376 hdmi_pll_config(pinfo->clk_rate);
377 hdmi_vco_enable();
378 hdmi_pixel_clk_enable(pinfo->clk_rate);
379 } else if(!target_cont_splash_screen()) {
380 /* Disable clocks if continuous splash off */
381 hdmi_pixel_clk_disable();
382 hdmi_vco_disable();
383 }
384
385 return NO_ERROR;
386}
387
Dhaval Patel019057a2014-08-12 13:52:25 -0700388int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
389{
Huaibin Yang928201b2015-01-15 10:40:21 -0800390 uint32_t ret = NO_ERROR;
Dhaval Patel019057a2014-08-12 13:52:25 -0700391 struct mdss_dsi_pll_config *pll_data;
Padmanabhan Komanduru3ccc0552015-04-27 16:46:33 -0700392 uint32_t flags, dsi_phy_pll_out;
Huaibin Yang928201b2015-01-15 10:40:21 -0800393 struct dfps_pll_codes *pll_codes = &pinfo->mipi.pll_codes;
Aravind Venkateswaranf3554322014-12-08 12:03:48 -0800394
395 if (pinfo->dest == DISPLAY_2) {
396 flags = MMSS_DSI_CLKS_FLAG_DSI1;
397 if (pinfo->mipi.dual_dsi)
398 flags |= MMSS_DSI_CLKS_FLAG_DSI0;
399 } else {
400 flags = MMSS_DSI_CLKS_FLAG_DSI0;
401 if (pinfo->mipi.dual_dsi)
402 flags |= MMSS_DSI_CLKS_FLAG_DSI1;
403 }
Dhaval Patel019057a2014-08-12 13:52:25 -0700404
405 pll_data = pinfo->mipi.dsi_pll_config;
Huaibin Yang928201b2015-01-15 10:40:21 -0800406
407 if (!enable) {
Aravind Venkateswaranf3554322014-12-08 12:03:48 -0800408 mmss_dsi_clock_disable(flags);
Huaibin Yang928201b2015-01-15 10:40:21 -0800409 goto clks_disable;
Dhaval Patel019057a2014-08-12 13:52:25 -0700410 }
411
Huaibin Yang928201b2015-01-15 10:40:21 -0800412 mdp_gdsc_ctrl(enable);
413 mmss_bus_clock_enable();
414 mdp_clock_enable();
415
416 ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
417 if (ret) {
418 dprintf(CRITICAL,
419 "%s: Failed to restore MDP security configs",
420 __func__);
421 goto clks_disable;
422 }
423
Aravind Venkateswaranf2702352015-07-23 18:14:13 -0700424 mdss_dsi_auto_pll_20nm_config(pinfo);
Huaibin Yang928201b2015-01-15 10:40:21 -0800425
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700426 if (!dsi_pll_20nm_enable_seq(pinfo->mipi.pll_base)) {
Huaibin Yang928201b2015-01-15 10:40:21 -0800427 ret = ERROR;
428 dprintf(CRITICAL, "PLL failed to lock!\n");
429 goto clks_disable;
430 }
431
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700432 pll_codes->codes[0] = readl_relaxed(pinfo->mipi.pll_base +
Huaibin Yang928201b2015-01-15 10:40:21 -0800433 MMSS_DSI_PHY_PLL_CORE_KVCO_CODE);
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700434 pll_codes->codes[1] = readl_relaxed(pinfo->mipi.pll_base +
Huaibin Yang928201b2015-01-15 10:40:21 -0800435 MMSS_DSI_PHY_PLL_CORE_VCO_TUNE);
436 dprintf(SPEW, "codes %d %d\n", pll_codes->codes[0],
437 pll_codes->codes[1]);
438
Padmanabhan Komanduru3ccc0552015-04-27 16:46:33 -0700439 if (pinfo->mipi.use_dsi1_pll)
440 dsi_phy_pll_out = DSI1_PHY_PLL_OUT;
441 else
442 dsi_phy_pll_out = DSI0_PHY_PLL_OUT;
443
444 mmss_dsi_clock_enable(dsi_phy_pll_out, flags,
Huaibin Yang928201b2015-01-15 10:40:21 -0800445 pll_data->pclk_m,
446 pll_data->pclk_n,
447 pll_data->pclk_d);
448
Dhaval Patel019057a2014-08-12 13:52:25 -0700449 return NO_ERROR;
Huaibin Yang928201b2015-01-15 10:40:21 -0800450
451clks_disable:
452 mdp_clock_disable();
453 mmss_bus_clock_disable();
454 mdp_gdsc_ctrl(0);
455
456 return ret;
Dhaval Patel019057a2014-08-12 13:52:25 -0700457}
458
459int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
460 struct msm_panel_info *pinfo)
461{
462 uint32_t i = 0;
463
464 if (enable) {
465 gpio_tlmm_config(reset_gpio.pin_id, 0,
466 reset_gpio.pin_direction, reset_gpio.pin_pull,
467 reset_gpio.pin_strength, reset_gpio.pin_state);
468 /* reset */
469 for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
470 if (resetseq->pin_state[i] == GPIO_STATE_LOW)
471 gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
472 else
473 gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
474 mdelay(resetseq->sleep[i]);
475 }
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700476 lcd_bklt_reg_enable();
Dhaval Patel019057a2014-08-12 13:52:25 -0700477 } else {
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700478 lcd_bklt_reg_disable();
Dhaval Patel019057a2014-08-12 13:52:25 -0700479 gpio_set(reset_gpio.pin_id, 0);
480 }
481
482 return NO_ERROR;
483}
484
Kuogee Hsieh099022f2014-12-05 15:43:40 -0800485static void wled_init(struct msm_panel_info *pinfo)
486{
487 struct qpnp_wled_config_data config = {0};
488 struct labibb_desc *labibb;
489 int display_type = 0;
490
491 labibb = pinfo->labibb;
492
493 if (labibb)
494 display_type = labibb->amoled_panel;
495
496 config.display_type = display_type;
497 config.lab_init_volt = 4600000; /* fixed, see pmi register */
498 config.ibb_init_volt = 1400000; /* fixed, see pmi register */
499
500 if (labibb && labibb->force_config) {
501 config.lab_min_volt = labibb->lab_min_volt;
502 config.lab_max_volt = labibb->lab_max_volt;
503 config.ibb_min_volt = labibb->ibb_min_volt;
504 config.ibb_max_volt = labibb->ibb_max_volt;
505 config.pwr_up_delay = labibb->pwr_up_delay;
506 config.pwr_down_delay = labibb->pwr_down_delay;
507 config.ibb_discharge_en = labibb->ibb_discharge_en;
508 } else {
509 /* default */
510 config.pwr_up_delay = 3;
511 config.pwr_down_delay = 3;
512 config.ibb_discharge_en = 1;
513 if (display_type) { /* amoled */
514 config.lab_min_volt = 4600000;
515 config.lab_max_volt = 4600000;
516 config.ibb_min_volt = 4000000;
517 config.ibb_max_volt = 4000000;
518 } else { /* lcd */
519 config.lab_min_volt = 5500000;
520 config.lab_max_volt = 5500000;
521 config.ibb_min_volt = 5500000;
522 config.ibb_max_volt = 5500000;
523 }
524 }
525
526 dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d %d %d\n", __func__,
527 config.display_type,
528 config.lab_min_volt, config.lab_max_volt,
529 config.ibb_min_volt, config.ibb_max_volt,
530 config.lab_init_volt, config.ibb_init_volt,
531 config.pwr_up_delay, config.pwr_down_delay,
532 config.ibb_discharge_en);
533
534
535 /* QPNP WLED init for display backlight */
536 pm8x41_wled_config_slave_id(PMIC_WLED_SLAVE_ID);
537
538 qpnp_wled_init(&config);
539}
540
Kuogee Hsieh93bcff62014-08-22 14:02:08 -0700541int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
Dhaval Patel019057a2014-08-12 13:52:25 -0700542{
543 if (enable) {
Casey Piperd2af07b2015-04-01 18:01:58 -0700544 regulator_enable(REG_LDO2 | REG_LDO12 |
545 REG_LDO14 | REG_LDO28);
Dhaval Patel019057a2014-08-12 13:52:25 -0700546 mdelay(10);
Kuogee Hsieh099022f2014-12-05 15:43:40 -0800547 wled_init(pinfo);
Dhaval Patel019057a2014-08-12 13:52:25 -0700548 qpnp_ibb_enable(true); /* +5V and -5V */
549 mdelay(50);
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700550
551 if (pinfo->lcd_reg_en)
552 lcd_reg_enable();
Dhaval Patel019057a2014-08-12 13:52:25 -0700553 } else {
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700554 if (pinfo->lcd_reg_en)
555 lcd_reg_disable();
556
Casey Piperd2af07b2015-04-01 18:01:58 -0700557 regulator_disable(REG_LDO2 | REG_LDO12 |
558 REG_LDO14 | REG_LDO28);
Dhaval Patel019057a2014-08-12 13:52:25 -0700559 }
560
561 return NO_ERROR;
562}
563
564int target_display_pre_on()
565{
Ingrid Gallardoc9776bd2014-09-04 14:13:28 -0700566 writel(0xC0000CCC, MDP_CLK_CTRL0);
567 writel(0xC0000CCC, MDP_CLK_CTRL1);
Dhaval Patel019057a2014-08-12 13:52:25 -0700568 writel(0x00CCCCCC, MDP_CLK_CTRL2);
569 writel(0x000000CC, MDP_CLK_CTRL6);
570 writel(0x0CCCC0C0, MDP_CLK_CTRL3);
571 writel(0xCCCCC0C0, MDP_CLK_CTRL4);
572 writel(0xCCCCC0C0, MDP_CLK_CTRL5);
573 writel(0x00CCC000, MDP_CLK_CTRL7);
574
Dhaval Patel019057a2014-08-12 13:52:25 -0700575 return NO_ERROR;
576}
577
Dhaval Patel7709c412015-05-12 10:09:41 -0700578int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
579{
580 memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
581 memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
582 memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
583 memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
584 memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
585 return NO_ERROR;
586}
587
Jeevan Shriram7aacc322014-12-29 16:02:25 -0800588int target_display_get_base_offset(uint32_t base)
589{
590 if(platform_is_msm8992()) {
Padmanabhan Komanduru36ff46c2015-06-08 14:06:31 +0530591 if ((base == MIPI_DSI0_BASE) || (base == DSI0_PHY_BASE) ||
592 (base == DSI0_PLL_BASE) || (base == DSI0_REGULATOR_BASE))
Jeevan Shriram7aacc322014-12-29 16:02:25 -0800593 return DSI0_BASE_ADJUST;
Padmanabhan Komanduru36ff46c2015-06-08 14:06:31 +0530594 else if ((base == MIPI_DSI1_BASE) || (base == DSI1_PHY_BASE) ||
595 (base == DSI1_PLL_BASE))
Jeevan Shriram7aacc322014-12-29 16:02:25 -0800596 return DSI1_BASE_ADJUST;
597 }
598
599 return 0;
600}
601
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530602bool target_display_panel_node(char *pbuf, uint16_t buf_size)
Dhaval Patel019057a2014-08-12 13:52:25 -0700603{
Ajay Singh Parmarcc6477b2014-11-14 16:59:44 -0800604 int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
605 bool ret = true;
Casey Piper4fd18e12015-03-20 16:51:52 -0700606 char vic_buf[HDMI_VIC_LEN] = "0";
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530607 struct oem_panel_data oem = mdss_dsi_get_oem_data();
Dhaval Patel019057a2014-08-12 13:52:25 -0700608
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530609 if (!strcmp(oem.panel, HDMI_PANEL_NAME)) {
Ajay Singh Parmarcc6477b2014-11-14 16:59:44 -0800610 if (buf_size < (prefix_string_len + LK_OVERRIDE_PANEL_LEN +
611 strlen(HDMI_CONTROLLER_STRING))) {
612 dprintf(CRITICAL, "command line argument is greater than buffer size\n");
613 return false;
614 }
615
616 strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
617 buf_size -= prefix_string_len;
618 strlcat(pbuf, LK_OVERRIDE_PANEL, buf_size);
619 buf_size -= LK_OVERRIDE_PANEL_LEN;
620 strlcat(pbuf, HDMI_CONTROLLER_STRING, buf_size);
Casey Piper4fd18e12015-03-20 16:51:52 -0700621 buf_size -= strlen(HDMI_CONTROLLER_STRING);
622 mdss_hdmi_get_vic(vic_buf);
623 strlcat(pbuf, vic_buf, buf_size);
Ajay Singh Parmarcc6477b2014-11-14 16:59:44 -0800624 } else {
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530625 ret = gcdb_display_cmdline_arg(pbuf, buf_size);
Ajay Singh Parmarcc6477b2014-11-14 16:59:44 -0800626 }
627
628 return ret;
Dhaval Patel019057a2014-08-12 13:52:25 -0700629}
630
631void target_display_init(const char *panel_name)
632{
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530633 struct oem_panel_data oem;
Veera Sundaram Sankaran3b758822014-10-17 12:15:39 -0700634
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530635 set_panel_cmd_string(panel_name);
636 oem = mdss_dsi_get_oem_data();
637
638 if (!strcmp(oem.panel, NO_PANEL_CONFIG)
639 || !strcmp(oem.panel, SIM_VIDEO_PANEL)
640 || !strcmp(oem.panel, SIM_DUALDSI_VIDEO_PANEL)
641 || !strcmp(oem.panel, SIM_CMD_PANEL)
642 || !strcmp(oem.panel, SIM_DUALDSI_CMD_PANEL)
643 || oem.skip) {
Veera Sundaram Sankaranb620f232014-09-03 22:43:53 -0700644 dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530645 oem.panel);
Veera Sundaram Sankaranb620f232014-09-03 22:43:53 -0700646 return;
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530647 } else if (!strcmp(oem.panel, HDMI_PANEL_NAME)) {
Casey Pipere9073f52015-03-20 16:48:19 -0700648 dprintf(INFO, "%s: HDMI is primary\n", __func__);
649 mdss_hdmi_display_init(MDP_REV_50, (void *) MIPI_FB_ADDR);
Ajay Singh Parmarcc6477b2014-11-14 16:59:44 -0800650 return;
Veera Sundaram Sankaranb620f232014-09-03 22:43:53 -0700651 }
Veera Sundaram Sankaran7868d542015-01-02 14:48:47 -0800652
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530653 if (gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR)) {
Justin Philipbe9de5c2014-09-17 12:26:49 +0530654 target_force_cont_splash_disable(true);
Dhaval Patel019057a2014-08-12 13:52:25 -0700655 msm_display_off();
Justin Philipbe9de5c2014-09-17 12:26:49 +0530656 }
Veera Sundaram Sankaran7868d542015-01-02 14:48:47 -0800657
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530658 if (!oem.cont_splash) {
Veera Sundaram Sankaran7868d542015-01-02 14:48:47 -0800659 dprintf(INFO, "Forcing continuous splash disable\n");
660 target_force_cont_splash_disable(true);
661 }
Dhaval Patel019057a2014-08-12 13:52:25 -0700662}
663
664void target_display_shutdown(void)
665{
666 gcdb_display_shutdown();
667}