blob: 3aa23792cb8ffd7b8fd3843f72f2337f972e8ba0 [file] [log] [blame]
Kuogee Hsiehdf961742013-12-18 14:13:45 -08001/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Dhaval Patelf9986272013-10-18 19:06:05 -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>
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 <board.h>
38#include <mdp5.h>
Dhaval Patel914e8db2014-04-16 12:07:13 -070039#include <scm.h>
Dhaval Patelf9986272013-10-18 19:06:05 -070040#include <endian.h>
41#include <platform/gpio.h>
42#include <platform/clock.h>
43#include <platform/iomap.h>
44#include <target/display.h>
45#include "include/panel.h"
46#include "include/display_resource.h"
47
48#define HFPLL_LDO_ID 12
49
50#define GPIO_STATE_LOW 0
51#define GPIO_STATE_HIGH 2
52#define RESET_GPIO_SEQ_LEN 3
53
Kuogee Hsiehacc31942014-06-17 15:12:10 -070054static struct backlight edp_bklt = {
55 0, 1, 4095, 100, 1, "PMIC_8941"
56};
57
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053058static uint32_t dsi_pll_lock_status(uint32_t pll_base)
Dhaval Patelf9986272013-10-18 19:06:05 -070059{
Dhaval Patelbb408712014-03-18 11:45:53 -070060 uint32_t counter, status;
Dhaval Patelf9986272013-10-18 19:06:05 -070061
Dhaval Patelbb408712014-03-18 11:45:53 -070062 udelay(100);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053063 mdss_dsi_uniphy_pll_lock_detect_setting(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -070064
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053065 status = readl(pll_base + 0x00c0) & 0x01;
Dhaval Patelbb408712014-03-18 11:45:53 -070066 for (counter = 0; counter < 5 && !status; counter++) {
67 udelay(100);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053068 status = readl(pll_base + 0x00c0) & 0x01;
Dhaval Patelbb408712014-03-18 11:45:53 -070069 }
70
71 return status;
72}
73
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053074static uint32_t dsi_pll_enable_seq_b(uint32_t pll_base)
Dhaval Patelbb408712014-03-18 11:45:53 -070075{
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053076 mdss_dsi_uniphy_pll_sw_reset(pll_base);
Dhaval Patelf9986272013-10-18 19:06:05 -070077
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053078 writel(0x01, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070079 udelay(1);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053080 writel(0x05, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070081 udelay(200);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053082 writel(0x07, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070083 udelay(500);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053084 writel(0x0f, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070085 udelay(500);
Dhaval Patelf9986272013-10-18 19:06:05 -070086
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053087 return dsi_pll_lock_status(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -070088}
Dhaval Patelf9986272013-10-18 19:06:05 -070089
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053090static uint32_t dsi_pll_enable_seq_d(uint32_t pll_base)
Dhaval Patelbb408712014-03-18 11:45:53 -070091{
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053092 mdss_dsi_uniphy_pll_sw_reset(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -070093
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053094 writel(0x01, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070095 udelay(1);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053096 writel(0x05, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070097 udelay(200);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053098 writel(0x07, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -070099 udelay(250);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530100 writel(0x05, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -0700101 udelay(200);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530102 writel(0x07, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -0700103 udelay(500);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530104 writel(0x0f, pll_base + 0x0020); /* GLB CFG */
Dhaval Patelbb408712014-03-18 11:45:53 -0700105 udelay(500);
106
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530107 return dsi_pll_lock_status(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -0700108}
109
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530110static void dsi_pll_enable_seq(uint32_t pll_base)
Dhaval Patelbb408712014-03-18 11:45:53 -0700111{
112 uint32_t counter, status;
113
114 for (counter = 0; counter < 3; counter++) {
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530115 status = dsi_pll_enable_seq_b(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -0700116 if (status)
117 break;
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530118 status = dsi_pll_enable_seq_d(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -0700119 if (status)
120 break;
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530121 status = dsi_pll_enable_seq_d(pll_base);
Dhaval Patelbb408712014-03-18 11:45:53 -0700122 if(status)
123 break;
Dhaval Patelf9986272013-10-18 19:06:05 -0700124 }
Dhaval Patelbb408712014-03-18 11:45:53 -0700125
126 if (!status)
127 dprintf(CRITICAL, "Pll lock sequence failed\n");
Dhaval Patelf9986272013-10-18 19:06:05 -0700128}
129
Kuogee Hsiehdf961742013-12-18 14:13:45 -0800130int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
Dhaval Patelf9986272013-10-18 19:06:05 -0700131{
132 struct pm8x41_gpio pwmgpio_param = {
133 .direction = PM_GPIO_DIR_OUT,
134 .function = PM_GPIO_FUNC_1,
135 .vin_sel = 2, /* VIN_2 */
136 .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10,
137 .output_buffer = PM_GPIO_OUT_CMOS,
138 .out_strength = 0x03,
139 };
Kuogee Hsiehdf961742013-12-18 14:13:45 -0800140
Dhaval Patelf9986272013-10-18 19:06:05 -0700141 if (enable) {
Dhaval Patel499b7d22014-01-07 21:57:30 -0800142 pm8x41_gpio_config(pwm_gpio.pin_id, &pwmgpio_param);
Dhaval Patelf9986272013-10-18 19:06:05 -0700143
Kuogee Hsiehacc31942014-06-17 15:12:10 -0700144 /* lpg channel 3 */
Dhaval Patel499b7d22014-01-07 21:57:30 -0800145 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */
146 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */
147 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */
148 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x44, 0xcc); /* LPG_VALUE_LSB */
149 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x45, 0x00); /* LPG_VALUE_MSB */
150 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */
Dhaval Patelf9986272013-10-18 19:06:05 -0700151 } else {
Dhaval Patel499b7d22014-01-07 21:57:30 -0800152 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x46, 0x0); /* LPG_ENABLE_CONTROL */
Dhaval Patelf9986272013-10-18 19:06:05 -0700153 }
154
155 return NO_ERROR;
156}
157
158int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
159{
Dhaval Patel914e8db2014-04-16 12:07:13 -0700160 uint32_t ret;
Dhaval Patelf9986272013-10-18 19:06:05 -0700161 struct mdss_dsi_pll_config *pll_data;
162 uint32_t dual_dsi = pinfo->mipi.dual_dsi;
163 dprintf(SPEW, "target_panel_clock\n");
164
165 pll_data = pinfo->mipi.dsi_pll_config;
166 if (enable) {
167 mdp_gdsc_ctrl(enable);
168 mmss_bus_clock_enable();
169 mdp_clock_enable();
Dhaval Patel914e8db2014-04-16 12:07:13 -0700170 ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
171 if (ret) {
172 dprintf(CRITICAL,
173 "%s: Failed to restore MDP security configs",
174 __func__);
175 mdp_clock_disable();
176 mmss_bus_clock_disable();
177 mdp_gdsc_ctrl(0);
178 return ret;
179 }
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530180 mdss_dsi_auto_pll_config(DSI0_PLL_BASE,
181 MIPI_DSI0_BASE, pll_data);
182 dsi_pll_enable_seq(DSI0_PLL_BASE);
Dhaval Patelf9986272013-10-18 19:06:05 -0700183 mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi,
184 pll_data->pclk_m,
185 pll_data->pclk_n,
186 pll_data->pclk_d);
187 } else if(!target_cont_splash_screen()) {
188 /* Disable clocks if continuous splash off */
Dhaval Patelf14af122013-10-29 12:48:41 -0700189 mmss_dsi_clock_disable(dual_dsi);
Dhaval Patelf9986272013-10-18 19:06:05 -0700190 mdp_clock_disable();
191 mmss_bus_clock_disable();
192 mdp_gdsc_ctrl(enable);
193 }
194
195 return NO_ERROR;
196}
197
198/* Pull DISP_RST_N high to get panel out of reset */
199int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
200 struct msm_panel_info *pinfo)
201{
202 uint32_t i = 0;
203
204 if (enable) {
205 gpio_tlmm_config(reset_gpio.pin_id, 0,
206 reset_gpio.pin_direction, reset_gpio.pin_pull,
207 reset_gpio.pin_strength, reset_gpio.pin_state);
208
209 gpio_tlmm_config(enable_gpio.pin_id, 0,
210 enable_gpio.pin_direction, enable_gpio.pin_pull,
211 enable_gpio.pin_strength, enable_gpio.pin_state);
212
213 gpio_tlmm_config(bkl_gpio.pin_id, 0,
214 bkl_gpio.pin_direction, bkl_gpio.pin_pull,
215 bkl_gpio.pin_strength, bkl_gpio.pin_state);
216
217 gpio_set(enable_gpio.pin_id, 2);
218 gpio_set(bkl_gpio.pin_id, 2);
219 /* reset */
220 for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
221 if (resetseq->pin_state[i] == GPIO_STATE_LOW)
222 gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
223 else
224 gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
225 mdelay(resetseq->sleep[i]);
226 }
227 } else {
228 gpio_set(reset_gpio.pin_id, 0);
229 gpio_set(enable_gpio.pin_id, 0);
230 gpio_set(bkl_gpio.pin_id, 0);
231 }
232
233 return NO_ERROR;
234}
235
236int target_ldo_ctrl(uint8_t enable)
237{
238 uint32_t ldocounter = 0;
239 uint32_t pm8x41_ldo_base = 0x13F00;
240
241 while (ldocounter < TOTAL_LDO_DEFINED) {
242 struct pm8x41_ldo ldo_entry = LDO((pm8x41_ldo_base +
243 0x100 * ldo_entry_array[ldocounter].ldo_id),
244 ldo_entry_array[ldocounter].ldo_type);
245
246 dprintf(SPEW, "Setting %s\n",
247 ldo_entry_array[ldocounter].ldo_id);
248
249 /* Set voltage during power on */
250 if (enable) {
251 pm8x41_ldo_set_voltage(&ldo_entry,
252 ldo_entry_array[ldocounter].ldo_voltage);
253 pm8x41_ldo_control(&ldo_entry, enable);
254 } else if(ldo_entry_array[ldocounter].ldo_id != HFPLL_LDO_ID) {
255 pm8x41_ldo_control(&ldo_entry, enable);
256 }
257 ldocounter++;
258 }
259
260 return NO_ERROR;
261}
262
Dhaval Patelab2de892013-10-25 10:40:58 -0700263int target_display_pre_on()
264{
265 writel(0x000000FA, MDP_QOS_REMAPPER_CLASS_0);
266 writel(0x00000055, MDP_QOS_REMAPPER_CLASS_1);
267 writel(0xC0000CCD, MDP_CLK_CTRL0);
268 writel(0xD0000CCC, MDP_CLK_CTRL1);
269 writel(0x00CCCCCC, MDP_CLK_CTRL2);
270 writel(0x000000CC, MDP_CLK_CTRL6);
271 writel(0x0CCCC0C0, MDP_CLK_CTRL3);
272 writel(0xCCCCC0C0, MDP_CLK_CTRL4);
273 writel(0xCCCCC0C0, MDP_CLK_CTRL5);
274 writel(0x00CCC000, MDP_CLK_CTRL7);
275
Dhaval Patelab2de892013-10-25 10:40:58 -0700276 writel(0x00080808, VBIF_VBIF_IN_RD_LIM_CONF0);
277 writel(0x08000808, VBIF_VBIF_IN_RD_LIM_CONF1);
278 writel(0x00080808, VBIF_VBIF_IN_RD_LIM_CONF2);
279 writel(0x00000808, VBIF_VBIF_IN_RD_LIM_CONF3);
280 writel(0x10000000, VBIF_VBIF_IN_WR_LIM_CONF0);
281 writel(0x00100000, VBIF_VBIF_IN_WR_LIM_CONF1);
282 writel(0x10000000, VBIF_VBIF_IN_WR_LIM_CONF2);
283 writel(0x00000000, VBIF_VBIF_IN_WR_LIM_CONF3);
284 writel(0x00013fff, VBIF_VBIF_ABIT_SHORT);
285 writel(0x000000A4, VBIF_VBIF_ABIT_SHORT_CONF);
286 writel(0x00003FFF, VBIF_VBIF_GATE_OFF_WRREQ_EN);
287 writel(0x00000003, VBIF_VBIF_DDR_RND_RBN_QOS_ARB);
288
289 return NO_ERROR;
290}
291
Kuogee Hsiehacc31942014-06-17 15:12:10 -0700292void target_edp_panel_init(struct msm_panel_info *pinfo)
293{
294 edp_panel_init(pinfo);
295}
296
297int target_edp_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
298{
299 uint32_t ret;
300
301 dprintf(SPEW, "%s: target_panel_clock\n", __func__);
302
303 if (enable) {
304 mdp_gdsc_ctrl(enable);
305 mmss_bus_clock_enable();
306 mdp_clock_enable();
307 ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
308 if (ret) {
309 dprintf(CRITICAL,
310 "%s: Failed to restore MDP security configs",
311 __func__);
312 mdp_clock_disable();
313 mmss_bus_clock_disable();
314 mdp_gdsc_ctrl(0);
315 return ret;
316 }
317
318 edp_clk_enable();
319 } else if(!target_cont_splash_screen()) {
320 /* Disable clocks if continuous splash off */
321 edp_clk_disable();
322 mdp_clock_disable();
323 mmss_bus_clock_disable();
324 mdp_gdsc_ctrl(enable);
325 }
326
327 return NO_ERROR;
328}
329
330int target_edp_panel_enable(void)
331{
332 gpio_tlmm_config(enable_gpio.pin_id, 0, /* gpio 137 */
333 enable_gpio.pin_direction, enable_gpio.pin_pull,
334 enable_gpio.pin_strength, enable_gpio.pin_state);
335
336
337 gpio_tlmm_config(edp_hpd_gpio.pin_id, 0, /* hpd 103 */
338 edp_hpd_gpio.pin_direction, edp_hpd_gpio.pin_pull,
339 edp_hpd_gpio.pin_strength, edp_hpd_gpio.pin_state);
340
341
342 gpio_tlmm_config(edp_lvl_en_gpio.pin_id, 0, /* lvl_en 91 */
343 edp_lvl_en_gpio.pin_direction, edp_lvl_en_gpio.pin_pull,
344 edp_lvl_en_gpio.pin_strength, edp_lvl_en_gpio.pin_state);
345
346 gpio_set(enable_gpio.pin_id, 2);
347 gpio_set(edp_lvl_en_gpio.pin_id, 2);
348
349 return NO_ERROR;
350}
351
352int target_edp_panel_disable(void)
353{
354 gpio_set(edp_lvl_en_gpio.pin_id, 0);
355 gpio_set(enable_gpio.pin_id, 0);
356
357 return NO_ERROR;
358}
359
360int target_edp_bl_ctrl(int enable)
361{
362 return target_backlight_ctrl(&edp_bklt, enable);
363}
364
Ajay Singh Parmareef1d602014-03-15 17:41:52 -0700365bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
366{
367 int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
368 bool ret = true;
369
370 panel_name += strspn(panel_name, " ");
371
372 if (!strcmp(panel_name, HDMI_PANEL_NAME)) {
373 if (buf_size < (prefix_string_len + LK_OVERRIDE_PANEL_LEN +
374 HDMI_CONTROLLER_STRING)) {
375 dprintf(CRITICAL, "command line argument is greater than buffer size\n");
376 return false;
377 }
378
379 strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
380 buf_size -= prefix_string_len;
381 strlcat(pbuf, LK_OVERRIDE_PANEL, buf_size);
382 buf_size -= LK_OVERRIDE_PANEL_LEN;
383 strlcat(pbuf, HDMI_CONTROLLER_STRING, buf_size);
384 } else {
385 ret = gcdb_display_cmdline_arg(pbuf, buf_size);
386 }
387
388 return ret;
389}
390
Aravind Venkateswaran6385f7e2014-02-25 16:45:11 -0800391void target_display_init(const char *panel_name)
Dhaval Patelf9986272013-10-18 19:06:05 -0700392{
393 uint32_t ret = 0;
Ajay Singh Parmareef1d602014-03-15 17:41:52 -0700394
395 panel_name += strspn(panel_name, " ");
396
Jeevan Shriramb0d523a2014-05-30 12:55:17 -0700397 if (!strcmp(panel_name, NO_PANEL_CONFIG)) {
398 dprintf(INFO, "Skip panel configuration\n");
399 return;
400 }
401
Ajay Singh Parmareef1d602014-03-15 17:41:52 -0700402 if (!strcmp(panel_name, HDMI_PANEL_NAME)) {
403 dprintf(INFO, "%s: HDMI is primary\n", __func__);
404 return;
405 }
406
Aravind Venkateswarand494f962014-02-25 17:16:49 -0800407 ret = gcdb_display_init(panel_name, MDP_REV_50, MIPI_FB_ADDR);
Dhaval Patelf9986272013-10-18 19:06:05 -0700408 if (ret) {
409 msm_display_off();
410 }
411}
412
Aravind Venkateswarandd50c1a2014-02-25 14:42:43 -0800413void target_display_shutdown(void)
Dhaval Patelf9986272013-10-18 19:06:05 -0700414{
415 gcdb_display_shutdown();
416}