blob: 9e23255a2af42c3b881474bd8eb1f1fb2382cfe0 [file] [log] [blame]
Sandeep Panda0ce96e92015-05-13 12:24:10 +05301/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
Shashank Mittal4bfb2e32012-04-16 10:56:27 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * 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
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -080012 * * Neither the name of The Linux Foundation nor the names of its
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070013 * 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 "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#include <debug.h>
30#include <reg.h>
31#include <mipi_dsi.h>
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070032#include <platform/iomap.h>
33
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -070034#if (DISPLAY_TYPE_MDSS == 0)
35#define MIPI_DSI0_BASE MIPI_DSI_BASE
36#define MIPI_DSI1_BASE MIPI_DSI_BASE
37#endif
38
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070039static void mipi_dsi_calibration(void)
40{
41 uint32_t i = 0;
42 uint32_t term_cnt = 5000;
43 int32_t cal_busy = readl(MIPI_DSI_BASE + 0x550);
44
45 /* DSI1_DSIPHY_REGULATOR_CAL_PWR_CFG */
46 writel(0x01, MIPI_DSI_BASE + 0x0518);
47
48 /* DSI1_DSIPHY_CAL_SW_CFG2 */
49 writel(0x0, MIPI_DSI_BASE + 0x0534);
50 /* DSI1_DSIPHY_CAL_HW_CFG1 */
51 writel(0x5a, MIPI_DSI_BASE + 0x053c);
52 /* DSI1_DSIPHY_CAL_HW_CFG3 */
53 writel(0x10, MIPI_DSI_BASE + 0x0544);
54 /* DSI1_DSIPHY_CAL_HW_CFG4 */
55 writel(0x01, MIPI_DSI_BASE + 0x0548);
56 /* DSI1_DSIPHY_CAL_HW_CFG0 */
57 writel(0x01, MIPI_DSI_BASE + 0x0538);
58
59 /* DSI1_DSIPHY_CAL_HW_TRIGGER */
60 writel(0x01, MIPI_DSI_BASE + 0x0528);
61
62 /* DSI1_DSIPHY_CAL_HW_TRIGGER */
63 writel(0x00, MIPI_DSI_BASE + 0x0528);
64
65 cal_busy = readl(MIPI_DSI_BASE + 0x550);
66 while (cal_busy & 0x10) {
67 i++;
68 if (i > term_cnt) {
69 dprintf(CRITICAL, "DSI1 PHY REGULATOR NOT READY,"
70 "exceeded polling TIMEOUT!\n");
71 break;
72 }
73 cal_busy = readl(MIPI_DSI_BASE + 0x550);
74 }
75}
76
77int mipi_dsi_phy_init(struct mipi_dsi_panel_config *pinfo)
78{
79 struct mipi_dsi_phy_ctrl *pd;
80 uint32_t i, off = 0;
Channagoud Kadabi539ef722012-03-29 16:02:50 +053081 int mdp_rev;
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070082
Channagoud Kadabi539ef722012-03-29 16:02:50 +053083 mdp_rev = mdp_get_revision();
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070084
Channagoud Kadabi539ef722012-03-29 16:02:50 +053085 if (MDP_REV_303 == mdp_rev || MDP_REV_41 == mdp_rev) {
86 writel(0x00000001, DSIPHY_SW_RESET);
87 writel(0x00000000, DSIPHY_SW_RESET);
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070088
Channagoud Kadabi539ef722012-03-29 16:02:50 +053089 pd = (pinfo->dsi_phy_config);
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070090
Channagoud Kadabi539ef722012-03-29 16:02:50 +053091 off = 0x02cc; /* regulator ctrl 0 */
92 for (i = 0; i < 4; i++) {
93 writel(pd->regulator[i], MIPI_DSI_BASE + off);
94 off += 4;
95 }
Shashank Mittal4bfb2e32012-04-16 10:56:27 -070096
Channagoud Kadabi539ef722012-03-29 16:02:50 +053097 off = 0x0260; /* phy timig ctrl 0 */
98 for (i = 0; i < 11; i++) {
99 writel(pd->timing[i], MIPI_DSI_BASE + off);
100 off += 4;
101 }
Shashank Mittal4bfb2e32012-04-16 10:56:27 -0700102
Channagoud Kadabi539ef722012-03-29 16:02:50 +0530103 /* T_CLK_POST, T_CLK_PRE for CLK lane P/N HS 200 mV timing
104 length should > data lane HS timing length */
105 writel(0xa1e, DSI_CLKOUT_TIMING_CTRL);
Shashank Mittal4bfb2e32012-04-16 10:56:27 -0700106
Channagoud Kadabi539ef722012-03-29 16:02:50 +0530107 off = 0x0290; /* ctrl 0 */
108 for (i = 0; i < 4; i++) {
109 writel(pd->ctrl[i], MIPI_DSI_BASE + off);
110 off += 4;
111 }
Shashank Mittal4bfb2e32012-04-16 10:56:27 -0700112
Channagoud Kadabi539ef722012-03-29 16:02:50 +0530113 off = 0x02a0; /* strength 0 */
114 for (i = 0; i < 4; i++) {
115 writel(pd->strength[i], MIPI_DSI_BASE + off);
116 off += 4;
117 }
Shashank Mittal4bfb2e32012-04-16 10:56:27 -0700118
Channagoud Kadabi539ef722012-03-29 16:02:50 +0530119 if (1 == pinfo->num_of_lanes)
120 pd->pll[10] |= 0x8;
Shashank Mittal4bfb2e32012-04-16 10:56:27 -0700121
Channagoud Kadabi539ef722012-03-29 16:02:50 +0530122 off = 0x0204; /* pll ctrl 1, skip 0 */
123 for (i = 1; i < 21; i++) {
124 writel(pd->pll[i], MIPI_DSI_BASE + off);
125 off += 4;
126 }
127
128 /* pll ctrl 0 */
129 writel(pd->pll[0], MIPI_DSI_BASE + 0x200);
130 writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);
131 /* lane swp ctrol */
132 if (pinfo->lane_swap)
133 writel(pinfo->lane_swap, MIPI_DSI_BASE + 0xac);
134 } else {
135 writel(0x0001, MIPI_DSI_BASE + 0x128); /* start phy sw reset */
136 writel(0x0000, MIPI_DSI_BASE + 0x128); /* end phy w reset */
137 writel(0x0003, MIPI_DSI_BASE + 0x500); /* regulator_ctrl_0 */
138 writel(0x0001, MIPI_DSI_BASE + 0x504); /* regulator_ctrl_1 */
139 writel(0x0001, MIPI_DSI_BASE + 0x508); /* regulator_ctrl_2 */
140 writel(0x0000, MIPI_DSI_BASE + 0x50c); /* regulator_ctrl_3 */
141 writel(0x0100, MIPI_DSI_BASE + 0x510); /* regulator_ctrl_4 */
142
143 pd = (pinfo->dsi_phy_config);
144
145 off = 0x0480; /* strength 0 - 2 */
146 for (i = 0; i < 3; i++) {
147 writel(pd->strength[i], MIPI_DSI_BASE + off);
148 off += 4;
149 }
150
151 off = 0x0470; /* ctrl 0 - 3 */
152 for (i = 0; i < 4; i++) {
153 writel(pd->ctrl[i], MIPI_DSI_BASE + off);
154 off += 4;
155 }
156
157 off = 0x0500; /* regulator ctrl 0 - 4 */
158 for (i = 0; i < 5; i++) {
159 writel(pd->regulator[i], MIPI_DSI_BASE + off);
160 off += 4;
161 }
162 mipi_dsi_calibration();
163
164 off = 0x0204; /* pll ctrl 1 - 19, skip 0 */
165 for (i = 1; i < 20; i++) {
166 writel(pd->pll[i], MIPI_DSI_BASE + off);
167 off += 4;
168 }
169
170 /* pll ctrl 0 */
171 writel(pd->pll[0], MIPI_DSI_BASE + 0x200);
172 writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);
173
174 /* Check that PHY is ready */
175 while (!(readl(DSIPHY_PLL_RDY) & 0x01))
176 udelay(1);
177
178 writel(0x202D, DSI_CLKOUT_TIMING_CTRL);
179
180 off = 0x0440; /* phy timing ctrl 0 - 11 */
181 for (i = 0; i < 12; i++) {
182 writel(pd->timing[i], MIPI_DSI_BASE + off);
183 off += 4;
184 }
Shashank Mittal4bfb2e32012-04-16 10:56:27 -0700185 }
186 return 0;
187}
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800188
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700189void mdss_dsi_phy_sw_reset(uint32_t ctl_base)
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800190{
191 /* start phy sw reset */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700192 writel(0x0001, ctl_base + 0x012c);
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800193 udelay(1000);
194
195 /* end phy sw reset */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700196 writel(0x0000, ctl_base + 0x012c);
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800197 udelay(100);
198}
199
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700200void mdss_dsi_uniphy_pll_lock_detect_setting(uint32_t ctl_base)
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800201{
Dhaval Patele9331fc2014-03-18 11:45:53 -0700202 writel(0x0d, ctl_base + 0x0264); /* LKDetect CFG2 */
Sandeep Panda0ce96e92015-05-13 12:24:10 +0530203 writel(0x0c, ctl_base + 0x0264); /* LKDetect CFG2 */
204 udelay(1);
205 writel(0x0d, ctl_base + 0x0264); /* LKDetect CFG2 */
raghavendra ambadas7d2adc32015-12-21 12:30:55 +0530206 mdelay(1);
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800207}
208
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700209void mdss_dsi_uniphy_pll_sw_reset(uint32_t ctl_base)
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800210{
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700211 writel(0x01, ctl_base + 0x0268); /* PLL TEST CFG */
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800212 udelay(1);
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700213 writel(0x00, ctl_base + 0x0268); /* PLL TEST CFG */
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800214 udelay(1);
215}
216
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700217int mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd)
218{
219 /* DSI0 and DSI1 have a common regulator */
220
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700221 uint32_t off = 0x0580; /* phy regulator ctrl settings */
222
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700223 /* Regulator ctrl 0 */
224 writel(0x00, MIPI_DSI0_BASE + off + (4 * 0));
225 /* Regulator ctrl - CAL_PWD_CFG */
226 writel(pd->regulator[6], MIPI_DSI0_BASE + off + (4 * 6));
227 /* Regulator ctrl - TEST */
228 writel(pd->regulator[5], MIPI_DSI0_BASE + off + (4 * 5));
229 /* Regulator ctrl 3 */
230 writel(pd->regulator[3], MIPI_DSI0_BASE + off + (4 * 3));
231 /* Regulator ctrl 2 */
232 writel(pd->regulator[2], MIPI_DSI0_BASE + off + (4 * 2));
233 /* Regulator ctrl 1 */
234 writel(pd->regulator[1], MIPI_DSI0_BASE + off + (4 * 1));
235 /* Regulator ctrl 0 */
236 writel(pd->regulator[0], MIPI_DSI0_BASE + off + (4 * 0));
237 /* Regulator ctrl 4 */
238 writel(pd->regulator[4], MIPI_DSI0_BASE + off + (4 * 4));
239 dmb();
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700240}
241
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400242int mdss_dsi_v2_phy_init(struct mipi_dsi_panel_config *pinfo, uint32_t ctl_base)
243{
244 struct mdss_dsi_phy_ctrl *pd;
245 uint32_t i, ln, off = 0, offset;
246
247 pd = pinfo->mdss_dsi_phy_config;
248 /* DSI PHY configuration */
249 off = 0x480;
250 writel(pd->strength[0], ctl_base + off + (4 * 0));
251 writel(pd->strength[1], ctl_base + off + (4 * 2));
252
253 off = 0x470;
254 writel(0x10, ctl_base + off + (4 * 3));
255 writel(0x5F, ctl_base + off + (4 * 0));
256
257 off = 0x500;
Xiaoming Zhou7c9e1ee2013-07-18 10:51:41 -0400258 /* use LDO mode */
259 writel(0x25, ctl_base + 0x4B0);
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400260 for (i = 0; i < 5; i++)
261 writel(pd->regulator[i], ctl_base + off + (4 * i));
262
263 mipi_dsi_calibration();
264
265 /* 4 lanes + clk lane configuration */
266 /* lane config n * (0 - 4) & DataPath setup */
267 for (ln = 0; ln < 5; ln++) {
268 off = 0x0300 + (ln * 0x40);
269 for (i = 0; i < 9; i++) {
270 offset = i + (ln * 9);
271 writel(pd->laneCfg[offset], ctl_base + off);
272 dmb();
273 off += 4;
274 }
275 }
276
277 off = 0x440;
278 for (i = 0; i < 12; i++)
279 writel(pd->timing[i], ctl_base + off + (4 * i));
280
281 if (1 == pinfo->num_of_lanes)
282 writel(0x8, ctl_base + 0x200 + (4 * 11));
283
284
285 if (pinfo->lane_swap)
286 writel(pinfo->lane_swap, ctl_base + 0x0ac);
287
288 /* T_CLK_POST, T_CLK_PRE for CLK lane P/N HS 200 mV timing
289 length should > data lane HS timing length */
290 writel(0x41b, ctl_base + 0x0c0);
291 return 0;
292}
293
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700294int mdss_dsi_phy_init(struct mipi_dsi_panel_config *pinfo, uint32_t ctl_base)
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800295{
296 struct mdss_dsi_phy_ctrl *pd;
297 uint32_t i, off = 0, ln, offset;
298
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400299 if (mdp_get_revision() == MDP_REV_304)
300 return mdss_dsi_v2_phy_init(pinfo, ctl_base);
301
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800302 pd = (pinfo->mdss_dsi_phy_config);
303
304 /* Strength ctrl 0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700305 writel(pd->strength[0], ctl_base + 0x0484);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800306
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700307 mdss_dsi_phy_regulator_init(pd);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800308
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800309 /* Strength ctrl 0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700310 writel(0x00, ctl_base + 0x04dc);
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800311
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800312 off = 0x0440; /* phy timing ctrl 0 - 11 */
313 for (i = 0; i < 12; i++) {
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700314 writel(pd->timing[i], ctl_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800315 dmb();
316 off += 4;
317 }
318
319 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700320 writel(0x00, ctl_base + 0x0474);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800321 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700322 writel(0x5f, ctl_base + 0x0470);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800323
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800324 dmb();
325 /* 4 lanes + clk lane configuration */
326 /* lane config n * (0 - 4) & DataPath setup */
327 for (ln = 0; ln < 5; ln++) {
328 off = 0x0300 + (ln * 0x40);
329 for (i = 0; i < 9; i++) {
330 offset = i + (ln * 9);
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700331 writel(pd->laneCfg[offset], ctl_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800332 dmb();
333 off += 4;
334 }
335 }
336
337 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700338 writel(0x5f, ctl_base + 0x0470);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800339
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700340 /* DSI_PHY_DSIPHY_GLBL_TEST_CTRL */
341 if (ctl_base == MIPI_DSI0_BASE)
342 writel(0x01, ctl_base + 0x04d4);
343 else
344 writel(0x00, ctl_base + 0x04d4);
345
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800346 dmb();
347
348 off = 0x04b4; /* phy BIST ctrl 0 - 5 */
349 for (i = 0; i < 6; i++) {
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700350 writel(pd->bistCtrl[i], ctl_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800351 off += 4;
352 }
353 dmb();
354
355 /* DSI_0_CLKOUT_TIMING_CTRL */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700356 writel(0x41b, ctl_base + 0x0c4);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800357 dmb();
358
359}
Xiaoming Zhou29238642014-07-31 15:24:41 -0400360
361void mdss_dsi_phy_contention_detection(
362 struct mipi_dsi_panel_config *pinfo,
363 uint32_t ctrl_base)
364{
365 struct mdss_dsi_phy_ctrl *pd;
366
367 if (mdp_get_revision() == MDP_REV_304)
368 return;
369
370 pd = (pinfo->mdss_dsi_phy_config);
371 writel(pd->strength[1], ctrl_base + 0x0488);
372 dmb();
373}
374