blob: 890f253d1ac576bc5db537cc362de5e33748951f [file] [log] [blame]
Jeevan Shriram7dfb85e2015-01-08 13:21:37 -08001/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Dhaval Patelee8c9b32014-08-12 16:18:50 -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.
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 "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 <err.h>
32#include <smem.h>
33#include <mipi_dsi.h>
34#include <platform/iomap.h>
Veera Sundaram Sankarandb0b2bf2014-12-16 18:09:27 -080035#include <qtimer.h>
36#include <arch/defines.h>
Dhaval Patelee8c9b32014-08-12 16:18:50 -070037
38#define LPFR_LUT_SIZE 10
39
40#define VCO_REF_CLOCK_RATE 19200000
41
42#define FRAC_DIVIDER 10000
43
44#define MMSS_DSI_PHY_PLL_SYS_CLK_CTRL 0x0000
45#define MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN 0x0004
46#define MMSS_DSI_PHY_PLL_CMN_MODE 0x0008
47#define MMSS_DSI_PHY_PLL_IE_TRIM 0x000C
48#define MMSS_DSI_PHY_PLL_IP_TRIM 0x0010
49#define MMSS_DSI_PHY_PLL_PLL_CNTRL 0x0014
50#define MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL 0x0018
51#define MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL 0x001C
52#define MMSS_DSI_PHY_PLL_PLL_PHSEL_DC 0x0020
53#define MMSS_DSI_PHY_PLL_PLL_IP_SETI 0x0024
54#define MMSS_DSI_PHY_PLL_CORE_CLK_IN_SYNC_SEL 0x0028
55#define MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN 0x002C
56
57#define MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN 0x0030
58#define MMSS_DSI_PHY_PLL_PLL_CP_SETI 0x0034
59#define MMSS_DSI_PHY_PLL_PLL_IP_SETP 0x0038
60#define MMSS_DSI_PHY_PLL_PLL_CP_SETP 0x003C
61#define MMSS_DSI_PHY_PLL_ATB_SEL1 0x0040
62#define MMSS_DSI_PHY_PLL_ATB_SEL2 0x0044
63#define MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND 0x0048
64#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL 0x004C
65#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL2 0x0050
66#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL3 0x0054
67#define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT1 0x0058
68#define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT2 0x005C
69#define MMSS_DSI_PHY_PLL_DIV_REF1 0x0060
70#define MMSS_DSI_PHY_PLL_DIV_REF2 0x0064
71#define MMSS_DSI_PHY_PLL_KVCO_COUNT1 0x0068
72#define MMSS_DSI_PHY_PLL_KVCO_COUNT2 0x006C
73#define MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL 0x0070
74#define MMSS_DSI_PHY_PLL_KVCO_CODE 0x0074
75#define MMSS_DSI_PHY_PLL_VREF_CFG1 0x0078
76#define MMSS_DSI_PHY_PLL_VREF_CFG2 0x007C
77#define MMSS_DSI_PHY_PLL_VREF_CFG3 0x0080
78#define MMSS_DSI_PHY_PLL_VREF_CFG4 0x0084
79#define MMSS_DSI_PHY_PLL_VREF_CFG5 0x0088
80#define MMSS_DSI_PHY_PLL_VREF_CFG6 0x008C
81#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP1 0x0090
82#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP2 0x0094
83#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP3 0x0098
84#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN 0x009C
85
86#define MMSS_DSI_PHY_PLL_BGTC 0x00A0
87#define MMSS_DSI_PHY_PLL_PLL_TEST_UPDN 0x00A4
88#define MMSS_DSI_PHY_PLL_PLL_VCO_TUNE 0x00A8
89#define MMSS_DSI_PHY_PLL_DEC_START1 0x00AC
90#define MMSS_DSI_PHY_PLL_PLL_AMP_OS 0x00B0
91#define MMSS_DSI_PHY_PLL_SSC_EN_CENTER 0x00B4
92#define MMSS_DSI_PHY_PLL_SSC_ADJ_PER1 0x00B8
93#define MMSS_DSI_PHY_PLL_SSC_ADJ_PER2 0x00BC
94#define MMSS_DSI_PHY_PLL_SSC_PER1 0x00C0
95#define MMSS_DSI_PHY_PLL_SSC_PER2 0x00C4
96#define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE1 0x00C8
97#define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE2 0x00CC
98#define MMSS_DSI_PHY_PLL_RES_CODE_UP 0x00D0
99#define MMSS_DSI_PHY_PLL_RES_CODE_DN 0x00D4
100#define MMSS_DSI_PHY_PLL_RES_CODE_UP_OFFSET 0x00D8
101#define MMSS_DSI_PHY_PLL_RES_CODE_DN_OFFSET 0x00DC
102#define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG1 0x00E0
103#define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG2 0x00E4
104#define MMSS_DSI_PHY_PLL_RES_CODE_CAL_CSR 0x00E8
105#define MMSS_DSI_PHY_PLL_RES_CODE 0x00EC
106#define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL 0x00F0
107#define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL2 0x00F4
108#define MMSS_DSI_PHY_PLL_RES_TRIM_EN_VCOCALDONE 0x00F8
109#define MMSS_DSI_PHY_PLL_FAUX_EN 0x00FC
110
111#define MMSS_DSI_PHY_PLL_DIV_FRAC_START1 0x0100
112#define MMSS_DSI_PHY_PLL_DIV_FRAC_START2 0x0104
113#define MMSS_DSI_PHY_PLL_DIV_FRAC_START3 0x0108
114#define MMSS_DSI_PHY_PLL_DEC_START2 0x010C
115#define MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN 0x0110
116#define MMSS_DSI_PHY_PLL_PLL_CRCTRL 0x0114
117#define MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL 0x013C
118#define MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL 0x0140
119#define MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER 0x0144
120#define MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER 0x0148
121#define MMSS_DSI_PHY_PLL_PLL_VCO_HIGH 0x014C
122#define MMSS_DSI_PHY_PLL_RESET_SM 0x0150
123
124uint32_t mdss_dsi_pll_20nm_lock_status(uint32_t pll_base)
125{
126 uint32_t cnt, status;
127
128 udelay(1000);
129
130 /* check pll lock first */
131 for (cnt = 0; cnt < 5; cnt++) {
132 status = readl(pll_base + MMSS_DSI_PHY_PLL_RESET_SM);
133 dprintf(SPEW, "%s: pll_base=%x cnt=%d status=%x\n",
134 __func__, pll_base, cnt, status);
135 status &= 0x20; /* bit 5 */
136 if (status)
137 break;
138 udelay(5000);
139 }
140
141 if (!status)
142 goto pll_done;
143
144 /* check pll ready */
145 for (cnt = 0; cnt < 5; cnt++) {
146 status = readl(pll_base + MMSS_DSI_PHY_PLL_RESET_SM);
147 dprintf(SPEW, "%s: pll_base=%x cnt=%d status=%x\n",
148 __func__, pll_base, cnt, status);
149 status &= 0x40; /* bit 6 */
150 if (status)
151 break;
152 udelay(5000);
153 }
154
155pll_done:
156 return status;
157}
158
Huaibin Yang90991f12014-12-29 13:24:43 -0800159static void mdss_dsi_pll_20nm_config_common_block_1(uint32_t pll_base)
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700160{
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800161 writel(0x82, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
162 writel(0x2a, pll_base + MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN);
163 writel(0x2b, pll_base + MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700164 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
Huaibin Yang90991f12014-12-29 13:24:43 -0800165}
166
167static void mdss_dsi_pll_20nm_config_common_block_2(uint32_t pll_base)
168{
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800169 writel(0x40, pll_base + MMSS_DSI_PHY_PLL_SYS_CLK_CTRL);
170 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_IE_TRIM);
171 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_IP_TRIM);
172 writel(0x08, pll_base + MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL);
173 writel(0x0e, pll_base + MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL);
174 writel(0x08, pll_base + MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN);
175 writel(0x4a, pll_base + MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700176 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_DIV_REF1);
177 writel(0x01, pll_base + MMSS_DSI_PHY_PLL_DIV_REF2);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800178 writel(0x07, pll_base + MMSS_DSI_PHY_PLL_PLL_CNTRL);
179 writel(0x1f, pll_base + MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700180 writel(0x8a, pll_base + MMSS_DSI_PHY_PLL_KVCO_COUNT1);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800181 writel(0x10, pll_base + MMSS_DSI_PHY_PLL_VREF_CFG3);
182 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_SSC_EN_CENTER);
183 writel(0x0c, pll_base + MMSS_DSI_PHY_PLL_FAUX_EN);
184 writel(0x0a, pll_base + MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN);
185 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL);
186 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_CMN_MODE);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700187}
188
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800189static void mdss_dsi_pll_20nm_config_loop_bw(uint32_t pll_base)
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700190{
191 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_IP_SETI);
192 writel(0x3f, pll_base + MMSS_DSI_PHY_PLL_PLL_CP_SETI);
193 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_IP_SETP);
194 writel(0x1f, pll_base + MMSS_DSI_PHY_PLL_PLL_CP_SETP);
195 writel(0x77, pll_base + MMSS_DSI_PHY_PLL_PLL_CRCTRL);
196}
197
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800198static void mdss_dsi_pll_20nm_config_vco_rate(uint32_t pll_base, struct mdss_dsi_pll_config *pd)
Siddhartha Agrawalb151f302014-08-20 22:15:52 -0700199{
Siddhartha Agrawalb151f302014-08-20 22:15:52 -0700200
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700201 uint32_t data;
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700202 /* set up divider */
203 data = readl(pll_base + MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
204 data |= 0x080; /* bit 7 */
205 data |= (pd->lp_div_mux << 5);
206 data |= pd->ndiv;
207
208 writel(data, pll_base + MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
209
210 writel(pd->hr_oclk2, pll_base + MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER);
211 writel(pd->hr_oclk3, pll_base + MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER);
212
213 writel(((pd->frac_start & 0x7f) | 0x80),
214 pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START1);
215 writel((((pd->frac_start >> 7) & 0x7f) | 0x80),
216 pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START2);
217 writel((((pd->frac_start >> 14) & 0x3f) | 0x40),
218 pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START3);
219
220 writel(((pd->dec_start & 0x7f) | 0x80),
221 pll_base + MMSS_DSI_PHY_PLL_DEC_START1);
222 writel((((pd->dec_start & 0x80) >> 7) | 0x02),
223 pll_base + MMSS_DSI_PHY_PLL_DEC_START2);
224
225 writel((pd->lock_comp & 0xff),
226 pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP1);
227
228 writel(((pd->lock_comp >> 8) & 0xff),
229 pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP2);
230
231 writel(((pd->lock_comp >> 16) & 0xff),
232 pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP3);
233
Chandan Uddaraju34dda2a2015-02-04 14:33:16 -0800234 if (pd->en_vco_zero_phase)
235 writel(0x01, pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN);
236 else
237 writel(0x0d, pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800238
239 dprintf(SPEW, "div frac1=0x%x, div frac2 = 0x%x, div frac3=0x%x\n",
240 readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START1),
241 readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START2),
242 readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START3));
243 dprintf(SPEW, "dec start1=0x%x, dec start2 = 0x%x\n",
244 readl(pll_base + MMSS_DSI_PHY_PLL_DEC_START1),
245 readl(pll_base + MMSS_DSI_PHY_PLL_DEC_START2));
246 dprintf(SPEW, "plllock cmp1=0x%x,plllock cmp2= 0x%x, plllock cmp3=0x%x\n",
247 readl(pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP1),
248 readl(pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP2),
249 readl(pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP3));
250
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700251 /*
252 * Make sure that PLL vco configuration is complete
253 * before controlling the state machine.
254 */
255 udelay(1000);
256 dmb();
257}
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800258
259static void mdss_dsi_pll_20nm_config_resetsm(uint32_t pll_base)
260{
261 writel(0x24, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL);
262 writel(0x07, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL2);
263}
264
265static void mdss_dsi_pll_20nm_config_vco_start(uint32_t pll_base)
266{
267 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
268 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
269 udelay(10);
270 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
271}
272
Huaibin Yang6592e772014-12-29 13:29:08 -0800273static void mdss_dsi_pll_20nm_config_powerdown(uint32_t pll_base)
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800274{
Huaibin Yang6592e772014-12-29 13:29:08 -0800275 dprintf(SPEW, "Powerdown DSI PHY PLL \n");
276 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_SYS_CLK_CTRL);
277 writel(0x01, pll_base + MMSS_DSI_PHY_PLL_CMN_MODE);
278 writel(0x82, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
279 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800280 dmb();
281}
282
Huaibin Yang90991f12014-12-29 13:24:43 -0800283
Aravind Venkateswaranf2702352015-07-23 18:14:13 -0700284void mdss_dsi_auto_pll_20nm_config(struct msm_panel_info *pinfo)
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800285{
Aravind Venkateswaranf2702352015-07-23 18:14:13 -0700286 struct mdss_dsi_pll_config *pd = pinfo->mipi.dsi_pll_config;
287 uint32_t pll_base = pinfo->mipi.pll_base;
288 uint32_t spll_base = pinfo->mipi.spll_base;
289
290 mdss_dsi_phy_sw_reset(pinfo->mipi.ctl_base);
291 if (pinfo->mipi.dual_dsi)
292 mdss_dsi_phy_sw_reset(pinfo->mipi.sctl_base);
293
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800294 /*
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700295 * For 20nm PHY, the DSI PLL which is not powered on to drive a panel
296 * drains some current in its reset state.
297 * Need to turn off that PLL explicitly.
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800298 */
Padmanabhan Komanduruc0766c82015-04-27 16:39:15 -0700299 mdss_dsi_pll_20nm_config_common_block_1(spll_base);
300 mdss_dsi_pll_20nm_config_powerdown(spll_base);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800301
Huaibin Yang90991f12014-12-29 13:24:43 -0800302 mdss_dsi_pll_20nm_config_common_block_1(pll_base);
303 mdss_dsi_pll_20nm_config_common_block_2(pll_base);
304 mdss_dsi_pll_20nm_config_loop_bw(pll_base);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800305 mdss_dsi_pll_20nm_config_vco_rate(pll_base, pd);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800306 mdss_dsi_pll_20nm_config_resetsm(pll_base);
307 mdss_dsi_pll_20nm_config_vco_start(pll_base);
Huaibin Yang90991f12014-12-29 13:24:43 -0800308
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800309 udelay(1000);
310}