blob: 754eb18bc7129a796ae186792bfa5892891b3505 [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
157uint32_t mdss_dsi_pll_20nm_sw_reset_st_machine(uint32_t pll_base)
158{
159 writel(0x64, pll_base + MMSS_DSI_PHY_PLL_RES_CODE_START_SEG1);
160 writel(0x64, pll_base + MMSS_DSI_PHY_PLL_RES_CODE_START_SEG2);
161 writel(0x15, pll_base + MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL);
162
163 writel(0x20, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL);
164 writel(0x07, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL2);
165 writel(0x02, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
166 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_RESETSM_CNTRL3);
167}
168
169static void pll_20nm_phy_kvco_config(uint32_t pll_base)
170{
171
172 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_DIV_REF1);
173 writel(0x01, pll_base + MMSS_DSI_PHY_PLL_DIV_REF2);
174 writel(0x8a, pll_base + MMSS_DSI_PHY_PLL_KVCO_COUNT1);
175 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL);
176 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_KVCO_CODE);
177}
178
179static void pll_20nm_phy_loop_bw_config(uint32_t pll_base)
180{
181 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_IP_SETI);
182 writel(0x3f, pll_base + MMSS_DSI_PHY_PLL_PLL_CP_SETI);
183 writel(0x03, pll_base + MMSS_DSI_PHY_PLL_PLL_IP_SETP);
184 writel(0x1f, pll_base + MMSS_DSI_PHY_PLL_PLL_CP_SETP);
185 writel(0x77, pll_base + MMSS_DSI_PHY_PLL_PLL_CRCTRL);
186}
187
188static void pll_20nm_phy_config(uint32_t pll_base)
189{
190 writel(0x40, pll_base + MMSS_DSI_PHY_PLL_SYS_CLK_CTRL);
191 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN);
192 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_CMN_MODE);
193 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_IE_TRIM);
194 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_IP_TRIM);
195 writel(0x08, pll_base + MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL);
196 writel(0x0e, pll_base + MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL);
197 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_PLL_PHSEL_DC);
198 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_CORE_CLK_IN_SYNC_SEL);
199 writel(0x08, pll_base + MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN);
200 writel(0x3f, pll_base + MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN);
201 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_ATB_SEL1);
202 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_ATB_SEL2);
203 writel(0x4b, pll_base + MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND);
204 udelay(1000);
205
206 pll_20nm_phy_kvco_config(pll_base);
207
208 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_VREF_CFG1);
209 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_VREF_CFG2);
210 writel(0x10, pll_base + MMSS_DSI_PHY_PLL_VREF_CFG3);
211 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_VREF_CFG4);
212 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_BGTC);
213 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_PLL_TEST_UPDN);
214 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_PLL_VCO_TUNE);
215 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_PLL_AMP_OS);
216 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_SSC_EN_CENTER);
217 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_RES_CODE_UP);
218 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_RES_CODE_DN);
219 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_RES_CODE_CAL_CSR);
220 writel(0x00, pll_base + MMSS_DSI_PHY_PLL_RES_TRIM_EN_VCOCALDONE);
221 writel(0x0c, pll_base + MMSS_DSI_PHY_PLL_FAUX_EN);
222 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN);
223
224 writel(0x0f, pll_base + MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL);
225 udelay(1000);
226
227 pll_20nm_phy_loop_bw_config(pll_base);
228}
229
230int32_t mdss_dsi_auto_pll_20nm_config(uint32_t pll_base, uint32_t ctl_base,
231 struct mdss_dsi_pll_config *pd)
232{
233 uint32_t data;
234
235 mdss_dsi_phy_sw_reset(ctl_base);
236 pll_20nm_phy_config(pll_base);
237
238 /* set up divider */
239 data = readl(pll_base + MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
240 data |= 0x080; /* bit 7 */
241 data |= (pd->lp_div_mux << 5);
242 data |= pd->ndiv;
243
244 writel(data, pll_base + MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
245
246 writel(pd->hr_oclk2, pll_base + MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER);
247 writel(pd->hr_oclk3, pll_base + MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER);
248
249 writel(((pd->frac_start & 0x7f) | 0x80),
250 pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START1);
251 writel((((pd->frac_start >> 7) & 0x7f) | 0x80),
252 pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START2);
253 writel((((pd->frac_start >> 14) & 0x3f) | 0x40),
254 pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START3);
255
256 writel(((pd->dec_start & 0x7f) | 0x80),
257 pll_base + MMSS_DSI_PHY_PLL_DEC_START1);
258 writel((((pd->dec_start & 0x80) >> 7) | 0x02),
259 pll_base + MMSS_DSI_PHY_PLL_DEC_START2);
260
261 writel((pd->lock_comp & 0xff),
262 pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP1);
263
264 writel(((pd->lock_comp >> 8) & 0xff),
265 pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP2);
266
267 writel(((pd->lock_comp >> 16) & 0xff),
268 pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP3);
269
270 /*
271 * Make sure that PLL vco configuration is complete
272 * before controlling the state machine.
273 */
274 udelay(1000);
275 dmb();
276}