Loading...
1/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include "dsi_phy.h"
15#include "dsi.xml.h"
16
17static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
18 struct msm_dsi_dphy_timing *timing)
19{
20 void __iomem *base = phy->base;
21
22 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_0,
23 DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
24 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_1,
25 DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
26 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_2,
27 DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
28 if (timing->clk_zero & BIT(8))
29 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_3,
30 DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8);
31 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_4,
32 DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
33 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_5,
34 DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
35 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_6,
36 DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
37 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_7,
38 DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
39 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_8,
40 DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
41 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_9,
42 DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
43 DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
44 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_10,
45 DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
46 dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_11,
47 DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
48}
49
50static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
51{
52 void __iomem *base = phy->reg_base;
53
54 if (!enable) {
55 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
56 return;
57 }
58
59 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
60 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
61 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
62 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
63 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x3);
64 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
65 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
66 dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
67}
68
69static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
70 const unsigned long bit_rate, const unsigned long esc_rate)
71{
72 struct msm_dsi_dphy_timing *timing = &phy->timing;
73 int i;
74 void __iomem *base = phy->base;
75
76 DBG("");
77
78 if (msm_dsi_dphy_timing_calc(timing, bit_rate, esc_rate)) {
79 dev_err(&phy->pdev->dev,
80 "%s: D-PHY timing calculation failed\n", __func__);
81 return -EINVAL;
82 }
83
84 dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_0, 0xff);
85
86 dsi_28nm_phy_regulator_ctrl(phy, true);
87
88 dsi_phy_write(base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
89
90 dsi_28nm_dphy_set_timing(phy, timing);
91
92 dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
93 dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
94
95 dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_1, 0x6);
96
97 for (i = 0; i < 4; i++) {
98 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_0(i), 0);
99 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_1(i), 0);
100 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_2(i), 0);
101 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_3(i), 0);
102 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(i), 0);
103 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i), 0);
104 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i), 0);
105 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i), 0x1);
106 dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i), 0x97);
107 }
108
109 dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_4, 0);
110 dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_1, 0xc0);
111 dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR0, 0x1);
112 dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR1, 0xbb);
113
114 dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
115
116 msm_dsi_phy_set_src_pll(phy, src_pll_id,
117 REG_DSI_28nm_PHY_GLBL_TEST_CTRL,
118 DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL);
119
120 return 0;
121}
122
123static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
124{
125 dsi_phy_write(phy->base + REG_DSI_28nm_PHY_CTRL_0, 0);
126 dsi_28nm_phy_regulator_ctrl(phy, false);
127
128 /*
129 * Wait for the registers writes to complete in order to
130 * ensure that the phy is completely disabled
131 */
132 wmb();
133}
134
135const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
136 .type = MSM_DSI_PHY_28NM_HPM,
137 .src_pll_truthtable = { {true, true}, {false, true} },
138 .reg_cfg = {
139 .num = 1,
140 .regs = {
141 {"vddio", 1800000, 1800000, 100000, 100},
142 },
143 },
144 .ops = {
145 .enable = dsi_28nm_phy_enable,
146 .disable = dsi_28nm_phy_disable,
147 },
148};
149
150const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
151 .type = MSM_DSI_PHY_28NM_LP,
152 .src_pll_truthtable = { {true, true}, {true, true} },
153 .reg_cfg = {
154 .num = 1,
155 .regs = {
156 {"vddio", 1800000, 1800000, 100000, 100},
157 },
158 },
159 .ops = {
160 .enable = dsi_28nm_phy_enable,
161 .disable = dsi_28nm_phy_disable,
162 },
163};
164
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/clk.h>
7#include <linux/clk-provider.h>
8
9#include "dsi_phy.h"
10#include "dsi.xml.h"
11#include "dsi_phy_28nm.xml.h"
12
13/*
14 * DSI PLL 28nm - clock diagram (eg: DSI0):
15 *
16 * dsi0analog_postdiv_clk
17 * | dsi0indirect_path_div2_clk
18 * | |
19 * +------+ | +----+ | |\ dsi0byte_mux
20 * dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \ |
21 * | +------+ +----+ | m| | +----+
22 * | | u|--o--| /4 |-- dsi0pllbyte
23 * | | x| +----+
24 * o--------------------------| /
25 * | |/
26 * | +------+
27 * o----------| DIV3 |------------------------- dsi0pll
28 * +------+
29 */
30
31#define POLL_MAX_READS 10
32#define POLL_TIMEOUT_US 50
33
34#define VCO_REF_CLK_RATE 19200000
35#define VCO_MIN_RATE 350000000
36#define VCO_MAX_RATE 750000000
37
38/* v2.0.0 28nm LP implementation */
39#define DSI_PHY_28NM_QUIRK_PHY_LP BIT(0)
40#define DSI_PHY_28NM_QUIRK_PHY_8226 BIT(1)
41
42#define LPFR_LUT_SIZE 10
43struct lpfr_cfg {
44 unsigned long vco_rate;
45 u32 resistance;
46};
47
48/* Loop filter resistance: */
49static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
50 { 479500000, 8 },
51 { 480000000, 11 },
52 { 575500000, 8 },
53 { 576000000, 12 },
54 { 610500000, 8 },
55 { 659500000, 9 },
56 { 671500000, 10 },
57 { 672000000, 14 },
58 { 708500000, 10 },
59 { 750000000, 11 },
60};
61
62struct pll_28nm_cached_state {
63 unsigned long vco_rate;
64 u8 postdiv3;
65 u8 postdiv1;
66 u8 byte_mux;
67};
68
69struct dsi_pll_28nm {
70 struct clk_hw clk_hw;
71
72 struct msm_dsi_phy *phy;
73
74 struct pll_28nm_cached_state cached_state;
75};
76
77#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, clk_hw)
78
79static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
80 u32 nb_tries, u32 timeout_us)
81{
82 bool pll_locked = false;
83 u32 val;
84
85 while (nb_tries--) {
86 val = readl(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_STATUS);
87 pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY);
88
89 if (pll_locked)
90 break;
91
92 udelay(timeout_us);
93 }
94 DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
95
96 return pll_locked;
97}
98
99static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm)
100{
101 void __iomem *base = pll_28nm->phy->pll_base;
102
103 /*
104 * Add HW recommended delays after toggling the software
105 * reset bit off and back on.
106 */
107 writel(DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, base + REG_DSI_28nm_PHY_PLL_TEST_CFG);
108 udelay(1);
109 writel(0, base + REG_DSI_28nm_PHY_PLL_TEST_CFG);
110 udelay(1);
111}
112
113/*
114 * Clock Callbacks
115 */
116static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
117 unsigned long parent_rate)
118{
119 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
120 struct device *dev = &pll_28nm->phy->pdev->dev;
121 void __iomem *base = pll_28nm->phy->pll_base;
122 unsigned long div_fbx1000, gen_vco_clk;
123 u32 refclk_cfg, frac_n_mode, frac_n_value;
124 u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
125 u32 cal_cfg10, cal_cfg11;
126 u32 rem;
127 int i;
128
129 VERB("rate=%lu, parent's=%lu", rate, parent_rate);
130
131 /* Force postdiv2 to be div-4 */
132 writel(3, base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG);
133
134 /* Configure the Loop filter resistance */
135 for (i = 0; i < LPFR_LUT_SIZE; i++)
136 if (rate <= lpfr_lut[i].vco_rate)
137 break;
138 if (i == LPFR_LUT_SIZE) {
139 DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n",
140 rate);
141 return -EINVAL;
142 }
143 writel(lpfr_lut[i].resistance, base + REG_DSI_28nm_PHY_PLL_LPFR_CFG);
144
145 /* Loop filter capacitance values : c1 and c2 */
146 writel(0x70, base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG);
147 writel(0x15, base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG);
148
149 rem = rate % VCO_REF_CLK_RATE;
150 if (rem) {
151 refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
152 frac_n_mode = 1;
153 div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500);
154 gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500);
155 } else {
156 refclk_cfg = 0x0;
157 frac_n_mode = 0;
158 div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000);
159 gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000);
160 }
161
162 DBG("refclk_cfg = %d", refclk_cfg);
163
164 rem = div_fbx1000 % 1000;
165 frac_n_value = (rem << 16) / 1000;
166
167 DBG("div_fb = %lu", div_fbx1000);
168 DBG("frac_n_value = %d", frac_n_value);
169
170 DBG("Generated VCO Clock: %lu", gen_vco_clk);
171 rem = 0;
172 sdm_cfg1 = readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
173 sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK;
174 if (frac_n_mode) {
175 sdm_cfg0 = 0x0;
176 sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0);
177 sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(
178 (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
179 sdm_cfg3 = frac_n_value >> 8;
180 sdm_cfg2 = frac_n_value & 0xff;
181 } else {
182 sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP;
183 sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(
184 (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
185 sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0);
186 sdm_cfg2 = 0;
187 sdm_cfg3 = 0;
188 }
189
190 DBG("sdm_cfg0=%d", sdm_cfg0);
191 DBG("sdm_cfg1=%d", sdm_cfg1);
192 DBG("sdm_cfg2=%d", sdm_cfg2);
193 DBG("sdm_cfg3=%d", sdm_cfg3);
194
195 cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000));
196 cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000);
197 DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11);
198
199 writel(0x02, base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG);
200 writel(0x2b, base + REG_DSI_28nm_PHY_PLL_CAL_CFG3);
201 writel(0x06, base + REG_DSI_28nm_PHY_PLL_CAL_CFG4);
202 writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
203
204 writel(sdm_cfg1, base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
205 writel(DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2),
206 base + REG_DSI_28nm_PHY_PLL_SDM_CFG2);
207 writel(DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3),
208 base + REG_DSI_28nm_PHY_PLL_SDM_CFG3);
209 writel(0, base + REG_DSI_28nm_PHY_PLL_SDM_CFG4);
210
211 /* Add hardware recommended delay for correct PLL configuration */
212 if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
213 udelay(1000);
214 else
215 udelay(1);
216
217 writel(refclk_cfg, base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG);
218 writel(0x00, base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG);
219 writel(0x31, base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG);
220 writel(sdm_cfg0, base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
221 writel(0x12, base + REG_DSI_28nm_PHY_PLL_CAL_CFG0);
222 writel(0x30, base + REG_DSI_28nm_PHY_PLL_CAL_CFG6);
223 writel(0x00, base + REG_DSI_28nm_PHY_PLL_CAL_CFG7);
224 writel(0x60, base + REG_DSI_28nm_PHY_PLL_CAL_CFG8);
225 writel(0x00, base + REG_DSI_28nm_PHY_PLL_CAL_CFG9);
226 writel(cal_cfg10 & 0xff, base + REG_DSI_28nm_PHY_PLL_CAL_CFG10);
227 writel(cal_cfg11 & 0xff, base + REG_DSI_28nm_PHY_PLL_CAL_CFG11);
228 writel(0x20, base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG);
229
230 return 0;
231}
232
233static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
234{
235 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
236
237 return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
238 POLL_TIMEOUT_US);
239}
240
241static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
242 unsigned long parent_rate)
243{
244 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
245 void __iomem *base = pll_28nm->phy->pll_base;
246 u32 sdm0, doubler, sdm_byp_div;
247 u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
248 u32 ref_clk = VCO_REF_CLK_RATE;
249 unsigned long vco_rate;
250
251 VERB("parent_rate=%lu", parent_rate);
252
253 /* Check to see if the ref clk doubler is enabled */
254 doubler = readl(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) &
255 DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
256 ref_clk += (doubler * VCO_REF_CLK_RATE);
257
258 /* see if it is integer mode or sdm mode */
259 sdm0 = readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
260 if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) {
261 /* integer mode */
262 sdm_byp_div = FIELD(
263 readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0),
264 DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
265 vco_rate = ref_clk * sdm_byp_div;
266 } else {
267 /* sdm mode */
268 sdm_dc_off = FIELD(
269 readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1),
270 DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET);
271 DBG("sdm_dc_off = %d", sdm_dc_off);
272 sdm2 = FIELD(readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2),
273 DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0);
274 sdm3 = FIELD(readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3),
275 DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8);
276 sdm_freq_seed = (sdm3 << 8) | sdm2;
277 DBG("sdm_freq_seed = %d", sdm_freq_seed);
278
279 vco_rate = (ref_clk * (sdm_dc_off + 1)) +
280 mult_frac(ref_clk, sdm_freq_seed, BIT(16));
281 DBG("vco rate = %lu", vco_rate);
282 }
283
284 DBG("returning vco rate = %lu", vco_rate);
285
286 return vco_rate;
287}
288
289static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm)
290{
291 struct device *dev = &pll_28nm->phy->pdev->dev;
292 void __iomem *base = pll_28nm->phy->pll_base;
293 u32 max_reads = 5, timeout_us = 100;
294 bool locked;
295 u32 val;
296 int i;
297
298 DBG("id=%d", pll_28nm->phy->id);
299
300 pll_28nm_software_reset(pll_28nm);
301
302 /*
303 * PLL power up sequence.
304 * Add necessary delays recommended by hardware.
305 */
306 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
307 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
308 udelay(1);
309
310 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
311 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
312 udelay(200);
313
314 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
315 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
316 udelay(500);
317
318 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
319 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
320 udelay(600);
321
322 for (i = 0; i < 2; i++) {
323 /* DSI Uniphy lock detect setting */
324 writel(0x0c, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
325 udelay(100);
326 writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
327
328 /* poll for PLL ready status */
329 locked = pll_28nm_poll_for_ready(pll_28nm, max_reads,
330 timeout_us);
331 if (locked)
332 break;
333
334 pll_28nm_software_reset(pll_28nm);
335
336 /*
337 * PLL power up sequence.
338 * Add necessary delays recommended by hardware.
339 */
340 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
341 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
342 udelay(1);
343
344 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
345 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
346 udelay(200);
347
348 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
349 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
350 udelay(250);
351
352 val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
353 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
354 udelay(200);
355
356 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
357 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
358 udelay(500);
359
360 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
361 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
362 udelay(600);
363 }
364
365 if (unlikely(!locked))
366 DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
367 else
368 DBG("DSI PLL Lock success");
369
370 return locked ? 0 : -EINVAL;
371}
372
373static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw)
374{
375 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
376 int i, ret;
377
378 if (unlikely(pll_28nm->phy->pll_on))
379 return 0;
380
381 for (i = 0; i < 3; i++) {
382 ret = _dsi_pll_28nm_vco_prepare_hpm(pll_28nm);
383 if (!ret) {
384 pll_28nm->phy->pll_on = true;
385 return 0;
386 }
387 }
388
389 return ret;
390}
391
392static int dsi_pll_28nm_vco_prepare_8226(struct clk_hw *hw)
393{
394 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
395 struct device *dev = &pll_28nm->phy->pdev->dev;
396 void __iomem *base = pll_28nm->phy->pll_base;
397 u32 max_reads = 5, timeout_us = 100;
398 bool locked;
399 u32 val;
400 int i;
401
402 DBG("id=%d", pll_28nm->phy->id);
403
404 pll_28nm_software_reset(pll_28nm);
405
406 /*
407 * PLL power up sequence.
408 * Add necessary delays recommended by hardware.
409 */
410 writel(0x34, base + REG_DSI_28nm_PHY_PLL_CAL_CFG1);
411
412 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
413 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
414 udelay(200);
415
416 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
417 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
418 udelay(200);
419
420 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
421 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
422 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
423 udelay(600);
424
425 for (i = 0; i < 7; i++) {
426 /* DSI Uniphy lock detect setting */
427 writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
428 writel(0x0c, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
429 udelay(100);
430 writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
431
432 /* poll for PLL ready status */
433 locked = pll_28nm_poll_for_ready(pll_28nm,
434 max_reads, timeout_us);
435 if (locked)
436 break;
437
438 pll_28nm_software_reset(pll_28nm);
439
440 /*
441 * PLL power up sequence.
442 * Add necessary delays recommended by hardware.
443 */
444 writel(0x00, base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG);
445 udelay(50);
446
447 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
448 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
449 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
450 udelay(100);
451
452 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
453 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
454 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
455 udelay(600);
456 }
457
458 if (unlikely(!locked))
459 DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
460 else
461 DBG("DSI PLL Lock success");
462
463 return locked ? 0 : -EINVAL;
464}
465
466static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw)
467{
468 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
469 struct device *dev = &pll_28nm->phy->pdev->dev;
470 void __iomem *base = pll_28nm->phy->pll_base;
471 bool locked;
472 u32 max_reads = 10, timeout_us = 50;
473 u32 val;
474
475 DBG("id=%d", pll_28nm->phy->id);
476
477 if (unlikely(pll_28nm->phy->pll_on))
478 return 0;
479
480 pll_28nm_software_reset(pll_28nm);
481
482 /*
483 * PLL power up sequence.
484 * Add necessary delays recommended by hardware.
485 */
486 writel(0x34, base + REG_DSI_28nm_PHY_PLL_CAL_CFG1);
487 ndelay(500);
488
489 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
490 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
491 ndelay(500);
492
493 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
494 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
495 ndelay(500);
496
497 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B |
498 DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
499 writel(val, base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
500 ndelay(500);
501
502 /* DSI PLL toggle lock detect setting */
503 writel(0x04, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
504 ndelay(500);
505 writel(0x05, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2);
506 udelay(512);
507
508 locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
509
510 if (unlikely(!locked)) {
511 DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
512 return -EINVAL;
513 }
514
515 DBG("DSI PLL lock success");
516 pll_28nm->phy->pll_on = true;
517
518 return 0;
519}
520
521static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw)
522{
523 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
524
525 DBG("id=%d", pll_28nm->phy->id);
526
527 if (unlikely(!pll_28nm->phy->pll_on))
528 return;
529
530 writel(0, pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_GLB_CFG);
531
532 pll_28nm->phy->pll_on = false;
533}
534
535static long dsi_pll_28nm_clk_round_rate(struct clk_hw *hw,
536 unsigned long rate, unsigned long *parent_rate)
537{
538 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
539
540 if (rate < pll_28nm->phy->cfg->min_pll_rate)
541 return pll_28nm->phy->cfg->min_pll_rate;
542 else if (rate > pll_28nm->phy->cfg->max_pll_rate)
543 return pll_28nm->phy->cfg->max_pll_rate;
544 else
545 return rate;
546}
547
548static const struct clk_ops clk_ops_dsi_pll_28nm_vco_hpm = {
549 .round_rate = dsi_pll_28nm_clk_round_rate,
550 .set_rate = dsi_pll_28nm_clk_set_rate,
551 .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
552 .prepare = dsi_pll_28nm_vco_prepare_hpm,
553 .unprepare = dsi_pll_28nm_vco_unprepare,
554 .is_enabled = dsi_pll_28nm_clk_is_enabled,
555};
556
557static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = {
558 .round_rate = dsi_pll_28nm_clk_round_rate,
559 .set_rate = dsi_pll_28nm_clk_set_rate,
560 .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
561 .prepare = dsi_pll_28nm_vco_prepare_lp,
562 .unprepare = dsi_pll_28nm_vco_unprepare,
563 .is_enabled = dsi_pll_28nm_clk_is_enabled,
564};
565
566static const struct clk_ops clk_ops_dsi_pll_28nm_vco_8226 = {
567 .round_rate = dsi_pll_28nm_clk_round_rate,
568 .set_rate = dsi_pll_28nm_clk_set_rate,
569 .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
570 .prepare = dsi_pll_28nm_vco_prepare_8226,
571 .unprepare = dsi_pll_28nm_vco_unprepare,
572 .is_enabled = dsi_pll_28nm_clk_is_enabled,
573};
574
575/*
576 * PLL Callbacks
577 */
578
579static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy)
580{
581 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
582 struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
583 void __iomem *base = pll_28nm->phy->pll_base;
584
585 cached_state->postdiv3 =
586 readl(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
587 cached_state->postdiv1 =
588 readl(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
589 cached_state->byte_mux = readl(base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
590 if (dsi_pll_28nm_clk_is_enabled(phy->vco_hw))
591 cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw);
592 else
593 cached_state->vco_rate = 0;
594}
595
596static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy)
597{
598 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
599 struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
600 void __iomem *base = pll_28nm->phy->pll_base;
601 int ret;
602
603 ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw,
604 cached_state->vco_rate, 0);
605 if (ret) {
606 DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev,
607 "restore vco rate failed. ret=%d\n", ret);
608 return ret;
609 }
610
611 writel(cached_state->postdiv3, base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
612 writel(cached_state->postdiv1, base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
613 writel(cached_state->byte_mux, base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
614
615 return 0;
616}
617
618static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks)
619{
620 char clk_name[32];
621 struct clk_init_data vco_init = {
622 .parent_data = &(const struct clk_parent_data) {
623 .fw_name = "ref", .name = "xo",
624 },
625 .num_parents = 1,
626 .name = clk_name,
627 .flags = CLK_IGNORE_UNUSED,
628 };
629 struct device *dev = &pll_28nm->phy->pdev->dev;
630 struct clk_hw *hw, *analog_postdiv, *indirect_path_div2, *byte_mux;
631 int ret;
632
633 DBG("%d", pll_28nm->phy->id);
634
635 if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
636 vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp;
637 else if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_8226)
638 vco_init.ops = &clk_ops_dsi_pll_28nm_vco_8226;
639 else
640 vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm;
641
642 snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_28nm->phy->id);
643 pll_28nm->clk_hw.init = &vco_init;
644 ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw);
645 if (ret)
646 return ret;
647
648 snprintf(clk_name, sizeof(clk_name), "dsi%danalog_postdiv_clk", pll_28nm->phy->id);
649 analog_postdiv = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
650 &pll_28nm->clk_hw, CLK_SET_RATE_PARENT,
651 pll_28nm->phy->pll_base +
652 REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
653 0, 4, 0, NULL);
654 if (IS_ERR(analog_postdiv))
655 return PTR_ERR(analog_postdiv);
656
657 snprintf(clk_name, sizeof(clk_name), "dsi%dindirect_path_div2_clk", pll_28nm->phy->id);
658 indirect_path_div2 = devm_clk_hw_register_fixed_factor_parent_hw(dev,
659 clk_name, analog_postdiv, CLK_SET_RATE_PARENT, 1, 2);
660 if (IS_ERR(indirect_path_div2))
661 return PTR_ERR(indirect_path_div2);
662
663 snprintf(clk_name, sizeof(clk_name), "dsi%dpll", pll_28nm->phy->id);
664 hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
665 &pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base +
666 REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
667 0, 8, 0, NULL);
668 if (IS_ERR(hw))
669 return PTR_ERR(hw);
670 provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
671
672 snprintf(clk_name, sizeof(clk_name), "dsi%dbyte_mux", pll_28nm->phy->id);
673 byte_mux = devm_clk_hw_register_mux_parent_hws(dev, clk_name,
674 ((const struct clk_hw *[]){
675 &pll_28nm->clk_hw,
676 indirect_path_div2,
677 }), 2, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base +
678 REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
679 if (IS_ERR(byte_mux))
680 return PTR_ERR(byte_mux);
681
682 snprintf(clk_name, sizeof(clk_name), "dsi%dpllbyte", pll_28nm->phy->id);
683 hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,
684 byte_mux, CLK_SET_RATE_PARENT, 1, 4);
685 if (IS_ERR(hw))
686 return PTR_ERR(hw);
687 provided_clocks[DSI_BYTE_PLL_CLK] = hw;
688
689 return 0;
690}
691
692static int dsi_pll_28nm_init(struct msm_dsi_phy *phy)
693{
694 struct platform_device *pdev = phy->pdev;
695 struct dsi_pll_28nm *pll_28nm;
696 int ret;
697
698 if (!pdev)
699 return -ENODEV;
700
701 pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
702 if (!pll_28nm)
703 return -ENOMEM;
704
705 pll_28nm->phy = phy;
706
707 ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws);
708 if (ret) {
709 DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
710 return ret;
711 }
712
713 phy->vco_hw = &pll_28nm->clk_hw;
714
715 return 0;
716}
717
718static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
719 struct msm_dsi_dphy_timing *timing)
720{
721 void __iomem *base = phy->base;
722
723 writel(DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero),
724 base + REG_DSI_28nm_PHY_TIMING_CTRL_0);
725 writel(DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail),
726 base + REG_DSI_28nm_PHY_TIMING_CTRL_1);
727 writel(DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare),
728 base + REG_DSI_28nm_PHY_TIMING_CTRL_2);
729 if (timing->clk_zero & BIT(8))
730 writel(DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8,
731 base + REG_DSI_28nm_PHY_TIMING_CTRL_3);
732 writel(DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit),
733 base + REG_DSI_28nm_PHY_TIMING_CTRL_4);
734 writel(DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero),
735 base + REG_DSI_28nm_PHY_TIMING_CTRL_5);
736 writel(DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare),
737 base + REG_DSI_28nm_PHY_TIMING_CTRL_6);
738 writel(DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail),
739 base + REG_DSI_28nm_PHY_TIMING_CTRL_7);
740 writel(DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst),
741 base + REG_DSI_28nm_PHY_TIMING_CTRL_8);
742 writel(DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
743 DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure),
744 base + REG_DSI_28nm_PHY_TIMING_CTRL_9);
745 writel(DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get),
746 base + REG_DSI_28nm_PHY_TIMING_CTRL_10);
747 writel(DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0),
748 base + REG_DSI_28nm_PHY_TIMING_CTRL_11);
749}
750
751static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy)
752{
753 void __iomem *base = phy->reg_base;
754
755 writel(0x0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0);
756 writel(1, base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG);
757 writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5);
758 writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3);
759 writel(0x3, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2);
760 writel(0x9, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1);
761 writel(0x7, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0);
762 writel(0x20, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4);
763 writel(0x00, phy->base + REG_DSI_28nm_PHY_LDO_CNTRL);
764}
765
766static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy)
767{
768 void __iomem *base = phy->reg_base;
769
770 writel(0x0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0);
771 writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG);
772 writel(0x7, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5);
773 writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3);
774 writel(0x1, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2);
775 writel(0x1, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1);
776 writel(0x20, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4);
777
778 if (phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
779 writel(0x05, phy->base + REG_DSI_28nm_PHY_LDO_CNTRL);
780 else
781 writel(0x0d, phy->base + REG_DSI_28nm_PHY_LDO_CNTRL);
782}
783
784static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
785{
786 if (!enable) {
787 writel(0, phy->reg_base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG);
788 return;
789 }
790
791 if (phy->regulator_ldo_mode)
792 dsi_28nm_phy_regulator_enable_ldo(phy);
793 else
794 dsi_28nm_phy_regulator_enable_dcdc(phy);
795}
796
797static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy,
798 struct msm_dsi_phy_clk_request *clk_req)
799{
800 struct msm_dsi_dphy_timing *timing = &phy->timing;
801 int i;
802 void __iomem *base = phy->base;
803 u32 val;
804
805 DBG("");
806
807 if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
808 DRM_DEV_ERROR(&phy->pdev->dev,
809 "%s: D-PHY timing calculation failed\n",
810 __func__);
811 return -EINVAL;
812 }
813
814 writel(0xff, base + REG_DSI_28nm_PHY_STRENGTH_0);
815
816 dsi_28nm_phy_regulator_ctrl(phy, true);
817
818 dsi_28nm_dphy_set_timing(phy, timing);
819
820 writel(0x00, base + REG_DSI_28nm_PHY_CTRL_1);
821 writel(0x5f, base + REG_DSI_28nm_PHY_CTRL_0);
822
823 writel(0x6, base + REG_DSI_28nm_PHY_STRENGTH_1);
824
825 for (i = 0; i < 4; i++) {
826 writel(0, base + REG_DSI_28nm_PHY_LN_CFG_0(i));
827 writel(0, base + REG_DSI_28nm_PHY_LN_CFG_1(i));
828 writel(0, base + REG_DSI_28nm_PHY_LN_CFG_2(i));
829 writel(0, base + REG_DSI_28nm_PHY_LN_CFG_3(i));
830 writel(0, base + REG_DSI_28nm_PHY_LN_CFG_4(i));
831 writel(0, base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i));
832 writel(0, base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i));
833 writel(0x1, base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i));
834 writel(0x97, base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i));
835 }
836
837 writel(0, base + REG_DSI_28nm_PHY_LNCK_CFG_4);
838 writel(0xc0, base + REG_DSI_28nm_PHY_LNCK_CFG_1);
839 writel(0x1, base + REG_DSI_28nm_PHY_LNCK_TEST_STR0);
840 writel(0xbb, base + REG_DSI_28nm_PHY_LNCK_TEST_STR1);
841
842 writel(0x5f, base + REG_DSI_28nm_PHY_CTRL_0);
843
844 val = readl(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL);
845 if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_SLAVE)
846 val &= ~DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
847 else
848 val |= DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
849 writel(val, base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL);
850
851 return 0;
852}
853
854static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
855{
856 writel(0, phy->base + REG_DSI_28nm_PHY_CTRL_0);
857 dsi_28nm_phy_regulator_ctrl(phy, false);
858
859 /*
860 * Wait for the registers writes to complete in order to
861 * ensure that the phy is completely disabled
862 */
863 wmb();
864}
865
866static const struct regulator_bulk_data dsi_phy_28nm_regulators[] = {
867 { .supply = "vddio", .init_load_uA = 100000 },
868};
869
870const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
871 .has_phy_regulator = true,
872 .regulator_data = dsi_phy_28nm_regulators,
873 .num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
874 .ops = {
875 .enable = dsi_28nm_phy_enable,
876 .disable = dsi_28nm_phy_disable,
877 .pll_init = dsi_pll_28nm_init,
878 .save_pll_state = dsi_28nm_pll_save_state,
879 .restore_pll_state = dsi_28nm_pll_restore_state,
880 },
881 .min_pll_rate = VCO_MIN_RATE,
882 .max_pll_rate = VCO_MAX_RATE,
883 .io_start = { 0xfd922b00, 0xfd923100 },
884 .num_dsi_phy = 2,
885};
886
887const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = {
888 .has_phy_regulator = true,
889 .regulator_data = dsi_phy_28nm_regulators,
890 .num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
891 .ops = {
892 .enable = dsi_28nm_phy_enable,
893 .disable = dsi_28nm_phy_disable,
894 .pll_init = dsi_pll_28nm_init,
895 .save_pll_state = dsi_28nm_pll_save_state,
896 .restore_pll_state = dsi_28nm_pll_restore_state,
897 },
898 .min_pll_rate = VCO_MIN_RATE,
899 .max_pll_rate = VCO_MAX_RATE,
900 .io_start = { 0x1a94400, 0x1a96400 },
901 .num_dsi_phy = 2,
902};
903
904const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
905 .has_phy_regulator = true,
906 .regulator_data = dsi_phy_28nm_regulators,
907 .num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
908 .ops = {
909 .enable = dsi_28nm_phy_enable,
910 .disable = dsi_28nm_phy_disable,
911 .pll_init = dsi_pll_28nm_init,
912 .save_pll_state = dsi_28nm_pll_save_state,
913 .restore_pll_state = dsi_28nm_pll_restore_state,
914 },
915 .min_pll_rate = VCO_MIN_RATE,
916 .max_pll_rate = VCO_MAX_RATE,
917 .io_start = { 0x1a98500 },
918 .num_dsi_phy = 1,
919 .quirks = DSI_PHY_28NM_QUIRK_PHY_LP,
920};
921
922const struct msm_dsi_phy_cfg dsi_phy_28nm_8226_cfgs = {
923 .has_phy_regulator = true,
924 .regulator_data = dsi_phy_28nm_regulators,
925 .num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
926 .ops = {
927 .enable = dsi_28nm_phy_enable,
928 .disable = dsi_28nm_phy_disable,
929 .pll_init = dsi_pll_28nm_init,
930 .save_pll_state = dsi_28nm_pll_save_state,
931 .restore_pll_state = dsi_28nm_pll_restore_state,
932 },
933 .min_pll_rate = VCO_MIN_RATE,
934 .max_pll_rate = VCO_MAX_RATE,
935 .io_start = { 0xfd922b00 },
936 .num_dsi_phy = 1,
937 .quirks = DSI_PHY_28NM_QUIRK_PHY_8226,
938};
939
940const struct msm_dsi_phy_cfg dsi_phy_28nm_8937_cfgs = {
941 .has_phy_regulator = true,
942 .regulator_data = dsi_phy_28nm_regulators,
943 .num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
944 .ops = {
945 .enable = dsi_28nm_phy_enable,
946 .disable = dsi_28nm_phy_disable,
947 .pll_init = dsi_pll_28nm_init,
948 .save_pll_state = dsi_28nm_pll_save_state,
949 .restore_pll_state = dsi_28nm_pll_restore_state,
950 },
951 .min_pll_rate = VCO_MIN_RATE,
952 .max_pll_rate = VCO_MAX_RATE,
953 .io_start = { 0x1a94400, 0x1a96400 },
954 .num_dsi_phy = 2,
955 .quirks = DSI_PHY_28NM_QUIRK_PHY_LP,
956};