blob: baa520b0ba46cf357e4c1da99cb1dbbacbcd19a9 [file] [log] [blame]
Dhaval Patelee8c9b32014-08-12 16:18:50 -07001/* Copyright (c) 2014, 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 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>
35
36#define LPFR_LUT_SIZE 10
37
38#define VCO_REF_CLOCK_RATE 19200000
39
40#define FRAC_DIVIDER 10000
41
42#define MMSS_DSI_PHY_PLL_SYS_CLK_CTRL 0x0000
43#define MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN 0x0004
44#define MMSS_DSI_PHY_PLL_CMN_MODE 0x0008
45#define MMSS_DSI_PHY_PLL_IE_TRIM 0x000C
46#define MMSS_DSI_PHY_PLL_IP_TRIM 0x0010
47#define MMSS_DSI_PHY_PLL_PLL_CNTRL 0x0014
48#define MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL 0x0018
49#define MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL 0x001C
50#define MMSS_DSI_PHY_PLL_PLL_PHSEL_DC 0x0020
51#define MMSS_DSI_PHY_PLL_PLL_IP_SETI 0x0024
52#define MMSS_DSI_PHY_PLL_CORE_CLK_IN_SYNC_SEL 0x0028
53#define MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN 0x002C
54
55#define MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN 0x0030
56#define MMSS_DSI_PHY_PLL_PLL_CP_SETI 0x0034
57#define MMSS_DSI_PHY_PLL_PLL_IP_SETP 0x0038
58#define MMSS_DSI_PHY_PLL_PLL_CP_SETP 0x003C
59#define MMSS_DSI_PHY_PLL_ATB_SEL1 0x0040
60#define MMSS_DSI_PHY_PLL_ATB_SEL2 0x0044
61#define MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND 0x0048
62#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL 0x004C
63#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL2 0x0050
64#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL3 0x0054
65#define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT1 0x0058
66#define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT2 0x005C
67#define MMSS_DSI_PHY_PLL_DIV_REF1 0x0060
68#define MMSS_DSI_PHY_PLL_DIV_REF2 0x0064
69#define MMSS_DSI_PHY_PLL_KVCO_COUNT1 0x0068
70#define MMSS_DSI_PHY_PLL_KVCO_COUNT2 0x006C
71#define MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL 0x0070
72#define MMSS_DSI_PHY_PLL_KVCO_CODE 0x0074
73#define MMSS_DSI_PHY_PLL_VREF_CFG1 0x0078
74#define MMSS_DSI_PHY_PLL_VREF_CFG2 0x007C
75#define MMSS_DSI_PHY_PLL_VREF_CFG3 0x0080
76#define MMSS_DSI_PHY_PLL_VREF_CFG4 0x0084
77#define MMSS_DSI_PHY_PLL_VREF_CFG5 0x0088
78#define MMSS_DSI_PHY_PLL_VREF_CFG6 0x008C
79#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP1 0x0090
80#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP2 0x0094
81#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP3 0x0098
82#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN 0x009C
83
84#define MMSS_DSI_PHY_PLL_BGTC 0x00A0
85#define MMSS_DSI_PHY_PLL_PLL_TEST_UPDN 0x00A4
86#define MMSS_DSI_PHY_PLL_PLL_VCO_TUNE 0x00A8
87#define MMSS_DSI_PHY_PLL_DEC_START1 0x00AC
88#define MMSS_DSI_PHY_PLL_PLL_AMP_OS 0x00B0
89#define MMSS_DSI_PHY_PLL_SSC_EN_CENTER 0x00B4
90#define MMSS_DSI_PHY_PLL_SSC_ADJ_PER1 0x00B8
91#define MMSS_DSI_PHY_PLL_SSC_ADJ_PER2 0x00BC
92#define MMSS_DSI_PHY_PLL_SSC_PER1 0x00C0
93#define MMSS_DSI_PHY_PLL_SSC_PER2 0x00C4
94#define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE1 0x00C8
95#define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE2 0x00CC
96#define MMSS_DSI_PHY_PLL_RES_CODE_UP 0x00D0
97#define MMSS_DSI_PHY_PLL_RES_CODE_DN 0x00D4
98#define MMSS_DSI_PHY_PLL_RES_CODE_UP_OFFSET 0x00D8
99#define MMSS_DSI_PHY_PLL_RES_CODE_DN_OFFSET 0x00DC
100#define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG1 0x00E0
101#define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG2 0x00E4
102#define MMSS_DSI_PHY_PLL_RES_CODE_CAL_CSR 0x00E8
103#define MMSS_DSI_PHY_PLL_RES_CODE 0x00EC
104#define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL 0x00F0
105#define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL2 0x00F4
106#define MMSS_DSI_PHY_PLL_RES_TRIM_EN_VCOCALDONE 0x00F8
107#define MMSS_DSI_PHY_PLL_FAUX_EN 0x00FC
108
109#define MMSS_DSI_PHY_PLL_DIV_FRAC_START1 0x0100
110#define MMSS_DSI_PHY_PLL_DIV_FRAC_START2 0x0104
111#define MMSS_DSI_PHY_PLL_DIV_FRAC_START3 0x0108
112#define MMSS_DSI_PHY_PLL_DEC_START2 0x010C
113#define MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN 0x0110
114#define MMSS_DSI_PHY_PLL_PLL_CRCTRL 0x0114
115#define MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL 0x013C
116#define MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL 0x0140
117#define MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER 0x0144
118#define MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER 0x0148
119#define MMSS_DSI_PHY_PLL_PLL_VCO_HIGH 0x014C
120#define MMSS_DSI_PHY_PLL_RESET_SM 0x0150
121
122uint32_t mdss_dsi_pll_20nm_lock_status(uint32_t pll_base)
123{
124 uint32_t cnt, status;
125
126 udelay(1000);
127
128 /* check pll lock first */
129 for (cnt = 0; cnt < 5; cnt++) {
130 status = readl(pll_base + MMSS_DSI_PHY_PLL_RESET_SM);
131 dprintf(SPEW, "%s: pll_base=%x cnt=%d status=%x\n",
132 __func__, pll_base, cnt, status);
133 status &= 0x20; /* bit 5 */
134 if (status)
135 break;
136 udelay(5000);
137 }
138
139 if (!status)
140 goto pll_done;
141
142 /* check pll ready */
143 for (cnt = 0; cnt < 5; cnt++) {
144 status = readl(pll_base + MMSS_DSI_PHY_PLL_RESET_SM);
145 dprintf(SPEW, "%s: pll_base=%x cnt=%d status=%x\n",
146 __func__, pll_base, cnt, status);
147 status &= 0x40; /* bit 6 */
148 if (status)
149 break;
150 udelay(5000);
151 }
152
153pll_done:
154 return status;
155}
156
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800157static void mdss_dsi_pll_20nm_config_common_block(uint32_t pll_base)
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700158{
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800159 writel(0x82, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
160 writel(0x2a, pll_base + MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN);
161 writel(0x2b, pll_base + MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700162 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800163 writel(0x40, pll_base + MMSS_DSI_PHY_PLL_SYS_CLK_CTRL);
164 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_IE_TRIM);
165 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_IP_TRIM);
166 writel(0x08, pll_base + MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL);
167 writel(0x0e, pll_base + MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL);
168 writel(0x08, pll_base + MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN);
169 writel(0x4a, pll_base + MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700170 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_DIV_REF1);
171 writel(0x01, pll_base + MMSS_DSI_PHY_PLL_DIV_REF2);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800172 writel(0x07, pll_base + MMSS_DSI_PHY_PLL_PLL_CNTRL);
173 writel(0x1f, pll_base + MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700174 writel(0x8a, pll_base + MMSS_DSI_PHY_PLL_KVCO_COUNT1);
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800175 writel(0x10, pll_base + MMSS_DSI_PHY_PLL_VREF_CFG3);
176 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_SSC_EN_CENTER);
177 writel(0x0c, pll_base + MMSS_DSI_PHY_PLL_FAUX_EN);
178 writel(0x0a, pll_base + MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN);
179 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL);
180 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_CMN_MODE);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700181}
182
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800183static void mdss_dsi_pll_20nm_config_loop_bw(uint32_t pll_base)
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700184{
185 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_IP_SETI);
186 writel(0x3f, pll_base + MMSS_DSI_PHY_PLL_PLL_CP_SETI);
187 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_IP_SETP);
188 writel(0x1f, pll_base + MMSS_DSI_PHY_PLL_PLL_CP_SETP);
189 writel(0x77, pll_base + MMSS_DSI_PHY_PLL_PLL_CRCTRL);
190}
191
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800192static void mdss_dsi_pll_20nm_phy_config(uint32_t pll_base)
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700193{
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800194 mdss_dsi_pll_20nm_config_common_block(pll_base);
195 mdss_dsi_pll_20nm_config_loop_bw(pll_base);
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700196}
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
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800234 writel(0x01, pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN);
235
236
237 dprintf(SPEW, "div frac1=0x%x, div frac2 = 0x%x, div frac3=0x%x\n",
238 readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START1),
239 readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START2),
240 readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START3));
241 dprintf(SPEW, "dec start1=0x%x, dec start2 = 0x%x\n",
242 readl(pll_base + MMSS_DSI_PHY_PLL_DEC_START1),
243 readl(pll_base + MMSS_DSI_PHY_PLL_DEC_START2));
244 dprintf(SPEW, "plllock cmp1=0x%x,plllock cmp2= 0x%x, plllock cmp3=0x%x\n",
245 readl(pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP1),
246 readl(pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP2),
247 readl(pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP3));
248
Dhaval Patelee8c9b32014-08-12 16:18:50 -0700249 /*
250 * Make sure that PLL vco configuration is complete
251 * before controlling the state machine.
252 */
253 udelay(1000);
254 dmb();
255}
Jeevan Shriram1d3115d2014-12-14 14:55:53 -0800256
257static void mdss_dsi_pll_20nm_config_resetsm(uint32_t pll_base)
258{
259 writel(0x24, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL);
260 writel(0x07, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL2);
261}
262
263static void mdss_dsi_pll_20nm_config_vco_start(uint32_t pll_base)
264{
265 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
266 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
267 udelay(10);
268 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
269}
270
271static void mdss_dsi_pll_20nm_disable(uint32_t pll_base)
272{
273 dprintf(SPEW, "Disabling DSI PHY PLL \n");
274 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
275 writel(0x06, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
276 dmb();
277}
278
279void mdss_dsi_auto_pll_20nm_config(uint32_t pll_base, uint32_t ctl_base,
280 struct mdss_dsi_pll_config *pd)
281{
282
283 mdss_dsi_pll_20nm_phy_config(pll_base);
284
285 /*
286 * For 20nm PHY, DSI PLL 1 drains some current in its reset state.
287 * Need to turn off the DSI1 PLL explicitly.
288 */
289 if (ctl_base == MIPI_DSI0_BASE) {
290 dprintf(SPEW, "Calling disable function for PHY PLL 1 \n");
291 mdss_dsi_pll_20nm_disable(DSI1_PLL_BASE);
292 }
293
294 mdss_dsi_pll_20nm_config_vco_rate(pll_base, pd);
295
296 mdss_dsi_pll_20nm_config_resetsm(pll_base);
297 mdss_dsi_pll_20nm_config_vco_start(pll_base);
298 udelay(1000);
299}