blob: edf1ceb50dd003d7fb6d154ac40860b252a347a5 [file] [log] [blame]
Dhaval Patel019057a2014-08-12 13:52:25 -07001/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
2 *
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>
31#include <smem.h>
32#include <err.h>
33#include <msm_panel.h>
34#include <mipi_dsi.h>
35#include <pm8x41.h>
36#include <pm8x41_wled.h>
37#include <qpnp_wled.h>
38#include <board.h>
39#include <mdp5.h>
40#include <scm.h>
41#include <endian.h>
42#include <platform/gpio.h>
43#include <platform/clock.h>
44#include <platform/iomap.h>
45#include <target/display.h>
46#include "include/panel.h"
47#include "include/display_resource.h"
48
49#define HFPLL_LDO_ID 12
50
51#define GPIO_STATE_LOW 0
52#define GPIO_STATE_HIGH 2
53#define RESET_GPIO_SEQ_LEN 3
54
55#define PWM_DUTY_US 13
56#define PWM_PERIOD_US 27
57#define PMIC_WLED_SLAVE_ID 3
58#define PMIC_MPP_SLAVE_ID 2
59
60static void dsi_pll_20nm_phy_init( uint32_t pll_base, int off)
61{
62 mdss_dsi_pll_20nm_sw_reset_st_machine(pll_base);
63
64 dmb();
65
66 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
67 writel(0x80, pll_base + off + 0x0174);
68
69 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
70 writel(0x00, pll_base + off + 0x0174);
71 udelay(5000);
72 /* Strength ctrl 0 */
73 writel(0x77, pll_base + off + 0x0184);
74 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
75 writel(0x7f, pll_base + off + 0x0170);
76
77 /* DSI_0_PHY_DSIPHY_GLBL_TEST_CTRL */
78 writel(0x00, pll_base + off + 0x01d4);
79
80 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_2 */
81 writel(0x00, pll_base + off + 0x0178);
82}
83
84static uint32_t dsi_pll_20nm_enable_seq(uint32_t pll_base)
85{
86 uint32_t pll_locked;
87
88 /*
89 * PLL power up sequence.
90 * Add necessary delays recommeded by hardware.
91 */
92 writel(0x0D, pll_base + 0x9c); /* MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN */
93 writel(0x07, pll_base + 0x14); /* MMSS_DSI_PHY_PLL_PLL_CNTRL */
94 writel(0x00, pll_base + 0x2c); /* MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN */
95 udelay(500);
96
97 dsi_pll_20nm_phy_init(pll_base, 0x200); /* Ctrl 0 */
98 dmb();
99
100 pll_locked = mdss_dsi_pll_20nm_lock_status(pll_base);
101 if (!pll_locked)
102 dprintf(INFO, "%s: DSI PLL lock failed\n", __func__);
103 else
104 dprintf(INFO, "%s: DSI PLL lock Success\n", __func__);
105
106 return pll_locked;
107}
108
109static int msm8994_wled_backlight_ctrl(uint8_t enable)
110{
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700111 uint8_t slave_id = 3; /* pmi */
Dhaval Patel019057a2014-08-12 13:52:25 -0700112
113 if (enable) {
114 pm8x41_wled_config_slave_id(slave_id);
115 qpnp_wled_enable_backlight(enable);
116 }
117 qpnp_ibb_enable(enable);
118 return NO_ERROR;
119}
120
121static int msm8994_pwm_backlight_ctrl(uint8_t enable)
122{
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700123 uint8_t slave_id = 3; /* lpg at pmi */
124
125 if (enable) {
126 /* mpp-1 had been configured already */
127 /* lpg channel 4 */
128
129 /* LPG_ENABLE_CONTROL */
130 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
131 mdelay(100);
132
133 /* LPG_VALUE_LSB, duty cycle = 0x80/0x200 = 1/4 */
134 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x44, 0x80);
135 /* LPG_VALUE_MSB */
136 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x45, 0x00);
137 /* LPG_PWM_SYNC */
138 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x47, 0x01);
139
140 /* LPG_PWM_SIZE_CLK, */
141 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x41, 0x13);
142 /* LPG_PWM_FREQ_PREDIV */
143 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x42, 0x02);
144 /* LPG_PWM_TYPE_CONFIG */
145 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x43, 0x20);
146 /* LPG_ENABLE_CONTROL */
147 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x04);
148
149 /* SEC_ACCESS */
150 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xD0, 0xA5);
151 /* DTEST4, OUT_HI */
152 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xE5, 0x01);
153 /* LPG_ENABLE_CONTROL */
154 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0xA4);
155 } else {
156 /* LPG_ENABLE_CONTROL */
157 pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
158 }
159
160 return NO_ERROR;
161}
162
163void lcd_bklt_reg_enable(void)
164{
165 uint8_t slave_id = 2; /* gpio at pmi */
166
167 struct pm8x41_gpio gpio = {
168 .direction = PM_GPIO_DIR_OUT,
169 .function = PM_GPIO_FUNC_HIGH,
170 .vin_sel = 2, /* VIN_2 */
171 .output_buffer = PM_GPIO_OUT_CMOS,
172 .out_strength = PM_GPIO_OUT_DRIVE_LOW,
173 };
174
175 pm8x41_gpio_config_sid(slave_id, bklt_gpio.pin_id, &gpio);
176 pm8x41_gpio_set_sid(slave_id, bklt_gpio.pin_id, 1);
177}
178
179void lcd_bklt_reg_disable(void)
180{
181 uint8_t slave_id = 2; /* gpio at pmi */
182
183 pm8x41_gpio_set_sid(slave_id, bklt_gpio.pin_id, 0);
Dhaval Patel019057a2014-08-12 13:52:25 -0700184}
185
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700186void lcd_reg_enable(void)
Dhaval Patel019057a2014-08-12 13:52:25 -0700187{
188 struct pm8x41_gpio gpio = {
189 .direction = PM_GPIO_DIR_OUT,
190 .function = PM_GPIO_FUNC_HIGH,
191 .vin_sel = 2, /* VIN_2 */
192 .output_buffer = PM_GPIO_OUT_CMOS,
193 .out_strength = PM_GPIO_OUT_DRIVE_MED,
194 };
195
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700196 pm8x41_gpio_config(lcd_reg_en.pin_id, &gpio);
197 pm8x41_gpio_set(lcd_reg_en.pin_id, 1);
198}
199
200void lcd_reg_disable(void)
201{
202 pm8x41_gpio_set(lcd_reg_en.pin_id, 0);
Dhaval Patel019057a2014-08-12 13:52:25 -0700203}
204
205int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
206{
207 uint32_t ret = NO_ERROR;
208 struct pm8x41_mpp mpp;
209 int rc;
210
211 if (!bl) {
212 dprintf(CRITICAL, "backlight structure is not available\n");
213 return ERR_INVALID_ARGS;
214 }
215
216 switch (bl->bl_interface_type) {
217 case BL_WLED:
218 /* Enable MPP4 */
219 pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
220 mpp.base = PM8x41_MMP4_BASE;
221 mpp.vin = MPP_VIN2;
222 if (enable) {
223 pm_pwm_enable(false);
224 rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
225 if (rc < 0) {
226 mpp.mode = MPP_HIGH;
227 } else {
228 mpp.mode = MPP_DTEST1;
229 pm_pwm_enable(true);
230 }
231 pm8x41_config_output_mpp(&mpp);
232 pm8x41_enable_mpp(&mpp, MPP_ENABLE);
233 } else {
234 pm_pwm_enable(false);
235 pm8x41_enable_mpp(&mpp, MPP_DISABLE);
236 }
237 /* Need delay before power on regulators */
238 mdelay(20);
239 /* Enable WLED backlight control */
240 ret = msm8994_wled_backlight_ctrl(enable);
241 break;
242 case BL_PWM:
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700243 /* Enable MPP1 */
244 pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
245 mpp.base = PM8x41_MMP1_BASE;
246 mpp.vin = MPP_VIN2;
247 mpp.mode = MPP_DTEST4;
248 if (enable) {
249 pm8x41_config_output_mpp(&mpp);
250 pm8x41_enable_mpp(&mpp, MPP_ENABLE);
251 } else {
252 pm8x41_enable_mpp(&mpp, MPP_DISABLE);
253 }
254 /* Need delay before power on regulators */
255 mdelay(20);
Dhaval Patel019057a2014-08-12 13:52:25 -0700256 ret = msm8994_pwm_backlight_ctrl(enable);
257 break;
258 default:
259 dprintf(CRITICAL, "backlight type:%d not supported\n",
260 bl->bl_interface_type);
261 return ERR_NOT_SUPPORTED;
262 }
263
264 return ret;
265}
266
267int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
268{
269 uint32_t ret;
270 struct mdss_dsi_pll_config *pll_data;
271 uint32_t dual_dsi = pinfo->mipi.dual_dsi;
272
273 pll_data = pinfo->mipi.dsi_pll_config;
274 if (enable) {
275 mdp_gdsc_ctrl(enable);
276 mmss_bus_clock_enable();
277 mdp_clock_enable();
278 ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
279 if (ret) {
280 dprintf(CRITICAL,
281 "%s: Failed to restore MDP security configs",
282 __func__);
283 mdp_clock_disable();
284 mmss_bus_clock_disable();
285 mdp_gdsc_ctrl(0);
286 return ret;
287 }
288 mdss_dsi_auto_pll_20nm_config(DSI0_PLL_BASE,
289 MIPI_DSI0_BASE, pll_data);
290 dsi_pll_20nm_enable_seq(DSI0_PLL_BASE);
291 mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi,
292 pll_data->pclk_m,
293 pll_data->pclk_n,
294 pll_data->pclk_d);
295 } else if(!target_cont_splash_screen()) {
296 /* Disable clocks if continuous splash off */
297 mmss_dsi_clock_disable(dual_dsi);
298 mdp_clock_disable();
299 mmss_bus_clock_disable();
300 mdp_gdsc_ctrl(enable);
301 }
302
303 return NO_ERROR;
304}
305
306int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
307 struct msm_panel_info *pinfo)
308{
309 uint32_t i = 0;
310
311 if (enable) {
312 gpio_tlmm_config(reset_gpio.pin_id, 0,
313 reset_gpio.pin_direction, reset_gpio.pin_pull,
314 reset_gpio.pin_strength, reset_gpio.pin_state);
315 /* reset */
316 for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
317 if (resetseq->pin_state[i] == GPIO_STATE_LOW)
318 gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
319 else
320 gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
321 mdelay(resetseq->sleep[i]);
322 }
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700323 lcd_bklt_reg_enable();
Dhaval Patel019057a2014-08-12 13:52:25 -0700324 } else {
Kuogee Hsieh911866e2014-09-02 16:41:18 -0700325 lcd_bklt_reg_disable();
Dhaval Patel019057a2014-08-12 13:52:25 -0700326 gpio_set(reset_gpio.pin_id, 0);
327 }
328
329 return NO_ERROR;
330}
331
Kuogee Hsieh93bcff62014-08-22 14:02:08 -0700332int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
Dhaval Patel019057a2014-08-12 13:52:25 -0700333{
334 if (enable) {
335 regulator_enable(); /* L2, L12, L14, and L28 */
336 mdelay(10);
337 qpnp_ibb_enable(true); /* +5V and -5V */
338 mdelay(50);
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700339
340 if (pinfo->lcd_reg_en)
341 lcd_reg_enable();
Dhaval Patel019057a2014-08-12 13:52:25 -0700342 } else {
Kuogee Hsieh208736d2014-08-22 14:16:55 -0700343 if (pinfo->lcd_reg_en)
344 lcd_reg_disable();
345
Dhaval Patel019057a2014-08-12 13:52:25 -0700346 regulator_disable();
347 }
348
349 return NO_ERROR;
350}
351
352int target_display_pre_on()
353{
354 writel(0x000000FA, MDP_QOS_REMAPPER_CLASS_0);
355 writel(0x00000055, MDP_QOS_REMAPPER_CLASS_1);
Ingrid Gallardoc9776bd2014-09-04 14:13:28 -0700356 writel(0xC0000CCC, MDP_CLK_CTRL0);
357 writel(0xC0000CCC, MDP_CLK_CTRL1);
Dhaval Patel019057a2014-08-12 13:52:25 -0700358 writel(0x00CCCCCC, MDP_CLK_CTRL2);
359 writel(0x000000CC, MDP_CLK_CTRL6);
360 writel(0x0CCCC0C0, MDP_CLK_CTRL3);
361 writel(0xCCCCC0C0, MDP_CLK_CTRL4);
362 writel(0xCCCCC0C0, MDP_CLK_CTRL5);
363 writel(0x00CCC000, MDP_CLK_CTRL7);
364
Dhaval Patel019057a2014-08-12 13:52:25 -0700365 return NO_ERROR;
366}
367
368bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
369{
370 int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
371 bool ret = true;
372
373 ret = gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
374
375 return ret;
376}
377
378void target_display_init(const char *panel_name)
379{
Veera Sundaram Sankaranb620f232014-09-03 22:43:53 -0700380 if ((!strcmp(panel_name, NO_PANEL_CONFIG))
381 || (!strcmp(panel_name, SIM_VIDEO_PANEL))
382 || (!strcmp(panel_name, SIM_DUALDSI_VIDEO_PANEL))) {
383 dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
384 panel_name);
385 return;
386 }
Justin Philipbe9de5c2014-09-17 12:26:49 +0530387 if (gcdb_display_init(panel_name, MDP_REV_50, MIPI_FB_ADDR)) {
388 target_force_cont_splash_disable(true);
Dhaval Patel019057a2014-08-12 13:52:25 -0700389 msm_display_off();
Justin Philipbe9de5c2014-09-17 12:26:49 +0530390 }
Dhaval Patel019057a2014-08-12 13:52:25 -0700391}
392
393void target_display_shutdown(void)
394{
395 gcdb_display_shutdown();
396}