blob: 1b2b0f9346fe6501f86f4e9ba9102ceec88aeb26 [file] [log] [blame]
Ray Zhang743e5032013-05-25 23:25:39 +08001/* Copyright (c) 2013, 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>
Arpita Banerjeec5f78df2013-05-24 15:43:40 -070032#include <err.h>
Ray Zhang743e5032013-05-25 23:25:39 +080033#include <msm_panel.h>
Arpita Banerjee0906ffd2013-05-24 16:25:38 -070034#include <mipi_dsi.h>
Ray Zhang743e5032013-05-25 23:25:39 +080035#include <pm8x41.h>
36#include <pm8x41_wled.h>
37#include <board.h>
38#include <mdp5.h>
39#include <platform/gpio.h>
40#include <platform/iomap.h>
41#include <target/display.h>
42
Casey Pipercbdfbd22013-08-14 17:22:16 -070043#include "include/panel.h"
Arpita Banerjeec5f78df2013-05-24 15:43:40 -070044#include "include/display_resource.h"
Ray Zhang743e5032013-05-25 23:25:39 +080045
Dhaval Patel815567c2013-07-31 11:13:25 -070046#define HFPLL_LDO_ID 8
47
Ray Zhang743e5032013-05-25 23:25:39 +080048static struct pm8x41_wled_data wled_ctrl = {
rayzhanga3667cd2013-07-01 12:22:54 +080049 .mod_scheme = 0x00,
Ray Zhang743e5032013-05-25 23:25:39 +080050 .led1_brightness = (0x0F << 8) | 0xEF,
Ray Zhang743e5032013-05-25 23:25:39 +080051 .max_duty_cycle = 0x01,
rayzhanga3667cd2013-07-01 12:22:54 +080052 .ovp = 0x0,
Zhenhua Huangd5355cb2013-09-04 16:03:01 +080053 .full_current_scale = 0x19,
54 .fdbck = 0x1
Ray Zhang743e5032013-05-25 23:25:39 +080055};
56
Casey Piper992edde2013-08-26 11:14:02 -070057static uint32_t dsi_pll_enable_seq_m(uint32_t ctl_base)
58{
59 uint32_t i = 0;
60 uint32_t pll_locked = 0;
61
62 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
63
64 /*
65 * Add hardware recommended delays between register writes for
66 * the updates to take effect. These delays are necessary for the
67 * PLL to successfully lock
68 */
69 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
70 udelay(200);
71 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
72 udelay(200);
73 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
74 udelay(1000);
75
76 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
77 pll_locked = readl(ctl_base + 0x02c0) & 0x01;
78 for (i = 0; (i < 4) && !pll_locked; i++) {
79 writel(0x07, ctl_base + 0x0220); /* GLB CFG */
80 if (i != 0)
81 writel(0x34, ctl_base + 0x00270); /* CAL CFG1*/
82 udelay(1);
83 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
84 udelay(1000);
85 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
86 pll_locked = readl(ctl_base + 0x02c0) & 0x01;
87 }
88
89 return pll_locked;
90}
91
92static uint32_t dsi_pll_enable_seq_d(uint32_t ctl_base)
93{
94 uint32_t pll_locked = 0;
95
96 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
97
98 /*
99 * Add hardware recommended delays between register writes for
100 * the updates to take effect. These delays are necessary for the
101 * PLL to successfully lock
102 */
103 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
104 udelay(200);
105 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
106 udelay(200);
107 writel(0x07, ctl_base + 0x0220); /* GLB CFG */
108 udelay(200);
109 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
110 udelay(200);
111 writel(0x07, ctl_base + 0x0220); /* GLB CFG */
112 udelay(200);
113 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
114 udelay(1000);
115
116 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
117 pll_locked = readl(ctl_base + 0x02c0) & 0x01;
118
119 return pll_locked;
120}
121
122static uint32_t dsi_pll_enable_seq_f1(uint32_t ctl_base)
123{
124 uint32_t pll_locked = 0;
125
126 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
127
128 /*
129 * Add hardware recommended delays between register writes for
130 * the updates to take effect. These delays are necessary for the
131 * PLL to successfully lock
132 */
133 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
134 udelay(200);
135 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
136 udelay(200);
137 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
138 udelay(200);
139 writel(0x0d, ctl_base + 0x0220); /* GLB CFG */
140 udelay(200);
141 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
142 udelay(1000);
143
144 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
145 pll_locked = readl(ctl_base + 0x02c0) & 0x01;
146
147 return pll_locked;
148}
149
150static uint32_t dsi_pll_enable_seq_c(uint32_t ctl_base)
151{
152 uint32_t pll_locked = 0;
153
154 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
155
156 /*
157 * Add hardware recommended delays between register writes for
158 * the updates to take effect. These delays are necessary for the
159 * PLL to successfully lock
160 */
161 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
162 udelay(200);
163 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
164 udelay(200);
165 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
166 udelay(1000);
167
168 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
169 pll_locked = readl(ctl_base + 0x02c0) & 0x01;
170
171 return pll_locked;
172}
173
174static uint32_t dsi_pll_enable_seq_e(uint32_t ctl_base)
175{
176 uint32_t pll_locked = 0;
177
178 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
179
180 /*
181 * Add hardware recommended delays between register writes for
182 * the updates to take effect. These delays are necessary for the
183 * PLL to successfully lock
184 */
185 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
186 udelay(200);
187 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
188 udelay(200);
189 writel(0x0d, ctl_base + 0x0220); /* GLB CFG */
190 udelay(1);
191 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
192 udelay(1000);
193
194 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
195 pll_locked = readl(ctl_base + 0x02c0) & 0x01;
196
197 return pll_locked;
198}
199
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700200int target_backlight_ctrl(uint8_t enable)
Ray Zhang743e5032013-05-25 23:25:39 +0800201{
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700202 dprintf(SPEW, "target_backlight_ctrl\n");
203
Ray Zhang743e5032013-05-25 23:25:39 +0800204 pm8x41_wled_config(&wled_ctrl);
205 pm8x41_wled_sink_control(1);
206 pm8x41_wled_iled_sync_control(1);
207 pm8x41_wled_enable(1);
208
209 return 0;
210}
211
Casey Piper992edde2013-08-26 11:14:02 -0700212static void dsi_pll_enable_seq(uint32_t ctl_base)
213{
214 if (dsi_pll_enable_seq_m(ctl_base)) {
215 } else if (dsi_pll_enable_seq_d(ctl_base)) {
216 } else if (dsi_pll_enable_seq_d(ctl_base)) {
217 } else if (dsi_pll_enable_seq_f1(ctl_base)) {
218 } else if (dsi_pll_enable_seq_c(ctl_base)) {
219 } else if (dsi_pll_enable_seq_e(ctl_base)) {
220 } else {
221 dprintf(CRITICAL, "Not able to enable the pll\n");
222 }
223}
224
Arpita Banerjee0906ffd2013-05-24 16:25:38 -0700225int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
Ray Zhang743e5032013-05-25 23:25:39 +0800226{
Arpita Banerjee0906ffd2013-05-24 16:25:38 -0700227 struct mdss_dsi_pll_config *pll_data;
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700228 dprintf(SPEW, "target_panel_clock\n");
Ray Zhang743e5032013-05-25 23:25:39 +0800229
Arpita Banerjee0906ffd2013-05-24 16:25:38 -0700230 pll_data = pinfo->mipi.dsi_pll_config;
231
Ray Zhang743e5032013-05-25 23:25:39 +0800232 if (enable) {
233 mdp_gdsc_ctrl(enable);
Aravind Venkateswaran24406c02013-09-19 15:13:43 -0700234 mmss_bus_clocks_enable();
235 mdp_clock_enable();
Casey Piper992edde2013-08-26 11:14:02 -0700236 mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data);
237 dsi_pll_enable_seq(MIPI_DSI0_BASE);
Aravind Venkateswaran24406c02013-09-19 15:13:43 -0700238 mmss_dsi_clocks_enable(pll_data->pclk_m,
Arpita Banerjee0906ffd2013-05-24 16:25:38 -0700239 pll_data->pclk_n,
240 pll_data->pclk_d);
Ray Zhang743e5032013-05-25 23:25:39 +0800241 } else if(!target_cont_splash_screen()) {
Aravind Venkateswaran24406c02013-09-19 15:13:43 -0700242 mmss_dsi_clocks_disable();
243 mdp_clock_disable();
244 mmss_bus_clocks_disable();
245 mdp_gdsc_ctrl(enable);
Ray Zhang743e5032013-05-25 23:25:39 +0800246 }
247
248 return 0;
249}
250
Dhaval Patel7a349562013-08-08 20:43:52 -0700251int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
252 struct msm_panel_info *pinfo)
Ray Zhang743e5032013-05-25 23:25:39 +0800253{
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700254 int ret = NO_ERROR;
Ray Zhang743e5032013-05-25 23:25:39 +0800255 if (enable) {
Dhaval Patel7a349562013-08-08 20:43:52 -0700256 gpio_tlmm_config(reset_gpio.pin_id, 0,
257 reset_gpio.pin_direction, reset_gpio.pin_pull,
258 reset_gpio.pin_strength, reset_gpio.pin_state);
Ray Zhang743e5032013-05-25 23:25:39 +0800259
Dhaval Patel7a349562013-08-08 20:43:52 -0700260 gpio_set_dir(reset_gpio.pin_id, 2);
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700261
Dhaval Patel7a349562013-08-08 20:43:52 -0700262 gpio_set_value(reset_gpio.pin_id, resetseq->pin_state[0]);
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700263 mdelay(resetseq->sleep[0]);
Dhaval Patel7a349562013-08-08 20:43:52 -0700264 gpio_set_value(reset_gpio.pin_id, resetseq->pin_state[1]);
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700265 mdelay(resetseq->sleep[1]);
Dhaval Patel7a349562013-08-08 20:43:52 -0700266 gpio_set_value(reset_gpio.pin_id, resetseq->pin_state[2]);
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700267 mdelay(resetseq->sleep[2]);
Ray Zhang743e5032013-05-25 23:25:39 +0800268 } else if(!target_cont_splash_screen()) {
Dhaval Patel7a349562013-08-08 20:43:52 -0700269 gpio_set_value(reset_gpio.pin_id, 0);
Ray Zhang743e5032013-05-25 23:25:39 +0800270 }
271
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700272 return ret;
Ray Zhang743e5032013-05-25 23:25:39 +0800273}
274
Dhaval Patel7a349562013-08-08 20:43:52 -0700275int target_ldo_ctrl(uint8_t enable)
Ray Zhang743e5032013-05-25 23:25:39 +0800276{
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700277 uint32_t ret = NO_ERROR;
278 uint32_t ldocounter = 0;
279 uint32_t pm8x41_ldo_base = 0x13F00;
Ray Zhang743e5032013-05-25 23:25:39 +0800280
Dhaval Patel7a349562013-08-08 20:43:52 -0700281 while (ldocounter < TOTAL_LDO_DEFINED) {
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700282 struct pm8x41_ldo ldo_entry = LDO((pm8x41_ldo_base +
283 0x100 * ldo_entry_array[ldocounter].ldo_id),
284 ldo_entry_array[ldocounter].ldo_type);
Ray Zhang743e5032013-05-25 23:25:39 +0800285
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700286 dprintf(SPEW, "Setting %s\n",
287 ldo_entry_array[ldocounter].ldo_id);
Ray Zhang743e5032013-05-25 23:25:39 +0800288
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700289 /* Set voltage during power on */
Dhaval Patel815567c2013-07-31 11:13:25 -0700290 if (enable) {
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700291 pm8x41_ldo_set_voltage(&ldo_entry,
292 ldo_entry_array[ldocounter].ldo_voltage);
Dhaval Patel815567c2013-07-31 11:13:25 -0700293
294 pm8x41_ldo_control(&ldo_entry, enable);
295
296 } else if(!target_cont_splash_screen() &&
297 ldo_entry_array[ldocounter].ldo_id != HFPLL_LDO_ID) {
298 pm8x41_ldo_control(&ldo_entry, enable);
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700299 }
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700300 ldocounter++;
Ray Zhang743e5032013-05-25 23:25:39 +0800301 }
302
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700303 return ret;
Ray Zhang743e5032013-05-25 23:25:39 +0800304}
305
306void display_init(void)
307{
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700308 gcdb_display_init(MDP_REV_50, MIPI_FB_ADDR);
Ray Zhang743e5032013-05-25 23:25:39 +0800309}
310
311void display_shutdown(void)
312{
Arpita Banerjeec5f78df2013-05-24 15:43:40 -0700313 gcdb_display_shutdown();
Ray Zhang743e5032013-05-25 23:25:39 +0800314}