Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/clk-provider.h>
0008 
0009 #include "dsi_phy.h"
0010 #include "dsi.xml.h"
0011 #include "dsi_phy_28nm.xml.h"
0012 
0013 /*
0014  * DSI PLL 28nm - clock diagram (eg: DSI0):
0015  *
0016  *         dsi0analog_postdiv_clk
0017  *                             |         dsi0indirect_path_div2_clk
0018  *                             |          |
0019  *                   +------+  |  +----+  |  |\   dsi0byte_mux
0020  *  dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \   |
0021  *                |  +------+     +----+     | m|  |  +----+
0022  *                |                          | u|--o--| /4 |-- dsi0pllbyte
0023  *                |                          | x|     +----+
0024  *                o--------------------------| /
0025  *                |                          |/
0026  *                |          +------+
0027  *                o----------| DIV3 |------------------------- dsi0pll
0028  *                           +------+
0029  */
0030 
0031 #define POLL_MAX_READS          10
0032 #define POLL_TIMEOUT_US     50
0033 
0034 #define VCO_REF_CLK_RATE        19200000
0035 #define VCO_MIN_RATE            350000000
0036 #define VCO_MAX_RATE            750000000
0037 
0038 /* v2.0.0 28nm LP implementation */
0039 #define DSI_PHY_28NM_QUIRK_PHY_LP   BIT(0)
0040 
0041 #define LPFR_LUT_SIZE           10
0042 struct lpfr_cfg {
0043     unsigned long vco_rate;
0044     u32 resistance;
0045 };
0046 
0047 /* Loop filter resistance: */
0048 static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
0049     { 479500000,  8 },
0050     { 480000000, 11 },
0051     { 575500000,  8 },
0052     { 576000000, 12 },
0053     { 610500000,  8 },
0054     { 659500000,  9 },
0055     { 671500000, 10 },
0056     { 672000000, 14 },
0057     { 708500000, 10 },
0058     { 750000000, 11 },
0059 };
0060 
0061 struct pll_28nm_cached_state {
0062     unsigned long vco_rate;
0063     u8 postdiv3;
0064     u8 postdiv1;
0065     u8 byte_mux;
0066 };
0067 
0068 struct dsi_pll_28nm {
0069     struct clk_hw clk_hw;
0070 
0071     struct msm_dsi_phy *phy;
0072 
0073     struct pll_28nm_cached_state cached_state;
0074 };
0075 
0076 #define to_pll_28nm(x)  container_of(x, struct dsi_pll_28nm, clk_hw)
0077 
0078 static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
0079                 u32 nb_tries, u32 timeout_us)
0080 {
0081     bool pll_locked = false;
0082     u32 val;
0083 
0084     while (nb_tries--) {
0085         val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_STATUS);
0086         pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY);
0087 
0088         if (pll_locked)
0089             break;
0090 
0091         udelay(timeout_us);
0092     }
0093     DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
0094 
0095     return pll_locked;
0096 }
0097 
0098 static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm)
0099 {
0100     void __iomem *base = pll_28nm->phy->pll_base;
0101 
0102     /*
0103      * Add HW recommended delays after toggling the software
0104      * reset bit off and back on.
0105      */
0106     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG,
0107             DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1);
0108     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1);
0109 }
0110 
0111 /*
0112  * Clock Callbacks
0113  */
0114 static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
0115         unsigned long parent_rate)
0116 {
0117     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0118     struct device *dev = &pll_28nm->phy->pdev->dev;
0119     void __iomem *base = pll_28nm->phy->pll_base;
0120     unsigned long div_fbx1000, gen_vco_clk;
0121     u32 refclk_cfg, frac_n_mode, frac_n_value;
0122     u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
0123     u32 cal_cfg10, cal_cfg11;
0124     u32 rem;
0125     int i;
0126 
0127     VERB("rate=%lu, parent's=%lu", rate, parent_rate);
0128 
0129     /* Force postdiv2 to be div-4 */
0130     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3);
0131 
0132     /* Configure the Loop filter resistance */
0133     for (i = 0; i < LPFR_LUT_SIZE; i++)
0134         if (rate <= lpfr_lut[i].vco_rate)
0135             break;
0136     if (i == LPFR_LUT_SIZE) {
0137         DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n",
0138                 rate);
0139         return -EINVAL;
0140     }
0141     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance);
0142 
0143     /* Loop filter capacitance values : c1 and c2 */
0144     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70);
0145     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15);
0146 
0147     rem = rate % VCO_REF_CLK_RATE;
0148     if (rem) {
0149         refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
0150         frac_n_mode = 1;
0151         div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500);
0152         gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500);
0153     } else {
0154         refclk_cfg = 0x0;
0155         frac_n_mode = 0;
0156         div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000);
0157         gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000);
0158     }
0159 
0160     DBG("refclk_cfg = %d", refclk_cfg);
0161 
0162     rem = div_fbx1000 % 1000;
0163     frac_n_value = (rem << 16) / 1000;
0164 
0165     DBG("div_fb = %lu", div_fbx1000);
0166     DBG("frac_n_value = %d", frac_n_value);
0167 
0168     DBG("Generated VCO Clock: %lu", gen_vco_clk);
0169     rem = 0;
0170     sdm_cfg1 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
0171     sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK;
0172     if (frac_n_mode) {
0173         sdm_cfg0 = 0x0;
0174         sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0);
0175         sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(
0176                 (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
0177         sdm_cfg3 = frac_n_value >> 8;
0178         sdm_cfg2 = frac_n_value & 0xff;
0179     } else {
0180         sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP;
0181         sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(
0182                 (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
0183         sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0);
0184         sdm_cfg2 = 0;
0185         sdm_cfg3 = 0;
0186     }
0187 
0188     DBG("sdm_cfg0=%d", sdm_cfg0);
0189     DBG("sdm_cfg1=%d", sdm_cfg1);
0190     DBG("sdm_cfg2=%d", sdm_cfg2);
0191     DBG("sdm_cfg3=%d", sdm_cfg3);
0192 
0193     cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000));
0194     cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000);
0195     DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11);
0196 
0197     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02);
0198     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3,    0x2b);
0199     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4,    0x06);
0200     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,  0x0d);
0201 
0202     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1);
0203     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2,
0204         DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2));
0205     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3,
0206         DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3));
0207     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00);
0208 
0209     /* Add hardware recommended delay for correct PLL configuration */
0210     if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
0211         udelay(1000);
0212     else
0213         udelay(1);
0214 
0215     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg);
0216     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00);
0217     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31);
0218     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0,   sdm_cfg0);
0219     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0,   0x12);
0220     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6,   0x30);
0221     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7,   0x00);
0222     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8,   0x60);
0223     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9,   0x00);
0224     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10,  cal_cfg10 & 0xff);
0225     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11,  cal_cfg11 & 0xff);
0226     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG,  0x20);
0227 
0228     return 0;
0229 }
0230 
0231 static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
0232 {
0233     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0234 
0235     return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
0236                     POLL_TIMEOUT_US);
0237 }
0238 
0239 static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
0240         unsigned long parent_rate)
0241 {
0242     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0243     void __iomem *base = pll_28nm->phy->pll_base;
0244     u32 sdm0, doubler, sdm_byp_div;
0245     u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
0246     u32 ref_clk = VCO_REF_CLK_RATE;
0247     unsigned long vco_rate;
0248 
0249     VERB("parent_rate=%lu", parent_rate);
0250 
0251     /* Check to see if the ref clk doubler is enabled */
0252     doubler = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) &
0253             DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
0254     ref_clk += (doubler * VCO_REF_CLK_RATE);
0255 
0256     /* see if it is integer mode or sdm mode */
0257     sdm0 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
0258     if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) {
0259         /* integer mode */
0260         sdm_byp_div = FIELD(
0261                 dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0),
0262                 DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
0263         vco_rate = ref_clk * sdm_byp_div;
0264     } else {
0265         /* sdm mode */
0266         sdm_dc_off = FIELD(
0267                 dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1),
0268                 DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET);
0269         DBG("sdm_dc_off = %d", sdm_dc_off);
0270         sdm2 = FIELD(dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2),
0271                 DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0);
0272         sdm3 = FIELD(dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3),
0273                 DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8);
0274         sdm_freq_seed = (sdm3 << 8) | sdm2;
0275         DBG("sdm_freq_seed = %d", sdm_freq_seed);
0276 
0277         vco_rate = (ref_clk * (sdm_dc_off + 1)) +
0278             mult_frac(ref_clk, sdm_freq_seed, BIT(16));
0279         DBG("vco rate = %lu", vco_rate);
0280     }
0281 
0282     DBG("returning vco rate = %lu", vco_rate);
0283 
0284     return vco_rate;
0285 }
0286 
0287 static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm)
0288 {
0289     struct device *dev = &pll_28nm->phy->pdev->dev;
0290     void __iomem *base = pll_28nm->phy->pll_base;
0291     u32 max_reads = 5, timeout_us = 100;
0292     bool locked;
0293     u32 val;
0294     int i;
0295 
0296     DBG("id=%d", pll_28nm->phy->id);
0297 
0298     pll_28nm_software_reset(pll_28nm);
0299 
0300     /*
0301      * PLL power up sequence.
0302      * Add necessary delays recommended by hardware.
0303      */
0304     val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
0305     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
0306 
0307     val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
0308     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
0309 
0310     val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
0311     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
0312 
0313     val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
0314     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
0315 
0316     for (i = 0; i < 2; i++) {
0317         /* DSI Uniphy lock detect setting */
0318         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,
0319                 0x0c, 100);
0320         dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
0321 
0322         /* poll for PLL ready status */
0323         locked = pll_28nm_poll_for_ready(pll_28nm,
0324                         max_reads, timeout_us);
0325         if (locked)
0326             break;
0327 
0328         pll_28nm_software_reset(pll_28nm);
0329 
0330         /*
0331          * PLL power up sequence.
0332          * Add necessary delays recommended by hardware.
0333          */
0334         val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
0335         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
0336 
0337         val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
0338         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
0339 
0340         val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
0341         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250);
0342 
0343         val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
0344         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
0345 
0346         val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
0347         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
0348 
0349         val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
0350         dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
0351     }
0352 
0353     if (unlikely(!locked))
0354         DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
0355     else
0356         DBG("DSI PLL Lock success");
0357 
0358     return locked ? 0 : -EINVAL;
0359 }
0360 
0361 static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw)
0362 {
0363     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0364     int i, ret;
0365 
0366     if (unlikely(pll_28nm->phy->pll_on))
0367         return 0;
0368 
0369     for (i = 0; i < 3; i++) {
0370         ret = _dsi_pll_28nm_vco_prepare_hpm(pll_28nm);
0371         if (!ret) {
0372             pll_28nm->phy->pll_on = true;
0373             return 0;
0374         }
0375     }
0376 
0377     return ret;
0378 }
0379 
0380 static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw)
0381 {
0382     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0383     struct device *dev = &pll_28nm->phy->pdev->dev;
0384     void __iomem *base = pll_28nm->phy->pll_base;
0385     bool locked;
0386     u32 max_reads = 10, timeout_us = 50;
0387     u32 val;
0388 
0389     DBG("id=%d", pll_28nm->phy->id);
0390 
0391     if (unlikely(pll_28nm->phy->pll_on))
0392         return 0;
0393 
0394     pll_28nm_software_reset(pll_28nm);
0395 
0396     /*
0397      * PLL power up sequence.
0398      * Add necessary delays recommended by hardware.
0399      */
0400     dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500);
0401 
0402     val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
0403     dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
0404 
0405     val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
0406     dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
0407 
0408     val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B |
0409         DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
0410     dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
0411 
0412     /* DSI PLL toggle lock detect setting */
0413     dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500);
0414     dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512);
0415 
0416     locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
0417 
0418     if (unlikely(!locked)) {
0419         DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
0420         return -EINVAL;
0421     }
0422 
0423     DBG("DSI PLL lock success");
0424     pll_28nm->phy->pll_on = true;
0425 
0426     return 0;
0427 }
0428 
0429 static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw)
0430 {
0431     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0432 
0433     DBG("id=%d", pll_28nm->phy->id);
0434 
0435     if (unlikely(!pll_28nm->phy->pll_on))
0436         return;
0437 
0438     dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00);
0439 
0440     pll_28nm->phy->pll_on = false;
0441 }
0442 
0443 static long dsi_pll_28nm_clk_round_rate(struct clk_hw *hw,
0444         unsigned long rate, unsigned long *parent_rate)
0445 {
0446     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
0447 
0448     if      (rate < pll_28nm->phy->cfg->min_pll_rate)
0449         return  pll_28nm->phy->cfg->min_pll_rate;
0450     else if (rate > pll_28nm->phy->cfg->max_pll_rate)
0451         return  pll_28nm->phy->cfg->max_pll_rate;
0452     else
0453         return rate;
0454 }
0455 
0456 static const struct clk_ops clk_ops_dsi_pll_28nm_vco_hpm = {
0457     .round_rate = dsi_pll_28nm_clk_round_rate,
0458     .set_rate = dsi_pll_28nm_clk_set_rate,
0459     .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
0460     .prepare = dsi_pll_28nm_vco_prepare_hpm,
0461     .unprepare = dsi_pll_28nm_vco_unprepare,
0462     .is_enabled = dsi_pll_28nm_clk_is_enabled,
0463 };
0464 
0465 static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = {
0466     .round_rate = dsi_pll_28nm_clk_round_rate,
0467     .set_rate = dsi_pll_28nm_clk_set_rate,
0468     .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
0469     .prepare = dsi_pll_28nm_vco_prepare_lp,
0470     .unprepare = dsi_pll_28nm_vco_unprepare,
0471     .is_enabled = dsi_pll_28nm_clk_is_enabled,
0472 };
0473 
0474 /*
0475  * PLL Callbacks
0476  */
0477 
0478 static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy)
0479 {
0480     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
0481     struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
0482     void __iomem *base = pll_28nm->phy->pll_base;
0483 
0484     cached_state->postdiv3 =
0485             dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
0486     cached_state->postdiv1 =
0487             dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
0488     cached_state->byte_mux = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
0489     if (dsi_pll_28nm_clk_is_enabled(phy->vco_hw))
0490         cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw);
0491     else
0492         cached_state->vco_rate = 0;
0493 }
0494 
0495 static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy)
0496 {
0497     struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
0498     struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
0499     void __iomem *base = pll_28nm->phy->pll_base;
0500     int ret;
0501 
0502     ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw,
0503                     cached_state->vco_rate, 0);
0504     if (ret) {
0505         DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev,
0506             "restore vco rate failed. ret=%d\n", ret);
0507         return ret;
0508     }
0509 
0510     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
0511             cached_state->postdiv3);
0512     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
0513             cached_state->postdiv1);
0514     dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG,
0515             cached_state->byte_mux);
0516 
0517     return 0;
0518 }
0519 
0520 static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks)
0521 {
0522     char clk_name[32], parent1[32], parent2[32], vco_name[32];
0523     struct clk_init_data vco_init = {
0524         .parent_data = &(const struct clk_parent_data) {
0525             .fw_name = "ref", .name = "xo",
0526         },
0527         .num_parents = 1,
0528         .name = vco_name,
0529         .flags = CLK_IGNORE_UNUSED,
0530     };
0531     struct device *dev = &pll_28nm->phy->pdev->dev;
0532     struct clk_hw *hw;
0533     int ret;
0534 
0535     DBG("%d", pll_28nm->phy->id);
0536 
0537     if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
0538         vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp;
0539     else
0540         vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm;
0541 
0542     snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->phy->id);
0543     pll_28nm->clk_hw.init = &vco_init;
0544     ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw);
0545     if (ret)
0546         return ret;
0547 
0548     snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id);
0549     snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id);
0550     hw = devm_clk_hw_register_divider(dev, clk_name,
0551             parent1, CLK_SET_RATE_PARENT,
0552             pll_28nm->phy->pll_base +
0553             REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
0554             0, 4, 0, NULL);
0555     if (IS_ERR(hw))
0556         return PTR_ERR(hw);
0557 
0558     snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->phy->id);
0559     snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id);
0560     hw = devm_clk_hw_register_fixed_factor(dev, clk_name,
0561             parent1, CLK_SET_RATE_PARENT,
0562             1, 2);
0563     if (IS_ERR(hw))
0564         return PTR_ERR(hw);
0565 
0566     snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id);
0567     snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id);
0568     hw = devm_clk_hw_register_divider(dev, clk_name,
0569                 parent1, 0, pll_28nm->phy->pll_base +
0570                 REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
0571                 0, 8, 0, NULL);
0572     if (IS_ERR(hw))
0573         return PTR_ERR(hw);
0574     provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
0575 
0576     snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->phy->id);
0577     snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id);
0578     snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->phy->id);
0579     hw = devm_clk_hw_register_mux(dev, clk_name,
0580             ((const char *[]){
0581                 parent1, parent2
0582             }), 2, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base +
0583             REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
0584     if (IS_ERR(hw))
0585         return PTR_ERR(hw);
0586 
0587     snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id);
0588     snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->phy->id);
0589     hw = devm_clk_hw_register_fixed_factor(dev, clk_name,
0590                 parent1, CLK_SET_RATE_PARENT, 1, 4);
0591     if (IS_ERR(hw))
0592         return PTR_ERR(hw);
0593     provided_clocks[DSI_BYTE_PLL_CLK] = hw;
0594 
0595     return 0;
0596 }
0597 
0598 static int dsi_pll_28nm_init(struct msm_dsi_phy *phy)
0599 {
0600     struct platform_device *pdev = phy->pdev;
0601     struct dsi_pll_28nm *pll_28nm;
0602     int ret;
0603 
0604     if (!pdev)
0605         return -ENODEV;
0606 
0607     pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
0608     if (!pll_28nm)
0609         return -ENOMEM;
0610 
0611     pll_28nm->phy = phy;
0612 
0613     ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws);
0614     if (ret) {
0615         DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
0616         return ret;
0617     }
0618 
0619     phy->vco_hw = &pll_28nm->clk_hw;
0620 
0621     return 0;
0622 }
0623 
0624 static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
0625         struct msm_dsi_dphy_timing *timing)
0626 {
0627     void __iomem *base = phy->base;
0628 
0629     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_0,
0630         DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
0631     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_1,
0632         DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
0633     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_2,
0634         DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
0635     if (timing->clk_zero & BIT(8))
0636         dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_3,
0637             DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8);
0638     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_4,
0639         DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
0640     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_5,
0641         DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
0642     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_6,
0643         DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
0644     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_7,
0645         DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
0646     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_8,
0647         DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
0648     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_9,
0649         DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
0650         DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
0651     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_10,
0652         DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
0653     dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_11,
0654         DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
0655 }
0656 
0657 static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy)
0658 {
0659     void __iomem *base = phy->reg_base;
0660 
0661     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
0662     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
0663     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
0664     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
0665     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x3);
0666     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
0667     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
0668     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
0669     dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
0670 }
0671 
0672 static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy)
0673 {
0674     void __iomem *base = phy->reg_base;
0675 
0676     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
0677     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
0678     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0x7);
0679     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
0680     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x1);
0681     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x1);
0682     dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
0683 
0684     if (phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
0685         dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x05);
0686     else
0687         dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x0d);
0688 }
0689 
0690 static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
0691 {
0692     if (!enable) {
0693         dsi_phy_write(phy->reg_base +
0694                   REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
0695         return;
0696     }
0697 
0698     if (phy->regulator_ldo_mode)
0699         dsi_28nm_phy_regulator_enable_ldo(phy);
0700     else
0701         dsi_28nm_phy_regulator_enable_dcdc(phy);
0702 }
0703 
0704 static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy,
0705                 struct msm_dsi_phy_clk_request *clk_req)
0706 {
0707     struct msm_dsi_dphy_timing *timing = &phy->timing;
0708     int i;
0709     void __iomem *base = phy->base;
0710     u32 val;
0711 
0712     DBG("");
0713 
0714     if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
0715         DRM_DEV_ERROR(&phy->pdev->dev,
0716             "%s: D-PHY timing calculation failed\n", __func__);
0717         return -EINVAL;
0718     }
0719 
0720     dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_0, 0xff);
0721 
0722     dsi_28nm_phy_regulator_ctrl(phy, true);
0723 
0724     dsi_28nm_dphy_set_timing(phy, timing);
0725 
0726     dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
0727     dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
0728 
0729     dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_1, 0x6);
0730 
0731     for (i = 0; i < 4; i++) {
0732         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_0(i), 0);
0733         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_1(i), 0);
0734         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_2(i), 0);
0735         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_3(i), 0);
0736         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(i), 0);
0737         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i), 0);
0738         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i), 0);
0739         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i), 0x1);
0740         dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i), 0x97);
0741     }
0742 
0743     dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_4, 0);
0744     dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_1, 0xc0);
0745     dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR0, 0x1);
0746     dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR1, 0xbb);
0747 
0748     dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
0749 
0750     val = dsi_phy_read(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL);
0751     if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_SLAVE)
0752         val &= ~DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
0753     else
0754         val |= DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
0755     dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, val);
0756 
0757     return 0;
0758 }
0759 
0760 static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
0761 {
0762     dsi_phy_write(phy->base + REG_DSI_28nm_PHY_CTRL_0, 0);
0763     dsi_28nm_phy_regulator_ctrl(phy, false);
0764 
0765     /*
0766      * Wait for the registers writes to complete in order to
0767      * ensure that the phy is completely disabled
0768      */
0769     wmb();
0770 }
0771 
0772 const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
0773     .has_phy_regulator = true,
0774     .reg_cfg = {
0775         .num = 1,
0776         .regs = {
0777             {"vddio", 100000, 100},
0778         },
0779     },
0780     .ops = {
0781         .enable = dsi_28nm_phy_enable,
0782         .disable = dsi_28nm_phy_disable,
0783         .pll_init = dsi_pll_28nm_init,
0784         .save_pll_state = dsi_28nm_pll_save_state,
0785         .restore_pll_state = dsi_28nm_pll_restore_state,
0786     },
0787     .min_pll_rate = VCO_MIN_RATE,
0788     .max_pll_rate = VCO_MAX_RATE,
0789     .io_start = { 0xfd922b00, 0xfd923100 },
0790     .num_dsi_phy = 2,
0791 };
0792 
0793 const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = {
0794     .has_phy_regulator = true,
0795     .reg_cfg = {
0796         .num = 1,
0797         .regs = {
0798             {"vddio", 100000, 100},
0799         },
0800     },
0801     .ops = {
0802         .enable = dsi_28nm_phy_enable,
0803         .disable = dsi_28nm_phy_disable,
0804         .pll_init = dsi_pll_28nm_init,
0805         .save_pll_state = dsi_28nm_pll_save_state,
0806         .restore_pll_state = dsi_28nm_pll_restore_state,
0807     },
0808     .min_pll_rate = VCO_MIN_RATE,
0809     .max_pll_rate = VCO_MAX_RATE,
0810     .io_start = { 0x1a94400, 0x1a96400 },
0811     .num_dsi_phy = 2,
0812 };
0813 
0814 const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
0815     .has_phy_regulator = true,
0816     .reg_cfg = {
0817         .num = 1,
0818         .regs = {
0819             {"vddio", 100000, 100}, /* 1.8 V */
0820         },
0821     },
0822     .ops = {
0823         .enable = dsi_28nm_phy_enable,
0824         .disable = dsi_28nm_phy_disable,
0825         .pll_init = dsi_pll_28nm_init,
0826         .save_pll_state = dsi_28nm_pll_save_state,
0827         .restore_pll_state = dsi_28nm_pll_restore_state,
0828     },
0829     .min_pll_rate = VCO_MIN_RATE,
0830     .max_pll_rate = VCO_MAX_RATE,
0831     .io_start = { 0x1a98500 },
0832     .num_dsi_phy = 1,
0833     .quirks = DSI_PHY_28NM_QUIRK_PHY_LP,
0834 };
0835