blob: 69bd7a155bf4c8194867e5da482fe8e7d4b31223 [file] [log] [blame]
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +05301/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Arpita Banerjee2522bc62013-05-24 16:03:53 -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 <platform/timer.h>
Arpita Banerjee2522bc62013-05-24 16:03:53 -070036
37#define LPFR_LUT_SIZE 10
38
39#define VCO_REF_CLOCK_RATE 19200000
40
41#define FRAC_DIVIDER 10000
42
Veera Sundaram Sankarandb0b2bf2014-12-16 18:09:27 -080043struct lpfr_cfg {
Arpita Banerjee2522bc62013-05-24 16:03:53 -070044 uint32_t vco_rate;
45 uint8_t resistance;
46};
47
48static struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
49 {479500000, 8},
50 {480000000, 11},
51 {575500000, 8},
52 {576000000, 12},
53 {610500000, 8},
54 {659500000, 9},
55 {671500000, 10},
56 {672000000, 14},
57 {708500000, 10},
58 {750000000, 11},
59 };
60
61uint64_t div_s64(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
62{
63 *remainder = dividend % divisor;
64
65 return dividend / divisor;
66}
67
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053068void mdss_dsi_uniphy_pll_lock_detect_setting(uint32_t pll_base)
69{
70 writel(0x0c, pll_base + 0x0064); /* LKDetect CFG2 */
71 udelay(100);
72 writel(0x0d, pll_base + 0x0064); /* LKDetect CFG2 */
Dhaval Patelf04efc32014-04-10 18:22:07 -070073 mdelay(1);
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +053074}
75
76void mdss_dsi_uniphy_pll_sw_reset(uint32_t pll_base)
77{
78 writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
79 udelay(1);
80 writel(0x00, pll_base + 0x0068); /* PLL TEST CFG */
81 udelay(1);
82}
83
84int32_t mdss_dsi_auto_pll_config(uint32_t pll_base, uint32_t ctl_base,
Casey Piper4bb1b742013-08-26 11:22:25 -070085 struct mdss_dsi_pll_config *pd)
Arpita Banerjee2522bc62013-05-24 16:03:53 -070086{
87 uint32_t rem, divider;
88 uint32_t refclk_cfg = 0, frac_n_mode = 0, ref_doubler_en_b = 0;
89 uint64_t vco_clock, div_fbx;
90 uint32_t ref_clk_to_pll = 0, frac_n_value = 0;
91 uint32_t sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
92 uint32_t gen_vco_clk, cal_cfg10, cal_cfg11;
Arpita Banerjee2522bc62013-05-24 16:03:53 -070093 uint8_t i, rc = NO_ERROR;
94
95 /* Configure the Loop filter resistance */
96 for (i = 0; i < LPFR_LUT_SIZE; i++)
97 if (pd->vco_clock <= lpfr_lut[i].vco_rate)
98 break;
99 if (i == LPFR_LUT_SIZE) {
100 dprintf(INFO, "unable to get loop filter resistance. vco=%d\n"
Lijuan Gao49a1a792014-10-22 11:19:37 +0800101 , lpfr_lut[i-1].vco_rate);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700102 rc = ERROR;
103 return rc;
104 }
105
Casey Piper4bb1b742013-08-26 11:22:25 -0700106 mdss_dsi_phy_sw_reset(ctl_base);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700107
108 /* Loop filter resistance value */
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530109 writel(lpfr_lut[i].resistance, pll_base + 0x002c);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700110 /* Loop filter capacitance values : c1 and c2 */
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530111 writel(0x70, pll_base + 0x0030);
112 writel(0x15, pll_base + 0x0034);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700113
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530114 writel(0x02, pll_base + 0x0008); /* ChgPump */
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700115 /* postDiv1 - calculated in pll config*/
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530116 writel(pd->posdiv1, pll_base + 0x0004);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700117 /* postDiv2 - fixed devision 4 */
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530118 writel(0x03, pll_base + 0x0024);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700119 /* postDiv3 - calculated in pll config */
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530120 writel(pd->posdiv3, pll_base + 0x0028); /* postDiv3 */
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700121
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530122 writel(0x2b, pll_base + 0x0078); /* Cal CFG3 */
123 writel(0x66, pll_base + 0x007c); /* Cal CFG4 */
124 writel(0x05, pll_base + 0x0064); /* LKDetect CFG2 */
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700125
126 rem = pd->vco_clock % VCO_REF_CLOCK_RATE;
127 if (rem) {
128 refclk_cfg = 0x1;
129 frac_n_mode = 1;
130 ref_doubler_en_b = 0;
131 } else {
132 refclk_cfg = 0x0;
133 frac_n_mode = 0;
134 ref_doubler_en_b = 1;
135 }
136
137 ref_clk_to_pll = (VCO_REF_CLOCK_RATE * 2 * refclk_cfg)
138 + (ref_doubler_en_b * VCO_REF_CLOCK_RATE);
139
140 vco_clock = ((uint64_t) pd->vco_clock) * FRAC_DIVIDER;
141
142 div_fbx = vco_clock / ref_clk_to_pll;
143
144 rem = (uint32_t) (div_fbx % FRAC_DIVIDER);
145 rem = rem * (1 << 16);
146 frac_n_value = rem / FRAC_DIVIDER;
147
148 divider = pd->vco_clock / ref_clk_to_pll;
149 div_fbx *= ref_clk_to_pll;
150 gen_vco_clk = div_fbx / FRAC_DIVIDER;
151
152 if (frac_n_mode) {
153 sdm_cfg0 = 0x0;
154 sdm_cfg1 = (divider & 0x3f) - 1;
155 sdm_cfg3 = frac_n_value / 256;
156 sdm_cfg2 = frac_n_value % 256;
157 } else {
158 sdm_cfg0 = (0x1 << 5);
159 sdm_cfg0 |= (divider & 0x3f) - 1;
160 sdm_cfg1 = 0x0;
161 sdm_cfg2 = 0;
162 sdm_cfg3 = 0;
163 }
164
165 cal_cfg11 = gen_vco_clk / 256000000;
166 cal_cfg10 = (gen_vco_clk % 256000000) / 1000000;
167
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530168 writel(sdm_cfg1 , pll_base + 0x003c); /* SDM CFG1 */
169 writel(sdm_cfg2 , pll_base + 0x0040); /* SDM CFG2 */
170 writel(sdm_cfg3 , pll_base + 0x0044); /* SDM CFG3 */
171 writel(0x00, pll_base + 0x0048); /* SDM CFG4 */
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700172
Padmanabhan Komanduru05975022014-04-17 16:47:34 +0530173 if (pd->vco_delay)
174 udelay(pd->vco_delay);
175 else
176 udelay(10);
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700177
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530178 writel(refclk_cfg, pll_base + 0x0000); /* REFCLK CFG */
179 writel(0x00, pll_base + 0x0014); /* PWRGEN CFG */
180 writel(0x71, pll_base + 0x000c); /* VCOLPF CFG */
181 writel(pd->directpath, pll_base + 0x0010); /* VREG CFG */
182 writel(sdm_cfg0, pll_base + 0x0038); /* SDM CFG0 */
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700183
Padmanabhan Komanduru703bd6d2014-03-25 19:57:01 +0530184 writel(0x0a, pll_base + 0x006c); /* CAL CFG0 */
185 writel(0x30, pll_base + 0x0084); /* CAL CFG6 */
186 writel(0x00, pll_base + 0x0088); /* CAL CFG7 */
187 writel(0x60, pll_base + 0x008c); /* CAL CFG8 */
188 writel(0x00, pll_base + 0x0090); /* CAL CFG9 */
189 writel(cal_cfg10, pll_base + 0x0094); /* CAL CFG10 */
190 writel(cal_cfg11, pll_base + 0x0098); /* CAL CFG11 */
191 writel(0x20, pll_base + 0x009c); /* EFUSE CFG */
Veera Sundaram Sankarandb0b2bf2014-12-16 18:09:27 -0800192 return rc;
Arpita Banerjee2522bc62013-05-24 16:03:53 -0700193}