]> Git Repo - J-linux.git/blob - drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / gpu / drm / msm / dsi / phy / dsi_phy_10nm.c
1 /*
2  * SPDX-License-Identifier: GPL-2.0
3  * Copyright (c) 2018, The Linux Foundation
4  */
5
6 #include <linux/clk.h>
7 #include <linux/clk-provider.h>
8 #include <linux/iopoll.h>
9
10 #include "dsi_phy.h"
11 #include "dsi.xml.h"
12 #include "dsi_phy_10nm.xml.h"
13
14 /*
15  * DSI PLL 10nm - clock diagram (eg: DSI0):
16  *
17  *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
18  *                              |                |
19  *                              |                |
20  *                 +---------+  |  +----------+  |  +----+
21  *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
22  *                 +---------+  |  +----------+  |  +----+
23  *                              |                |
24  *                              |                |         dsi0_pll_by_2_bit_clk
25  *                              |                |          |
26  *                              |                |  +----+  |  |\  dsi0_pclk_mux
27  *                              |                |--| /2 |--o--| \   |
28  *                              |                |  +----+     |  \  |  +---------+
29  *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
30  *                              |------------------------------|  /     +---------+
31  *                              |          +-----+             | /
32  *                              -----------| /4? |--o----------|/
33  *                                         +-----+  |           |
34  *                                                  |           |dsiclk_sel
35  *                                                  |
36  *                                                  dsi0_pll_post_out_div_clk
37  */
38
39 #define VCO_REF_CLK_RATE                19200000
40 #define FRAC_BITS 18
41
42 /* v3.0.0 10nm implementation that requires the old timings settings */
43 #define DSI_PHY_10NM_QUIRK_OLD_TIMINGS  BIT(0)
44
45 struct dsi_pll_config {
46         bool enable_ssc;
47         bool ssc_center;
48         u32 ssc_freq;
49         u32 ssc_offset;
50         u32 ssc_adj_per;
51
52         /* out */
53         u32 pll_prop_gain_rate;
54         u32 decimal_div_start;
55         u32 frac_div_start;
56         u32 pll_clock_inverters;
57         u32 ssc_stepsize;
58         u32 ssc_div_per;
59 };
60
61 struct pll_10nm_cached_state {
62         unsigned long vco_rate;
63         u8 bit_clk_div;
64         u8 pix_clk_div;
65         u8 pll_out_div;
66         u8 pll_mux;
67 };
68
69 struct dsi_pll_10nm {
70         struct clk_hw clk_hw;
71
72         struct msm_dsi_phy *phy;
73
74         u64 vco_current_rate;
75
76         /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */
77         spinlock_t postdiv_lock;
78
79         struct pll_10nm_cached_state cached_state;
80
81         struct dsi_pll_10nm *slave;
82 };
83
84 #define to_pll_10nm(x)  container_of(x, struct dsi_pll_10nm, clk_hw)
85
86 /**
87  * struct dsi_phy_10nm_tuning_cfg - Holds 10nm PHY tuning config parameters.
88  * @rescode_offset_top: Offset for pull-up legs rescode.
89  * @rescode_offset_bot: Offset for pull-down legs rescode.
90  * @vreg_ctrl: vreg ctrl to drive LDO level
91  */
92 struct dsi_phy_10nm_tuning_cfg {
93         u8 rescode_offset_top[DSI_LANE_MAX];
94         u8 rescode_offset_bot[DSI_LANE_MAX];
95         u8 vreg_ctrl;
96 };
97
98 /*
99  * Global list of private DSI PLL struct pointers. We need this for bonded DSI
100  * mode, where the master PLL's clk_ops needs access the slave's private data
101  */
102 static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX];
103
104 static void dsi_pll_setup_config(struct dsi_pll_config *config)
105 {
106         config->ssc_freq = 31500;
107         config->ssc_offset = 5000;
108         config->ssc_adj_per = 2;
109
110         config->enable_ssc = false;
111         config->ssc_center = false;
112 }
113
114 static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
115 {
116         u64 fref = VCO_REF_CLK_RATE;
117         u64 pll_freq;
118         u64 divider;
119         u64 dec, dec_multiple;
120         u32 frac;
121         u64 multiplier;
122
123         pll_freq = pll->vco_current_rate;
124
125         divider = fref * 2;
126
127         multiplier = 1 << FRAC_BITS;
128         dec_multiple = div_u64(pll_freq * multiplier, divider);
129         dec = div_u64_rem(dec_multiple, multiplier, &frac);
130
131         if (pll_freq <= 1900000000UL)
132                 config->pll_prop_gain_rate = 8;
133         else if (pll_freq <= 3000000000UL)
134                 config->pll_prop_gain_rate = 10;
135         else
136                 config->pll_prop_gain_rate = 12;
137         if (pll_freq < 1100000000UL)
138                 config->pll_clock_inverters = 8;
139         else
140                 config->pll_clock_inverters = 0;
141
142         config->decimal_div_start = dec;
143         config->frac_div_start = frac;
144 }
145
146 #define SSC_CENTER              BIT(0)
147 #define SSC_EN                  BIT(1)
148
149 static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
150 {
151         u32 ssc_per;
152         u32 ssc_mod;
153         u64 ssc_step_size;
154         u64 frac;
155
156         if (!config->enable_ssc) {
157                 DBG("SSC not enabled\n");
158                 return;
159         }
160
161         ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
162         ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
163         ssc_per -= ssc_mod;
164
165         frac = config->frac_div_start;
166         ssc_step_size = config->decimal_div_start;
167         ssc_step_size *= (1 << FRAC_BITS);
168         ssc_step_size += frac;
169         ssc_step_size *= config->ssc_offset;
170         ssc_step_size *= (config->ssc_adj_per + 1);
171         ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
172         ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
173
174         config->ssc_div_per = ssc_per;
175         config->ssc_stepsize = ssc_step_size;
176
177         pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
178                  config->decimal_div_start, frac, FRAC_BITS);
179         pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
180                  ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
181 }
182
183 static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
184 {
185         void __iomem *base = pll->phy->pll_base;
186
187         if (config->enable_ssc) {
188                 pr_debug("SSC is enabled\n");
189
190                 writel(config->ssc_stepsize & 0xff,
191                        base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1);
192                 writel(config->ssc_stepsize >> 8,
193                        base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1);
194                 writel(config->ssc_div_per & 0xff,
195                        base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1);
196                 writel(config->ssc_div_per >> 8,
197                        base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1);
198                 writel(config->ssc_adj_per & 0xff,
199                        base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1);
200                 writel(config->ssc_adj_per >> 8,
201                        base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1);
202                 writel(SSC_EN | (config->ssc_center ? SSC_CENTER : 0),
203                        base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL);
204         }
205 }
206
207 static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll)
208 {
209         void __iomem *base = pll->phy->pll_base;
210
211         writel(0x80, base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE);
212         writel(0x03, base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO);
213         writel(0x00, base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE);
214         writel(0x00, base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER);
215         writel(0x4e, base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER);
216         writel(0x40, base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS);
217         writel(0xba, base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE);
218         writel(0x0c, base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE);
219         writel(0x00, base + REG_DSI_10nm_PHY_PLL_OUTDIV);
220         writel(0x00, base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE);
221         writel(0x08, base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO);
222         writel(0x08, base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1);
223         writel(0xc0, base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1);
224         writel(0xfa, base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1);
225         writel(0x4c, base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1);
226         writel(0x80, base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE);
227         writel(0x29, base + REG_DSI_10nm_PHY_PLL_PFILT);
228         writel(0x3f, base + REG_DSI_10nm_PHY_PLL_IFILT);
229 }
230
231 static void dsi_pll_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
232 {
233         void __iomem *base = pll->phy->pll_base;
234
235         writel(0x12, base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE);
236         writel(config->decimal_div_start,
237                base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1);
238         writel(config->frac_div_start & 0xff,
239                base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1);
240         writel((config->frac_div_start & 0xff00) >> 8,
241                base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1);
242         writel((config->frac_div_start & 0x30000) >> 16,
243                base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1);
244         writel(64, base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1);
245         writel(0x06, base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY);
246         writel(0x10, base + REG_DSI_10nm_PHY_PLL_CMODE);
247         writel(config->pll_clock_inverters, base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS);
248 }
249
250 static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
251                                      unsigned long parent_rate)
252 {
253         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
254         struct dsi_pll_config config;
255
256         DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->phy->id, rate,
257             parent_rate);
258
259         pll_10nm->vco_current_rate = rate;
260
261         dsi_pll_setup_config(&config);
262
263         dsi_pll_calc_dec_frac(pll_10nm, &config);
264
265         dsi_pll_calc_ssc(pll_10nm, &config);
266
267         dsi_pll_commit(pll_10nm, &config);
268
269         dsi_pll_config_hzindep_reg(pll_10nm);
270
271         dsi_pll_ssc_commit(pll_10nm, &config);
272
273         /* flush, ensure all register writes are done*/
274         wmb();
275
276         return 0;
277 }
278
279 static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
280 {
281         struct device *dev = &pll->phy->pdev->dev;
282         int rc;
283         u32 status = 0;
284         u32 const delay_us = 100;
285         u32 const timeout_us = 5000;
286
287         rc = readl_poll_timeout_atomic(pll->phy->pll_base +
288                                        REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE,
289                                        status,
290                                        ((status & BIT(0)) > 0),
291                                        delay_us,
292                                        timeout_us);
293         if (rc)
294                 DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n",
295                               pll->phy->id, status);
296
297         return rc;
298 }
299
300 static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll)
301 {
302         u32 data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
303
304         writel(0, pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES);
305         writel(data & ~BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
306         ndelay(250);
307 }
308
309 static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll)
310 {
311         u32 data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
312
313         writel(data | BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
314         writel(0xc0, pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES);
315         ndelay(250);
316 }
317
318 static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll)
319 {
320         u32 data;
321
322         data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
323         writel(data & ~BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
324 }
325
326 static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll)
327 {
328         u32 data;
329
330         data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
331         writel(data | BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
332 }
333
334 static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw)
335 {
336         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
337         struct device *dev = &pll_10nm->phy->pdev->dev;
338         int rc;
339
340         dsi_pll_enable_pll_bias(pll_10nm);
341         if (pll_10nm->slave)
342                 dsi_pll_enable_pll_bias(pll_10nm->slave);
343
344         rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0);
345         if (rc) {
346                 DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc);
347                 return rc;
348         }
349
350         /* Start PLL */
351         writel(0x01, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL);
352
353         /*
354          * ensure all PLL configurations are written prior to checking
355          * for PLL lock.
356          */
357         wmb();
358
359         /* Check for PLL lock */
360         rc = dsi_pll_10nm_lock_status(pll_10nm);
361         if (rc) {
362                 DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->phy->id);
363                 goto error;
364         }
365
366         pll_10nm->phy->pll_on = true;
367
368         dsi_pll_enable_global_clk(pll_10nm);
369         if (pll_10nm->slave)
370                 dsi_pll_enable_global_clk(pll_10nm->slave);
371
372         writel(0x01, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL);
373         if (pll_10nm->slave)
374                 writel(0x01, pll_10nm->slave->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL);
375
376 error:
377         return rc;
378 }
379
380 static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll)
381 {
382         writel(0, pll->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL);
383         dsi_pll_disable_pll_bias(pll);
384 }
385
386 static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw)
387 {
388         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
389
390         /*
391          * To avoid any stray glitches while abruptly powering down the PLL
392          * make sure to gate the clock using the clock enable bit before
393          * powering down the PLL
394          */
395         dsi_pll_disable_global_clk(pll_10nm);
396         writel(0, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL);
397         dsi_pll_disable_sub(pll_10nm);
398         if (pll_10nm->slave) {
399                 dsi_pll_disable_global_clk(pll_10nm->slave);
400                 dsi_pll_disable_sub(pll_10nm->slave);
401         }
402         /* flush, ensure all register writes are done */
403         wmb();
404         pll_10nm->phy->pll_on = false;
405 }
406
407 static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
408                                                   unsigned long parent_rate)
409 {
410         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
411         void __iomem *base = pll_10nm->phy->pll_base;
412         u64 ref_clk = VCO_REF_CLK_RATE;
413         u64 vco_rate = 0x0;
414         u64 multiplier;
415         u32 frac;
416         u32 dec;
417         u64 pll_freq, tmp64;
418
419         dec = readl(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1);
420         dec &= 0xff;
421
422         frac = readl(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1);
423         frac |= ((readl(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) &
424                   0xff) << 8);
425         frac |= ((readl(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
426                   0x3) << 16);
427
428         /*
429          * TODO:
430          *      1. Assumes prescaler is disabled
431          */
432         multiplier = 1 << FRAC_BITS;
433         pll_freq = dec * (ref_clk * 2);
434         tmp64 = (ref_clk * 2 * frac);
435         pll_freq += div_u64(tmp64, multiplier);
436
437         vco_rate = pll_freq;
438         pll_10nm->vco_current_rate = vco_rate;
439
440         DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
441             pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac);
442
443         return (unsigned long)vco_rate;
444 }
445
446 static long dsi_pll_10nm_clk_round_rate(struct clk_hw *hw,
447                 unsigned long rate, unsigned long *parent_rate)
448 {
449         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
450
451         if      (rate < pll_10nm->phy->cfg->min_pll_rate)
452                 return  pll_10nm->phy->cfg->min_pll_rate;
453         else if (rate > pll_10nm->phy->cfg->max_pll_rate)
454                 return  pll_10nm->phy->cfg->max_pll_rate;
455         else
456                 return rate;
457 }
458
459 static const struct clk_ops clk_ops_dsi_pll_10nm_vco = {
460         .round_rate = dsi_pll_10nm_clk_round_rate,
461         .set_rate = dsi_pll_10nm_vco_set_rate,
462         .recalc_rate = dsi_pll_10nm_vco_recalc_rate,
463         .prepare = dsi_pll_10nm_vco_prepare,
464         .unprepare = dsi_pll_10nm_vco_unprepare,
465 };
466
467 /*
468  * PLL Callbacks
469  */
470
471 static void dsi_10nm_pll_save_state(struct msm_dsi_phy *phy)
472 {
473         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
474         struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
475         void __iomem *phy_base = pll_10nm->phy->base;
476         u32 cmn_clk_cfg0, cmn_clk_cfg1;
477
478         cached->pll_out_div = readl(pll_10nm->phy->pll_base +
479                         REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
480         cached->pll_out_div &= 0x3;
481
482         cmn_clk_cfg0 = readl(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0);
483         cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
484         cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
485
486         cmn_clk_cfg1 = readl(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
487         cached->pll_mux = cmn_clk_cfg1 & 0x3;
488
489         DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
490             pll_10nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
491             cached->pix_clk_div, cached->pll_mux);
492 }
493
494 static int dsi_10nm_pll_restore_state(struct msm_dsi_phy *phy)
495 {
496         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
497         struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
498         void __iomem *phy_base = pll_10nm->phy->base;
499         u32 val;
500         int ret;
501
502         val = readl(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
503         val &= ~0x3;
504         val |= cached->pll_out_div;
505         writel(val, pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
506
507         writel(cached->bit_clk_div | (cached->pix_clk_div << 4),
508                phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0);
509
510         val = readl(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
511         val &= ~0x3;
512         val |= cached->pll_mux;
513         writel(val, phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
514
515         ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw,
516                         pll_10nm->vco_current_rate,
517                         VCO_REF_CLK_RATE);
518         if (ret) {
519                 DRM_DEV_ERROR(&pll_10nm->phy->pdev->dev,
520                         "restore vco rate failed. ret=%d\n", ret);
521                 return ret;
522         }
523
524         DBG("DSI PLL%d", pll_10nm->phy->id);
525
526         return 0;
527 }
528
529 static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy)
530 {
531         struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
532         void __iomem *base = phy->base;
533         u32 data = 0x0; /* internal PLL */
534
535         DBG("DSI PLL%d", pll_10nm->phy->id);
536
537         switch (phy->usecase) {
538         case MSM_DSI_PHY_STANDALONE:
539                 break;
540         case MSM_DSI_PHY_MASTER:
541                 pll_10nm->slave = pll_10nm_list[(pll_10nm->phy->id + 1) % DSI_MAX];
542                 break;
543         case MSM_DSI_PHY_SLAVE:
544                 data = 0x1; /* external PLL */
545                 break;
546         default:
547                 return -EINVAL;
548         }
549
550         /* set PLL src */
551         writel(data << 2, base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
552
553         return 0;
554 }
555
556 /*
557  * The post dividers and mux clocks are created using the standard divider and
558  * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
559  * state to follow the master PLL's divider/mux state. Therefore, we don't
560  * require special clock ops that also configure the slave PLL registers
561  */
562 static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **provided_clocks)
563 {
564         char clk_name[32];
565         struct clk_init_data vco_init = {
566                 .parent_data = &(const struct clk_parent_data) {
567                         .fw_name = "ref",
568                 },
569                 .num_parents = 1,
570                 .name = clk_name,
571                 .flags = CLK_IGNORE_UNUSED,
572                 .ops = &clk_ops_dsi_pll_10nm_vco,
573         };
574         struct device *dev = &pll_10nm->phy->pdev->dev;
575         struct clk_hw *hw, *pll_out_div, *pll_bit, *pll_by_2_bit;
576         struct clk_hw *pll_post_out_div, *pclk_mux;
577         int ret;
578
579         DBG("DSI%d", pll_10nm->phy->id);
580
581         snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_10nm->phy->id);
582         pll_10nm->clk_hw.init = &vco_init;
583
584         ret = devm_clk_hw_register(dev, &pll_10nm->clk_hw);
585         if (ret)
586                 return ret;
587
588         snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_out_div_clk", pll_10nm->phy->id);
589
590         pll_out_div = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
591                         &pll_10nm->clk_hw, CLK_SET_RATE_PARENT,
592                         pll_10nm->phy->pll_base +
593                                 REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE,
594                         0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
595         if (IS_ERR(pll_out_div)) {
596                 ret = PTR_ERR(pll_out_div);
597                 goto fail;
598         }
599
600         snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_bit_clk", pll_10nm->phy->id);
601
602         /* BIT CLK: DIV_CTRL_3_0 */
603         pll_bit = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
604                         pll_out_div, CLK_SET_RATE_PARENT,
605                         pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
606                         0, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock);
607         if (IS_ERR(pll_bit)) {
608                 ret = PTR_ERR(pll_bit);
609                 goto fail;
610         }
611
612         snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_byteclk", pll_10nm->phy->id);
613
614         /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
615         hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,
616                         pll_bit, CLK_SET_RATE_PARENT, 1, 8);
617         if (IS_ERR(hw)) {
618                 ret = PTR_ERR(hw);
619                 goto fail;
620         }
621
622         provided_clocks[DSI_BYTE_PLL_CLK] = hw;
623
624         snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id);
625
626         pll_by_2_bit = devm_clk_hw_register_fixed_factor_parent_hw(dev,
627                         clk_name, pll_bit, 0, 1, 2);
628         if (IS_ERR(pll_by_2_bit)) {
629                 ret = PTR_ERR(pll_by_2_bit);
630                 goto fail;
631         }
632
633         snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id);
634
635         pll_post_out_div = devm_clk_hw_register_fixed_factor_parent_hw(dev,
636                         clk_name, pll_out_div, 0, 1, 4);
637         if (IS_ERR(pll_post_out_div)) {
638                 ret = PTR_ERR(pll_post_out_div);
639                 goto fail;
640         }
641
642         snprintf(clk_name, sizeof(clk_name), "dsi%d_pclk_mux", pll_10nm->phy->id);
643
644         pclk_mux = devm_clk_hw_register_mux_parent_hws(dev, clk_name,
645                         ((const struct clk_hw *[]){
646                                 pll_bit,
647                                 pll_by_2_bit,
648                                 pll_out_div,
649                                 pll_post_out_div,
650                         }), 4, 0, pll_10nm->phy->base +
651                                 REG_DSI_10nm_PHY_CMN_CLK_CFG1, 0, 2, 0, NULL);
652         if (IS_ERR(pclk_mux)) {
653                 ret = PTR_ERR(pclk_mux);
654                 goto fail;
655         }
656
657         snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_dsiclk", pll_10nm->phy->id);
658
659         /* PIX CLK DIV : DIV_CTRL_7_4*/
660         hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, pclk_mux,
661                         0, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
662                         4, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock);
663         if (IS_ERR(hw)) {
664                 ret = PTR_ERR(hw);
665                 goto fail;
666         }
667
668         provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
669
670         return 0;
671
672 fail:
673
674         return ret;
675 }
676
677 static int dsi_pll_10nm_init(struct msm_dsi_phy *phy)
678 {
679         struct platform_device *pdev = phy->pdev;
680         struct dsi_pll_10nm *pll_10nm;
681         int ret;
682
683         pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL);
684         if (!pll_10nm)
685                 return -ENOMEM;
686
687         DBG("DSI PLL%d", phy->id);
688
689         pll_10nm_list[phy->id] = pll_10nm;
690
691         spin_lock_init(&pll_10nm->postdiv_lock);
692
693         pll_10nm->phy = phy;
694
695         ret = pll_10nm_register(pll_10nm, phy->provided_clocks->hws);
696         if (ret) {
697                 DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
698                 return ret;
699         }
700
701         phy->vco_hw = &pll_10nm->clk_hw;
702
703         /* TODO: Remove this when we have proper display handover support */
704         msm_dsi_phy_pll_save_state(phy);
705
706         return 0;
707 }
708
709 static int dsi_phy_hw_v3_0_is_pll_on(struct msm_dsi_phy *phy)
710 {
711         void __iomem *base = phy->base;
712         u32 data = 0;
713
714         data = readl(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL);
715         mb(); /* make sure read happened */
716
717         return (data & BIT(0));
718 }
719
720 static void dsi_phy_hw_v3_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
721 {
722         void __iomem *lane_base = phy->lane_base;
723         int phy_lane_0 = 0;     /* TODO: Support all lane swap configs */
724
725         /*
726          * LPRX and CDRX need to enabled only for physical data lane
727          * corresponding to the logical data lane 0
728          */
729         if (enable)
730                 writel(0x3, lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0));
731         else
732                 writel(0, lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0));
733 }
734
735 static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
736 {
737         int i;
738         u8 tx_dctrl[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
739         void __iomem *lane_base = phy->lane_base;
740         struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg;
741
742         if (phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)
743                 tx_dctrl[3] = 0x02;
744
745         /* Strength ctrl settings */
746         for (i = 0; i < 5; i++) {
747                 writel(0x55, lane_base + REG_DSI_10nm_PHY_LN_LPTX_STR_CTRL(i));
748                 /*
749                  * Disable LPRX and CDRX for all lanes. And later on, it will
750                  * be only enabled for the physical data lane corresponding
751                  * to the logical data lane 0
752                  */
753                 writel(0, lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(i));
754                 writel(0x0, lane_base + REG_DSI_10nm_PHY_LN_PIN_SWAP(i));
755                 writel(0x88, lane_base + REG_DSI_10nm_PHY_LN_HSTX_STR_CTRL(i));
756         }
757
758         dsi_phy_hw_v3_0_config_lpcdrx(phy, true);
759
760         /* other settings */
761         for (i = 0; i < 5; i++) {
762                 writel(0, lane_base + REG_DSI_10nm_PHY_LN_CFG0(i));
763                 writel(0, lane_base + REG_DSI_10nm_PHY_LN_CFG1(i));
764                 writel(0, lane_base + REG_DSI_10nm_PHY_LN_CFG2(i));
765                 writel(i == 4 ? 0x80 : 0x0, lane_base + REG_DSI_10nm_PHY_LN_CFG3(i));
766
767                 /* platform specific dsi phy drive strength adjustment */
768                 writel(tuning_cfg->rescode_offset_top[i],
769                        lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i));
770                 writel(tuning_cfg->rescode_offset_bot[i],
771                        lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i));
772
773                 writel(tx_dctrl[i],
774                        lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i));
775         }
776
777         if (!(phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)) {
778                 /* Toggle BIT 0 to release freeze I/0 */
779                 writel(0x05, lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3));
780                 writel(0x04, lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3));
781         }
782 }
783
784 static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy,
785                                struct msm_dsi_phy_clk_request *clk_req)
786 {
787         int ret;
788         u32 status;
789         u32 const delay_us = 5;
790         u32 const timeout_us = 1000;
791         struct msm_dsi_dphy_timing *timing = &phy->timing;
792         void __iomem *base = phy->base;
793         struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg;
794         u32 data;
795
796         DBG("");
797
798         if (msm_dsi_dphy_timing_calc_v3(timing, clk_req)) {
799                 DRM_DEV_ERROR(&phy->pdev->dev,
800                         "%s: D-PHY timing calculation failed\n", __func__);
801                 return -EINVAL;
802         }
803
804         if (dsi_phy_hw_v3_0_is_pll_on(phy))
805                 pr_warn("PLL turned on before configuring PHY\n");
806
807         /* wait for REFGEN READY */
808         ret = readl_poll_timeout_atomic(base + REG_DSI_10nm_PHY_CMN_PHY_STATUS,
809                                         status, (status & BIT(0)),
810                                         delay_us, timeout_us);
811         if (ret) {
812                 pr_err("Ref gen not ready. Aborting\n");
813                 return -EINVAL;
814         }
815
816         /* de-assert digital and pll power down */
817         data = BIT(6) | BIT(5);
818         writel(data, base + REG_DSI_10nm_PHY_CMN_CTRL_0);
819
820         /* Assert PLL core reset */
821         writel(0x00, base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL);
822
823         /* turn off resync FIFO */
824         writel(0x00, base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL);
825
826         /* Select MS1 byte-clk */
827         writel(0x10, base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL);
828
829         /* Enable LDO with platform specific drive level/amplitude adjustment */
830         writel(tuning_cfg->vreg_ctrl, base + REG_DSI_10nm_PHY_CMN_VREG_CTRL);
831
832         /* Configure PHY lane swap (TODO: we need to calculate this) */
833         writel(0x21, base + REG_DSI_10nm_PHY_CMN_LANE_CFG0);
834         writel(0x84, base + REG_DSI_10nm_PHY_CMN_LANE_CFG1);
835
836         /* DSI PHY timings */
837         writel(timing->hs_halfbyte_en, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_0);
838         writel(timing->clk_zero, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_1);
839         writel(timing->clk_prepare, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_2);
840         writel(timing->clk_trail, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_3);
841         writel(timing->hs_exit, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_4);
842         writel(timing->hs_zero, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_5);
843         writel(timing->hs_prepare, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_6);
844         writel(timing->hs_trail, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_7);
845         writel(timing->hs_rqst, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_8);
846         writel(timing->ta_go | (timing->ta_sure << 3), base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_9);
847         writel(timing->ta_get, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_10);
848         writel(0x00, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_11);
849
850         /* Remove power down from all blocks */
851         writel(0x7f, base + REG_DSI_10nm_PHY_CMN_CTRL_0);
852
853         /* power up lanes */
854         data = readl(base + REG_DSI_10nm_PHY_CMN_CTRL_0);
855
856         /* TODO: only power up lanes that are used */
857         data |= 0x1F;
858         writel(data, base + REG_DSI_10nm_PHY_CMN_CTRL_0);
859         writel(0x1F, base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0);
860
861         /* Select full-rate mode */
862         writel(0x40, base + REG_DSI_10nm_PHY_CMN_CTRL_2);
863
864         ret = dsi_10nm_set_usecase(phy);
865         if (ret) {
866                 DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
867                         __func__, ret);
868                 return ret;
869         }
870
871         /* DSI lane settings */
872         dsi_phy_hw_v3_0_lane_settings(phy);
873
874         DBG("DSI%d PHY enabled", phy->id);
875
876         return 0;
877 }
878
879 static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy)
880 {
881         void __iomem *base = phy->base;
882         u32 data;
883
884         DBG("");
885
886         if (dsi_phy_hw_v3_0_is_pll_on(phy))
887                 pr_warn("Turning OFF PHY while PLL is on\n");
888
889         dsi_phy_hw_v3_0_config_lpcdrx(phy, false);
890         data = readl(base + REG_DSI_10nm_PHY_CMN_CTRL_0);
891
892         /* disable all lanes */
893         data &= ~0x1F;
894         writel(data, base + REG_DSI_10nm_PHY_CMN_CTRL_0);
895         writel(0, base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0);
896
897         /* Turn off all PHY blocks */
898         writel(0x00, base + REG_DSI_10nm_PHY_CMN_CTRL_0);
899         /* make sure phy is turned off */
900         wmb();
901
902         DBG("DSI%d PHY disabled", phy->id);
903 }
904
905 static int dsi_10nm_phy_parse_dt(struct msm_dsi_phy *phy)
906 {
907         struct device *dev = &phy->pdev->dev;
908         struct dsi_phy_10nm_tuning_cfg *tuning_cfg;
909         s8 offset_top[DSI_LANE_MAX] = { 0 }; /* No offset */
910         s8 offset_bot[DSI_LANE_MAX] = { 0 }; /* No offset */
911         u32 ldo_level = 400; /* 400mV */
912         u8 level;
913         int ret, i;
914
915         tuning_cfg = devm_kzalloc(dev, sizeof(*tuning_cfg), GFP_KERNEL);
916         if (!tuning_cfg)
917                 return -ENOMEM;
918
919         /* Drive strength adjustment parameters */
920         ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-top",
921                                         offset_top, DSI_LANE_MAX);
922         if (ret && ret != -EINVAL) {
923                 DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-top, %d\n", ret);
924                 return ret;
925         }
926
927         for (i = 0; i < DSI_LANE_MAX; i++) {
928                 if (offset_top[i] < -32 || offset_top[i] > 31) {
929                         DRM_DEV_ERROR(dev,
930                                 "qcom,phy-rescode-offset-top value %d is not in range [-32..31]\n",
931                                 offset_top[i]);
932                         return -EINVAL;
933                 }
934                 tuning_cfg->rescode_offset_top[i] = 0x3f & offset_top[i];
935         }
936
937         ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-bot",
938                                         offset_bot, DSI_LANE_MAX);
939         if (ret && ret != -EINVAL) {
940                 DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-bot, %d\n", ret);
941                 return ret;
942         }
943
944         for (i = 0; i < DSI_LANE_MAX; i++) {
945                 if (offset_bot[i] < -32 || offset_bot[i] > 31) {
946                         DRM_DEV_ERROR(dev,
947                                 "qcom,phy-rescode-offset-bot value %d is not in range [-32..31]\n",
948                                 offset_bot[i]);
949                         return -EINVAL;
950                 }
951                 tuning_cfg->rescode_offset_bot[i] = 0x3f & offset_bot[i];
952         }
953
954         /* Drive level/amplitude adjustment parameters */
955         ret = of_property_read_u32(dev->of_node, "qcom,phy-drive-ldo-level", &ldo_level);
956         if (ret && ret != -EINVAL) {
957                 DRM_DEV_ERROR(dev, "failed to parse qcom,phy-drive-ldo-level, %d\n", ret);
958                 return ret;
959         }
960
961         switch (ldo_level) {
962         case 375:
963                 level = 0;
964                 break;
965         case 400:
966                 level = 1;
967                 break;
968         case 425:
969                 level = 2;
970                 break;
971         case 450:
972                 level = 3;
973                 break;
974         case 475:
975                 level = 4;
976                 break;
977         case 500:
978                 level = 5;
979                 break;
980         default:
981                 DRM_DEV_ERROR(dev, "qcom,phy-drive-ldo-level %d is not supported\n", ldo_level);
982                 return -EINVAL;
983         }
984         tuning_cfg->vreg_ctrl = 0x58 | (0x7 & level);
985
986         phy->tuning_cfg = tuning_cfg;
987
988         return 0;
989 }
990
991 static const struct regulator_bulk_data dsi_phy_10nm_regulators[] = {
992         { .supply = "vdds", .init_load_uA = 36000 },
993 };
994
995 const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = {
996         .has_phy_lane = true,
997         .regulator_data = dsi_phy_10nm_regulators,
998         .num_regulators = ARRAY_SIZE(dsi_phy_10nm_regulators),
999         .ops = {
1000                 .enable = dsi_10nm_phy_enable,
1001                 .disable = dsi_10nm_phy_disable,
1002                 .pll_init = dsi_pll_10nm_init,
1003                 .save_pll_state = dsi_10nm_pll_save_state,
1004                 .restore_pll_state = dsi_10nm_pll_restore_state,
1005                 .parse_dt_properties = dsi_10nm_phy_parse_dt,
1006         },
1007         .min_pll_rate = 1000000000UL,
1008         .max_pll_rate = 3500000000UL,
1009         .io_start = { 0xae94400, 0xae96400 },
1010         .num_dsi_phy = 2,
1011 };
1012
1013 const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = {
1014         .has_phy_lane = true,
1015         .regulator_data = dsi_phy_10nm_regulators,
1016         .num_regulators = ARRAY_SIZE(dsi_phy_10nm_regulators),
1017         .ops = {
1018                 .enable = dsi_10nm_phy_enable,
1019                 .disable = dsi_10nm_phy_disable,
1020                 .pll_init = dsi_pll_10nm_init,
1021                 .save_pll_state = dsi_10nm_pll_save_state,
1022                 .restore_pll_state = dsi_10nm_pll_restore_state,
1023                 .parse_dt_properties = dsi_10nm_phy_parse_dt,
1024         },
1025         .min_pll_rate = 1000000000UL,
1026         .max_pll_rate = 3500000000UL,
1027         .io_start = { 0xc994400, 0xc996400 },
1028         .num_dsi_phy = 2,
1029         .quirks = DSI_PHY_10NM_QUIRK_OLD_TIMINGS,
1030 };
This page took 0.088968 seconds and 4 git commands to generate.