blob: 9af712e24ba9caab2a698df8b236b165953ac0e2 [file] [log] [blame]
Sandeep Pandaae8d68e2014-12-29 20:07:22 +05301/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +05302 *
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>
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +053036#include <pm8x41_wled.h>
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053037#include <board.h>
38#include <mdp3.h>
39#include <scm.h>
40#include <platform/gpio.h>
41#include <platform/iomap.h>
42#include <target/display.h>
Casey Piperd2af07b2015-04-01 18:01:58 -070043#include <regulator.h>
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053044
45#include "include/panel.h"
46#include "include/display_resource.h"
Veera Sundaram Sankaran87f88132015-01-28 11:32:44 -080047#include "gcdb_display.h"
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053048
49#define VCO_DELAY_USEC 1000
50#define GPIO_STATE_LOW 0
51#define GPIO_STATE_HIGH 2
52#define RESET_GPIO_SEQ_LEN 3
53#define PWM_DUTY_US 13
54#define PWM_PERIOD_US 27
Shivaraj Shetty89fc8ed2015-01-23 15:03:35 +053055#define PM8916_VER 0x20000
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053056
57static void mdss_dsi_uniphy_pll_sw_reset_8909(uint32_t pll_base)
58{
59 writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
60 mdelay(1);
61 writel(0x00, pll_base + 0x0068); /* PLL TEST CFG */
62 mdelay(1);
63}
64
Padmanabhan Komanduru048df212015-05-28 15:21:22 +053065static void dsi_pll_toggle_lock_detect_8909(uint32_t pll_base)
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053066{
Padmanabhan Komanduru048df212015-05-28 15:21:22 +053067 writel(0x04, pll_base + 0x0064); /* LKDetect CFG2 */
68 udelay(1);
69 writel(0x05, pll_base + 0x0064); /* LKDetect CFG2 */
70 udelay(512);
71}
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053072
Padmanabhan Komanduru048df212015-05-28 15:21:22 +053073static void dsi_pll_sw_reset_8909(uint32_t pll_base)
74{
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +053075 writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
76 udelay(1);
77 writel(0x00, pll_base + 0x0068); /* PLL TEST CFG */
Padmanabhan Komanduru048df212015-05-28 15:21:22 +053078}
79
80static uint32_t dsi_pll_enable_seq_1_8909(uint32_t pll_base)
81{
82 uint32_t rc;
83
84 dsi_pll_sw_reset_8909(pll_base);
85 /*
86 * Add hardware recommended delays between register writes for
87 * the updates to take effect. These delays are necessary for the
88 * PLL to successfully lock
89 */
90
91 writel(0x34, pll_base + 0x0070); /* CAL CFG1*/
92 writel(0x01, pll_base + 0x0020); /* GLB CFG */
93 writel(0x05, pll_base + 0x0020); /* GLB CFG */
94 writel(0x0f, pll_base + 0x0020); /* GLB CFG */
95 udelay(500);
96
97 dsi_pll_toggle_lock_detect_8909(pll_base);
98 rc = readl(pll_base + 0x00c0) & 0x01;
99
100 return rc;
101}
102
103static uint32_t dsi_pll_enable_seq_2_8909(uint32_t pll_base)
104{
105 uint32_t rc;
106
107 dsi_pll_sw_reset_8909(pll_base);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530108
109 /*
110 * Add hardware recommended delays between register writes for
111 * the updates to take effect. These delays are necessary for the
112 * PLL to successfully lock
113 */
Padmanabhan Komanduru048df212015-05-28 15:21:22 +0530114 writel(0x14, pll_base + 0x0070); /* CAL CFG1*/
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530115 writel(0x01, pll_base + 0x0020); /* GLB CFG */
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530116 writel(0x05, pll_base + 0x0020); /* GLB CFG */
Padmanabhan Komanduru048df212015-05-28 15:21:22 +0530117 udelay(3);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530118 writel(0x0f, pll_base + 0x0020); /* GLB CFG */
Padmanabhan Komanduru048df212015-05-28 15:21:22 +0530119 udelay(500);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530120
Padmanabhan Komanduru048df212015-05-28 15:21:22 +0530121 dsi_pll_toggle_lock_detect_8909(pll_base);
122 rc = readl(pll_base + 0x00c0) & 0x01;
123
124 return rc;
125}
126
127static uint32_t dsi_pll_enable_seq_3_8909(uint32_t pll_base)
128{
129 uint32_t rc;
130
131 dsi_pll_sw_reset_8909(pll_base);
132
133 /*
134 * Add hardware recommended delays between register writes for
135 * the updates to take effect. These delays are necessary for the
136 * PLL to successfully lock
137 */
138 writel(0x04, pll_base + 0x0070); /* CAL CFG1*/
139 writel(0x01, pll_base + 0x0020); /* GLB CFG */
140 writel(0x05, pll_base + 0x0020); /* GLB CFG */
141 udelay(3);
142 writel(0x0f, pll_base + 0x0020); /* GLB CFG */
143 udelay(500);
144
145 dsi_pll_toggle_lock_detect_8909(pll_base);
146 rc = readl(pll_base + 0x00c0) & 0x01;
147
148 return rc;
149}
150
151static uint32_t dsi_pll_enable_seq_8909(uint32_t pll_base)
152{
153 uint32_t pll_locked = 0;
154 uint32_t counter = 0;
155
156 do {
157 pll_locked = dsi_pll_enable_seq_1_8909(pll_base);
158
159 dprintf(SPEW, "TSMC pll locked status is %d\n", pll_locked);
160 ++counter;
161 } while (!pll_locked && (counter < 3));
162
163 if (!pll_locked) {
164 counter = 0;
165 do {
166 pll_locked = dsi_pll_enable_seq_2_8909(pll_base);
167
168 dprintf(SPEW, "GF P1 pll locked status is %d\n",
169 pll_locked);
170 ++counter;
171 } while (!pll_locked && (counter < 3));
172 }
173
174 if (!pll_locked) {
175 counter = 0;
176 do {
177 pll_locked = dsi_pll_enable_seq_3_8909(pll_base);
178
179 dprintf(SPEW, "GF P2 pll locked status is %d\n",
180 pll_locked);
181 ++counter;
182 } while (!pll_locked && (counter < 3));
183 }
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530184
185 return pll_locked;
186}
187
188int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
189{
190 struct pm8x41_mpp mpp;
Shivaraj Shettybe6b6fd2014-12-12 13:48:29 +0530191 uint32_t hw_id = board_hardware_id();
Shivaraj Shetty89fc8ed2015-01-23 15:03:35 +0530192 struct board_pmic_data pmic_info;
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530193 int rc;
194
195 if (bl->bl_interface_type == BL_DCS)
196 return 0;
197
Shivaraj Shetty89fc8ed2015-01-23 15:03:35 +0530198 board_pmic_info(&pmic_info, 1);
199 if (pmic_info.pmic_version == PM8916_VER)
Shivaraj Shettybe6b6fd2014-12-12 13:48:29 +0530200 mpp.base = PM8x41_MMP4_BASE;
201 else
202 mpp.base = PM8x41_MMP2_BASE;
203
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530204 mpp.vin = MPP_VIN0;
205 if (enable) {
206 pm_pwm_enable(false);
207 rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
208 if (rc < 0)
209 mpp.mode = MPP_HIGH;
210 else {
211 mpp.mode = MPP_DTEST1;
212 pm_pwm_enable(true);
213 }
214 pm8x41_config_output_mpp(&mpp);
215 pm8x41_enable_mpp(&mpp, MPP_ENABLE);
216 } else {
217 pm_pwm_enable(false);
218 pm8x41_enable_mpp(&mpp, MPP_DISABLE);
219 }
220 mdelay(20);
Sandeep Pandaae8d68e2014-12-29 20:07:22 +0530221
222 if (enable) {
223 gpio_tlmm_config(bkl_gpio.pin_id, 0,
224 bkl_gpio.pin_direction, bkl_gpio.pin_pull,
225 bkl_gpio.pin_strength, bkl_gpio.pin_state);
226 gpio_set(bkl_gpio.pin_id, 2);
227 }
228
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530229 return 0;
230}
231
232int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
233{
234 int32_t ret = 0;
235 struct mdss_dsi_pll_config *pll_data;
236 dprintf(SPEW, "target_panel_clock\n");
237
238 pll_data = pinfo->mipi.dsi_pll_config;
239 pll_data->vco_delay = VCO_DELAY_USEC;
240
241 if (enable) {
242 mdp_gdsc_ctrl(enable);
243 mdss_bus_clocks_enable();
244 mdp_clock_enable();
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530245
246 /*
247 * Enable auto functional gating
248 * on DSI CMD AXI fetch from DDR
249 */
250 writel(0x3ffff, MDP_CGC_EN);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530251 ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
252 if (ret) {
253 dprintf(CRITICAL,
254 "%s: Failed to restore MDP security configs",
255 __func__);
256 mdp_clock_disable();
257 mdss_bus_clocks_disable();
258 mdp_gdsc_ctrl(0);
259 return ret;
260 }
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700261 mdss_dsi_uniphy_pll_sw_reset_8909(pinfo->mipi.pll_base);
262 mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
Jeevan Shriram2d3500b2014-12-29 16:25:06 -0800263 pinfo->mipi.ctl_base, pll_data);
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700264 if (!dsi_pll_enable_seq_8909(pinfo->mipi.pll_base))
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530265 dprintf(CRITICAL, "Not able to enable the pll\n");
266 gcc_dsi_clocks_enable(pll_data->pclk_m,
267 pll_data->pclk_n,
268 pll_data->pclk_d);
269 } else if(!target_cont_splash_screen()) {
270 gcc_dsi_clocks_disable();
271 mdp_clock_disable();
272 mdss_bus_clocks_disable();
273 mdp_gdsc_ctrl(enable);
274 }
275
276 return 0;
277}
278
279int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
280 struct msm_panel_info *pinfo)
281{
282 int ret = NO_ERROR;
283 uint32_t hw_id = board_hardware_id();
284 uint32_t hw_subtype = board_hardware_subtype();
285
286 if (enable) {
287 if (pinfo->mipi.use_enable_gpio) {
288 gpio_tlmm_config(enable_gpio.pin_id, 0,
289 enable_gpio.pin_direction, enable_gpio.pin_pull,
290 enable_gpio.pin_strength,
291 enable_gpio.pin_state);
292
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530293 gpio_set(enable_gpio.pin_id, 2);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530294 }
295
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530296 gpio_tlmm_config(reset_gpio.pin_id, 0,
297 reset_gpio.pin_direction, reset_gpio.pin_pull,
298 reset_gpio.pin_strength, reset_gpio.pin_state);
299
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530300 gpio_set(reset_gpio.pin_id, 2);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530301
302 /* reset */
303 for (int i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
304 if (resetseq->pin_state[i] == GPIO_STATE_LOW)
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530305 gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530306 else
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530307 gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530308 mdelay(resetseq->sleep[i]);
309 }
310 } else if(!target_cont_splash_screen()) {
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530311 gpio_set(reset_gpio.pin_id, 0);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530312 if (pinfo->mipi.use_enable_gpio)
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530313 gpio_set(enable_gpio.pin_id, 0);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530314 }
315
316 return ret;
317}
318
Veera Sundaram Sankaran87f88132015-01-28 11:32:44 -0800319int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530320{
Shivaraj Shetty01734d32014-11-20 12:24:01 +0530321 if (enable)
Casey Piperd2af07b2015-04-01 18:01:58 -0700322 regulator_enable(REG_LDO2 | REG_LDO6 | REG_LDO17);
Shivaraj Shetty01734d32014-11-20 12:24:01 +0530323
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530324 return NO_ERROR;
325}
326
Dhaval Patel7709c412015-05-12 10:09:41 -0700327int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
328{
329 memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
330 memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
331 memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
332 memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
333 memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
334 return NO_ERROR;
335}
336
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530337bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
338{
Shivaraj Shettyaf4c6072014-11-04 16:25:31 +0530339 return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530340}
341
342void target_display_init(const char *panel_name)
343{
344 uint32_t panel_loop = 0;
345 uint32_t ret = 0;
Veera Sundaram Sankaran7868d542015-01-02 14:48:47 -0800346 char cont_splash = '\0';
347
348 set_panel_cmd_string(panel_name, &cont_splash);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530349
Sandeep Panda63933f92014-11-26 19:13:44 +0530350 panel_name += strspn(panel_name, " ");
351 if (!strcmp(panel_name, NO_PANEL_CONFIG)
352 || !strcmp(panel_name, SIM_VIDEO_PANEL)
353 || !strcmp(panel_name, SIM_CMD_PANEL)) {
354 dprintf(INFO, "Selected %s: Skip panel configuration\n",
355 panel_name);
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530356 return;
357 }
358
359 do {
360 target_force_cont_splash_disable(false);
361 ret = gcdb_display_init(panel_name, MDP_REV_305, MIPI_FB_ADDR);
362 if (!ret || ret == ERR_NOT_SUPPORTED) {
363 break;
364 } else {
365 target_force_cont_splash_disable(true);
366 msm_display_off();
367 }
368 } while (++panel_loop <= oem_panel_max_auto_detect_panels());
Veera Sundaram Sankaran7868d542015-01-02 14:48:47 -0800369
370 if (cont_splash == '0') {
371 dprintf(INFO, "Forcing continuous splash disable\n");
372 target_force_cont_splash_disable(true);
373 }
Shivaraj Shettyf9e10c42014-09-17 04:21:15 +0530374}
375
376void target_display_shutdown(void)
377{
378 gcdb_display_shutdown();
379}