blob: 7409915e05375a1f2cc30a172280146471d8eb66 [file] [log] [blame]
Dhaval Patelbb408712014-03-18 11:45:53 -07001/* Copyright (c) 2012-2014, 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 -0700200int mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd)
201{
202 /* DSI0 and DSI1 have a common regulator */
203
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530204 uint32_t off = 0x0280; /* phy regulator ctrl settings */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700205
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700206 /* Regulator ctrl 0 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530207 writel(0x00, DSI0_PHY_BASE + off + (4 * 0));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700208 /* Regulator ctrl - CAL_PWD_CFG */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530209 writel(pd->regulator[6], DSI0_PHY_BASE + off + (4 * 6));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700210 /* Regulator ctrl - TEST */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530211 writel(pd->regulator[5], DSI0_PHY_BASE + off + (4 * 5));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700212 /* Regulator ctrl 3 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530213 writel(pd->regulator[3], DSI0_PHY_BASE + off + (4 * 3));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700214 /* Regulator ctrl 2 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530215 writel(pd->regulator[2], DSI0_PHY_BASE + off + (4 * 2));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700216 /* Regulator ctrl 1 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530217 writel(pd->regulator[1], DSI0_PHY_BASE + off + (4 * 1));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700218 /* Regulator ctrl 0 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530219 writel(pd->regulator[0], DSI0_PHY_BASE + off + (4 * 0));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700220 /* Regulator ctrl 4 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530221 writel(pd->regulator[4], DSI0_PHY_BASE + off + (4 * 4));
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700222 dmb();
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700223}
224
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400225int mdss_dsi_v2_phy_init(struct mipi_dsi_panel_config *pinfo, uint32_t ctl_base)
226{
227 struct mdss_dsi_phy_ctrl *pd;
228 uint32_t i, ln, off = 0, offset;
229
230 pd = pinfo->mdss_dsi_phy_config;
231 /* DSI PHY configuration */
232 off = 0x480;
233 writel(pd->strength[0], ctl_base + off + (4 * 0));
234 writel(pd->strength[1], ctl_base + off + (4 * 2));
235
236 off = 0x470;
237 writel(0x10, ctl_base + off + (4 * 3));
238 writel(0x5F, ctl_base + off + (4 * 0));
239
240 off = 0x500;
Xiaoming Zhou7c9e1ee2013-07-18 10:51:41 -0400241 /* use LDO mode */
242 writel(0x25, ctl_base + 0x4B0);
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400243 for (i = 0; i < 5; i++)
244 writel(pd->regulator[i], ctl_base + off + (4 * i));
245
246 mipi_dsi_calibration();
247
248 /* 4 lanes + clk lane configuration */
249 /* lane config n * (0 - 4) & DataPath setup */
250 for (ln = 0; ln < 5; ln++) {
251 off = 0x0300 + (ln * 0x40);
252 for (i = 0; i < 9; i++) {
253 offset = i + (ln * 9);
254 writel(pd->laneCfg[offset], ctl_base + off);
255 dmb();
256 off += 4;
257 }
258 }
259
260 off = 0x440;
261 for (i = 0; i < 12; i++)
262 writel(pd->timing[i], ctl_base + off + (4 * i));
263
264 if (1 == pinfo->num_of_lanes)
265 writel(0x8, ctl_base + 0x200 + (4 * 11));
266
267
268 if (pinfo->lane_swap)
269 writel(pinfo->lane_swap, ctl_base + 0x0ac);
270
271 /* T_CLK_POST, T_CLK_PRE for CLK lane P/N HS 200 mV timing
272 length should > data lane HS timing length */
273 writel(0x41b, ctl_base + 0x0c0);
274 return 0;
275}
276
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530277int mdss_dsi_phy_init(struct mipi_dsi_panel_config *pinfo,
278 uint32_t ctl_base, uint32_t phy_base)
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800279{
280 struct mdss_dsi_phy_ctrl *pd;
281 uint32_t i, off = 0, ln, offset;
282
Terence Hampsonf49ff4e2013-06-18 15:11:31 -0400283 if (mdp_get_revision() == MDP_REV_304)
284 return mdss_dsi_v2_phy_init(pinfo, ctl_base);
285
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800286 pd = (pinfo->mdss_dsi_phy_config);
287
288 /* Strength ctrl 0 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530289 writel(pd->strength[0], phy_base + 0x0184);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800290
Mao Flynn5f137ed2014-04-18 14:59:47 +0800291 if (pd->regulator_mode == DSI_PHY_REGULATOR_LDO_MODE)
292 pd->regulator[0] = 0x2; /* LDO mode */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700293 mdss_dsi_phy_regulator_init(pd);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800294
Mao Flynn5f137ed2014-04-18 14:59:47 +0800295 /* DSIPHY_REGULATOR_CTRL_0 */
296 if (pd->regulator_mode == DSI_PHY_REGULATOR_LDO_MODE)
297 writel(0x25, phy_base + 0x01dc); /* LDO mode */
298 else
299 writel(0x00, phy_base + 0x01dc); /* DCDC mode */
Chandan Uddaraju932723b2013-02-21 18:36:20 -0800300
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530301 off = 0x0140; /* phy timing ctrl 0 - 11 */
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800302 for (i = 0; i < 12; i++) {
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530303 writel(pd->timing[i], phy_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800304 dmb();
305 off += 4;
306 }
307
308 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530309 writel(0x00, phy_base + 0x0174);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800310 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530311 writel(0x5f, phy_base + 0x0170);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800312
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800313 dmb();
314 /* 4 lanes + clk lane configuration */
315 /* lane config n * (0 - 4) & DataPath setup */
316 for (ln = 0; ln < 5; ln++) {
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530317 off = (ln * 0x40);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800318 for (i = 0; i < 9; i++) {
319 offset = i + (ln * 9);
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530320 writel(pd->laneCfg[offset], phy_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800321 dmb();
322 off += 4;
323 }
324 }
325
326 /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530327 writel(0x5f, phy_base + 0x0170);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800328
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700329 /* DSI_PHY_DSIPHY_GLBL_TEST_CTRL */
Vineet Bajaj2f08a362014-07-24 20:50:42 +0530330 if (phy_base == DSI0_PHY_BASE ||
331 (readl(MIPI_DSI0_BASE) == DSI_HW_REV_103_1))
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530332 writel(0x01, phy_base + 0x01d4);
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700333 else
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530334 writel(0x00, phy_base + 0x01d4);
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700335
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800336 dmb();
337
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530338 off = 0x01b4; /* phy BIST ctrl 0 - 5 */
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800339 for (i = 0; i < 6; i++) {
Padmanabhan Komandurucdc651e2014-03-25 20:25:55 +0530340 writel(pd->bistCtrl[i], phy_base + off);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800341 off += 4;
342 }
343 dmb();
344
345 /* DSI_0_CLKOUT_TIMING_CTRL */
Siddhartha Agrawal1b2ed842013-05-29 18:02:28 -0700346 writel(0x41b, ctl_base + 0x0c4);
Siddhartha Agrawal3e694ea2013-01-23 17:01:31 -0800347 dmb();
348
349}
Xiaoming Zhou03fd48b2014-07-31 15:24:41 -0400350
351void mdss_dsi_phy_contention_detection(
352 struct mipi_dsi_panel_config *pinfo,
353 uint32_t phy_base)
354{
355 struct mdss_dsi_phy_ctrl *pd;
356
357 if (mdp_get_revision() == MDP_REV_304)
358 return;
359
360 pd = (pinfo->mdss_dsi_phy_config);
361 writel(pd->strength[1], phy_base + 0x0188);
362 dmb();
363}
364