blob: 6449e02dab9a98b6723d56b7653338152a582619 [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 */
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800206}
207
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700208void mdss_dsi_uniphy_pll_sw_reset(uint32_t ctl_base)
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800209{
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700210 writel(0x01, ctl_base + 0x0268); /* PLL TEST CFG */
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800211 udelay(1);
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700212 writel(0x00, ctl_base + 0x0268); /* PLL TEST CFG */
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800213 udelay(1);
214}
215
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700216int mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd)
217{
218 /* DSI0 and DSI1 have a common regulator */
219
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700220 uint32_t off = 0x0580; /* phy regulator ctrl settings */
221
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700222 /* Regulator ctrl 0 */
223 writel(0x00, MIPI_DSI0_BASE + off + (4 * 0));
224 /* Regulator ctrl - CAL_PWD_CFG */
225 writel(pd->regulator[6], MIPI_DSI0_BASE + off + (4 * 6));
226 /* Regulator ctrl - TEST */
227 writel(pd->regulator[5], MIPI_DSI0_BASE + off + (4 * 5));
228 /* Regulator ctrl 3 */
229 writel(pd->regulator[3], MIPI_DSI0_BASE + off + (4 * 3));
230 /* Regulator ctrl 2 */
231 writel(pd->regulator[2], MIPI_DSI0_BASE + off + (4 * 2));
232 /* Regulator ctrl 1 */
233 writel(pd->regulator[1], MIPI_DSI0_BASE + off + (4 * 1));
234 /* Regulator ctrl 0 */
235 writel(pd->regulator[0], MIPI_DSI0_BASE + off + (4 * 0));
236 /* Regulator ctrl 4 */
237 writel(pd->regulator[4], MIPI_DSI0_BASE + off + (4 * 4));
238 dmb();
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700239}
240
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400241int mdss_dsi_v2_phy_init(struct mipi_dsi_panel_config *pinfo, uint32_t ctl_base)
242{
243 struct mdss_dsi_phy_ctrl *pd;
244 uint32_t i, ln, off = 0, offset;
245
246 pd = pinfo->mdss_dsi_phy_config;
247 /* DSI PHY configuration */
248 off = 0x480;
249 writel(pd->strength[0], ctl_base + off + (4 * 0));
250 writel(pd->strength[1], ctl_base + off + (4 * 2));
251
252 off = 0x470;
253 writel(0x10, ctl_base + off + (4 * 3));
254 writel(0x5F, ctl_base + off + (4 * 0));
255
256 off = 0x500;
Xiaoming Zhou7c9e1ee2013-07-18 10:51:41 -0400257 /* use LDO mode */
258 writel(0x25, ctl_base + 0x4B0);
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400259 for (i = 0; i < 5; i++)
260 writel(pd->regulator[i], ctl_base + off + (4 * i));
261
262 mipi_dsi_calibration();
263
264 /* 4 lanes + clk lane configuration */
265 /* lane config n * (0 - 4) & DataPath setup */
266 for (ln = 0; ln < 5; ln++) {
267 off = 0x0300 + (ln * 0x40);
268 for (i = 0; i < 9; i++) {
269 offset = i + (ln * 9);
270 writel(pd->laneCfg[offset], ctl_base + off);
271 dmb();
272 off += 4;
273 }
274 }
275
276 off = 0x440;
277 for (i = 0; i < 12; i++)
278 writel(pd->timing[i], ctl_base + off + (4 * i));
279
280 if (1 == pinfo->num_of_lanes)
281 writel(0x8, ctl_base + 0x200 + (4 * 11));
282
283
284 if (pinfo->lane_swap)
285 writel(pinfo->lane_swap, ctl_base + 0x0ac);
286
287 /* T_CLK_POST, T_CLK_PRE for CLK lane P/N HS 200 mV timing
288 length should > data lane HS timing length */
289 writel(0x41b, ctl_base + 0x0c0);
290 return 0;
291}
292
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700293int mdss_dsi_phy_init(struct mipi_dsi_panel_config *pinfo, uint32_t ctl_base)
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800294{
295 struct mdss_dsi_phy_ctrl *pd;
296 uint32_t i, off = 0, ln, offset;
297
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400298 if (mdp_get_revision() == MDP_REV_304)
299 return mdss_dsi_v2_phy_init(pinfo, ctl_base);
300
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800301 pd = (pinfo->mdss_dsi_phy_config);
302
303 /* Strength ctrl 0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700304 writel(pd->strength[0], ctl_base + 0x0484);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800305
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700306 mdss_dsi_phy_regulator_init(pd);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800307
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800308 /* Strength ctrl 0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700309 writel(0x00, ctl_base + 0x04dc);
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800310
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800311 off = 0x0440; /* phy timing ctrl 0 - 11 */
312 for (i = 0; i < 12; i++) {
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700313 writel(pd->timing[i], ctl_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800314 dmb();
315 off += 4;
316 }
317
318 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700319 writel(0x00, ctl_base + 0x0474);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800320 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700321 writel(0x5f, ctl_base + 0x0470);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800322
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800323 dmb();
324 /* 4 lanes + clk lane configuration */
325 /* lane config n * (0 - 4) & DataPath setup */
326 for (ln = 0; ln < 5; ln++) {
327 off = 0x0300 + (ln * 0x40);
328 for (i = 0; i < 9; i++) {
329 offset = i + (ln * 9);
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700330 writel(pd->laneCfg[offset], ctl_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800331 dmb();
332 off += 4;
333 }
334 }
335
336 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700337 writel(0x5f, ctl_base + 0x0470);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800338
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700339 /* DSI_PHY_DSIPHY_GLBL_TEST_CTRL */
340 if (ctl_base == MIPI_DSI0_BASE)
341 writel(0x01, ctl_base + 0x04d4);
342 else
343 writel(0x00, ctl_base + 0x04d4);
344
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800345 dmb();
346
347 off = 0x04b4; /* phy BIST ctrl 0 - 5 */
348 for (i = 0; i < 6; i++) {
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700349 writel(pd->bistCtrl[i], ctl_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800350 off += 4;
351 }
352 dmb();
353
354 /* DSI_0_CLKOUT_TIMING_CTRL */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700355 writel(0x41b, ctl_base + 0x0c4);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800356 dmb();
357
358}
Xiaoming Zhou29238642014-07-31 15:24:41 -0400359
360void mdss_dsi_phy_contention_detection(
361 struct mipi_dsi_panel_config *pinfo,
362 uint32_t ctrl_base)
363{
364 struct mdss_dsi_phy_ctrl *pd;
365
366 if (mdp_get_revision() == MDP_REV_304)
367 return;
368
369 pd = (pinfo->mdss_dsi_phy_config);
370 writel(pd->strength[1], ctrl_base + 0x0488);
371 dmb();
372}
373